enlarge a curved arc with rounded edges, only from the rounded edge
4 Comments
Answers (2)
0 Comments
Hi @gaandi,
To address your query effectively, let me break down the provided code
% Load the matrix load('multiple_cells.mat'); % Assuming 'L' is loaded into workspace
% Display original image figure; imagesc(L); colormap(gray); title('Original Image'); axis equal;
% Define parameters extension_length = size(L, 1) / 8; % Extending 1/8th of original blob
% Identify edges using Canny edge detection edges = edge(L, 'Canny');
% Find endpoints of the curve (red region) [y, x] = find(edges); % Get coordinates of edges endpoints = [x, y]; % Store endpoints
% Initialize extended image matrix extended_L = L;
% Extrapolate from each endpoint for i = 1:size(endpoints, 1) endpoint = endpoints(i, :);
% Create angles for extrapolation based on curve direction theta = linspace(-pi/2, pi/2, 100); % Adjust angle for curvature
% Calculate extended points for positive extension x_ext_pos = round(endpoint(1) + extension_length * cos(theta)); y_ext_pos = round(endpoint(2) + extension_length * sin(theta));
% Ensure we stay within bounds for positive extension valid_pos_indices = (x_ext_pos >= 1 & x_ext_pos <= size(L, 2)) & ... (y_ext_pos >= 1 & y_ext_pos <= size(L, 1));
% Extend the original matrix for positive extension extended_L(sub2ind(size(extended_L), y_ext_pos(valid_pos_indices), x_ext_pos(valid_pos_indices))) = 255;
% Calculate extended points for negative extension x_ext_neg = round(endpoint(1) - extension_length * cos(theta)); y_ext_neg = round(endpoint(2) - extension_length * sin(theta));
% Ensure we stay within bounds for negative extension valid_neg_indices = (x_ext_neg >= 1 & x_ext_neg <= size(L, 2)) & ... (y_ext_neg >= 1 & y_ext_neg <= size(L, 1));
% Extend the original matrix for negative extension extended_L(sub2ind(size(extended_L), y_ext_neg(valid_neg_indices), x_ext_neg(valid_neg_indices))) = 255; end
% Display updated image figure; imagesc(extended_L); colormap(gray); title('Extended Image'); axis
and provide you step by step instructions that how it meets the requirements set forth in the comments:
Loading and Displaying the Original Image
load('multiple_cells.mat'); % Assuming 'L' is loaded into workspace figure; imagesc(L); colormap(gray); title('Original Image'); axis equal;
For more information on imagesc function, please refer to
https://www.mathworks.com/help/matlab/ref/imagesc.html?s_tid=doc_ta
This segment loads the matrix containing the image data and displays it using imagesc,setting a grayscale colormap for better visualization.
Defining Parameters for Extrapolation
extension_length = size(L, 1) / 8; % Extending 1/8th of original blob
Here, the code defines extension_length as one-eighth of the height of the original image, which directly relates to gaandi's request to extend each end by this proportion.
Edge Detection
edges = edge(L, 'Canny'); [y, x] = find(edges); % Get coordinates of edges endpoints = [x, y]; % Store endpoints
For more information on edge function,please refer to
https://www.mathworks.com/help/images/ref/edge.html
The Canny edge detection algorithm identifies edges within the segmented matrix. The subsequent find function extracts coordinates of these edges, which are crucial for identifying where to begin extrapolation (as noted in Matt J's comment).
Extrapolation from Each Endpoint
for i = 1:size(endpoints, 1) endpoint = endpoints(i, :); theta = linspace(-pi/2, pi/2, 100); % Adjust angle for curvature
% Calculate extended points for positive extension x_ext_pos = round(endpoint(1) + extension_length * cos(theta)); y_ext_pos = round(endpoint(2) + extension_length * sin(theta));
% Ensure we stay within bounds for positive extension valid_pos_indices = (x_ext_pos >= 1 & x_ext_pos <= size(L, 2)) & ... (y_ext_pos >= 1 & y_ext_pos <= size(L, 1));
extended_L(sub2ind(size(extended_L), y_ext_pos(valid_pos_indices), x_ext_pos(valid_pos_indices))) = 255;
% Calculate extended points for negative extension x_ext_neg = round(endpoint(1) - extension_length * cos(theta)); y_ext_neg = round(endpoint(2) - extension_length * sin(theta));
% Ensure we stay within bounds for negative extension valid_neg_indices = (x_ext_neg >= 1 & x_ext_neg <= size(L, 2)) & ... (y_ext_neg >= 1 & y_ext_neg <= size(L, 1));
extended_L(sub2ind(size(extended_L), y_ext_neg(valid_neg_indices), x_ext_neg(valid_neg_indices))) = 255; end
This loop iterates over each endpoint found in the edge-detected image. For each endpoint:
- It calculates potential new points to extend both positively and negatively based on the direction defined by `theta`, which represents angles around the endpoint.
- Valid indices are checked to ensure that extrapolated points remain within image boundaries before they are added to `extended_L`, effectively extending both ends of each curve as requested by gaandi.
Displaying the Extended Image
figure; imagesc(extended_L); colormap(gray); title('Extended Image'); axis equal;
For more information on imageesc function, please refer to
https://www.mathworks.com/help/matlab/ref/imagesc.html
Finally, this section visualizes the newly created matrix with extended regions.
Please see attached.
As DGM pointed out, extrapolating shapes can be complex due to varying widths and orientations. The code employs a consistent stroke width by using a constant extension_length, ensuring that extensions remain uniform.
Please let us know if you have any further questions for us.
9 Comments
Hi @ gaandi,
Hope, this new improved code addresses several of the concerns raised in the comments regarding fluorescence detection in segmented cells. Below, I will break down how the code responds to the specific issues mentioned and suggest improvements for better accuracy and reliability.
fluorescence_data = load('/MATLAB Drive/multiple_cells.mat'); fluorescence_image = fluorescence_data.L;
figure; imshow(fluorescence_image, []); title('Fluorescence Image');
threshold = adaptthresh(fluorescence_image, 0.5); binary_mask = imbinarize(fluorescence_image, threshold);
binary_mask = imopen(binary_mask, strel('disk', 3)); binary_mask = imclose(binary_mask, strel('disk', 3));
[B,L] = bwboundaries(binary_mask, 'noholes'); labeled_cells = bwlabel(binary_mask);
figure; imshow(label2rgb(labeled_cells)); title('Labeled Cells');
cell_stats = regionprops(labeled_cells, 'Area'); fluorescent_stats = regionprops(labeled_cells .* binary_mask, 'Area');
area_fraction_fluorescent = [fluorescent_stats.Area] ./ [cell_stats.Area];
figure; bar(area_fraction_fluorescent); xlabel('Cell ID'); ylabel('Area Fraction of Fluorescent Pixels'); title('Area Fraction of Fluorescent Pixels per Cell');
focus_sizes = [fluorescent_stats.Area]; cell_lengths = [cell_stats.Area];
correlation_coefficient = corrcoef(focus_sizes, cell_lengths); disp(['Correlation coefficient between focus size and cell length: ', num2str(correlation_coefficient(1,2))]);
Adaptive Thresholding for Binary Mask Creation
The code employs adaptive thresholding to create a binary mask from the fluorescence image:
threshold = adaptthresh(fluorescence_image, 0.5); binary_mask = imbinarize(fluorescence_image, threshold);
This approach is beneficial as it adjusts the threshold based on local image characteristics, which can help in accurately capturing fluorescence even at the edges of cells. This method addresses the concern of excluding fluorescence that is located at the very edge of the DIC binary mask.
Morphological Operations
The subsequent morphological operations (imopen and imclose) are crucial for refining the binary mask:
binary_mask = imopen(binary_mask, strel('disk', 3)); % Remove small noise binary_mask = imclose(binary_mask, strel('disk', 3)); %
Close gaps
These operations help eliminate small noise and close gaps in the binary mask, which can further enhance the detection of fluorescence that may be partially included in the segmentation.
Contour Detection and Cell Labeling
Instead of relying solely on watershed segmentation, the code uses contour detection:
[B,L] = bwboundaries(binary_mask, 'noholes'); labeled_cells = bwlabel(binary_mask);
This method allows for a more accurate delineation of cell boundaries, which is essential for associating fluorescence with the correct cells, especially when they are in close proximity to one another.
Area Fraction Calculation
The code calculates the area fraction of fluorescent pixels per cell:
cell_stats = regionprops(labeled_cells, 'Area'); fluorescent_stats = regionprops(labeled_cells .* binary_mask, 'Area'); area_fraction_fluorescent = [fluorescent_stats.Area] ./ [cell_stats.Area];
This metric directly addresses the suggestion to use the area fraction of fluorescent pixels as a simpler and potentially more effective measure. By focusing on the area fraction, the code avoids the complications of individual cell segmentation and instead provides a bulk metric that can correlate with biological outcomes.
Correlation Analysis
The code also includes a correlation analysis between focus sizes and cell lengths:
correlation_coefficient = corrcoef(focus_sizes, cell_lengths); disp(['Correlation coefficient between focus size and cell length: ', num2str(correlation_coefficient(1,2))]);
This analysis is critical for understanding the relationship between fluorescence intensity and cell dimensions, which can provide insights into the biological significance of the observed fluorescence.
Please see attached.
So, in nutshell, this provided updated MATLAB code now effectively addresses the comments regarding fluorescence detection within segmented cells. By utilizing adaptive thresholding, morphological operations, contour detection, and area fraction calculations, the code enhances the accuracy of fluorescence detection while simplifying the analysis process. Furthermore, the correlation analysis offers a pathway to explore the relationship between fluorescence and cell characteristics, which can be pivotal for future research.
See Also
Categories
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!