Extracting metrics from cellular pattern

2 views (last 30 days)
I'm trying to determine the width, height, area, and centroid of an scaly pattern shown in the attached image. I've tried using a gradient filter, edge detection, (see attached images) and various other functions, but the problem is I'm not able to get the edges to meet up and complete the cell pattern to where I can discern each cell as a separate object using, say, the regionprops function. I was hoping to get some guidance as to whether there are specific functions or established pre-processing steps I need in order to get the image in this format. Thanks in advance for any help!
  2 Comments
Image Analyst
Image Analyst on 14 Sep 2024
I'm not exactly sure where the boundaries of the cell would be. In general, yes, in a very rough sense but not if you want it to be accurate down to the nearest pixel. Can you post an annotated one where you've drawn in the outlines, say, in red?
Would you be willing to place markers or points on the vertices of the cells? If so, a human assisted algorithm might work and be faster than trying to develop an automated algorithm, especially if you have only a handful of images, not thousands of them.
MBP
MBP on 14 Sep 2024
Thanks for responding so quickly!
The pattern can be estimated as a diamond, and for now I will be satisfied with even a rough estimate of the width, height, area, and centroid location of the cell. To that end, if there was a way to somehow "close the gaps" that would work as well. I am also willing, as you said, to place points on the cell vertices, but will need to figure out a way to automate this because I'm going to be looking at a number of images (perhaps not thousands, but enough to make manual placement of markers a no-go).
Essentially, what I'm going to be doing is taking an average value of the cell metrics and defining a distribution, say, the mean width, , and so on.
I've attempted to annotate the image, as you suggesed using red lines to extend the edges to where they would meet and form a vertex. This is rough, but, as I said, will give me a good first estimate to start.

Sign in to comment.

Accepted Answer

Image Analyst
Image Analyst on 16 Sep 2024
Try this:
clear all; close all; clc
% Load the synthetic detonation pattern image
gray_image = imread('CellularPattern_Test.png');
% Step 1: Convert to grayscale (if the image is RGB)
if size(gray_image, 3) == 3
gray_image = rgb2gray(gray_image);
end
hFig1 = figure('Name', 'Analysis by Image Analyst');
subplot(2, 3, 1);
imshow(gray_image);
title('Original Image')
[gradMag] = imgradient(gray_image);
subplot(2, 3, 2);
imshow(gradMag, []);
title('Gradient Magnitude')
subplot(2, 3, 3);
histogram(gradMag)
grid on;
threshold = 35;
xline(threshold, 'Color', 'r', 'LineWidth', 2)
binaryGrad = gradMag > threshold;
subplot(2, 3, 4);
imshow(binaryGrad, []);
impixelinfo
title('Gradient Magnitude above threshold')
binaryGrad = imdilate(binaryGrad,strel('disk', 2));
subplot(2, 3, 5);
imshow(binaryGrad);
title('Binary Image after Dilation')
% Get areas of blobs
props = regionprops(binaryGrad, 'Area')
subplot(2, 3, 6);
allAreas = sort([props.Area], 'ascend')
histogram(allAreas, 1000);
title('Histogram of blob areas')
% Remove very small components (noise) if necessary
% Use bwareaopen to remove small components (e.g., areas smaller than 1000 pixels)
binaryGrad = bwareafilt(binaryGrad, 1);
subplot(2, 3, 6);
imshow(binaryGrad);
title('Binary Image after Size Filter');
% Invert the image and remove blobs touching the border (partial blobs).
mask = imclearborder(~binaryGrad);
hfig2 = figure('Name', 'Analysis by Image Analyst');
subplot(2, 3, 1);
imshow(mask);
title('Individual Cells');
hfig2.WindowState = 'maximized';
% Shrink blobs to disconnect them.
se = strel('disk', 3, 0);
mask = imerode(mask, se);
% Grow them back out but don't let them reconnect.
mask = bwmorph(mask, 'thicken', 3);
% Get areas of blobs
props = regionprops(mask, 'Area')
subplot(2, 3, 2);
allAreas = sort([props.Area], 'ascend')
histogram(allAreas, 1000);
grid on;
title('Histogram of blob areas')
% Get rid of small blobs.
mask = bwareafilt(mask, [1000, inf]);
% Fill holes and get convex hull
mask = bwconvhull(mask, 'objects', 4);
subplot(2, 3, 3);
imshow(mask);
title('Individual Cells');
% Label each blob with 8-connectivity, so we can make measurements of it
[labeledImage, numberOfBlobs] = bwlabel(mask, 8);
% Apply a variety of pseudo-colors to the regions.
coloredLabelsImage = label2rgb (labeledImage, 'hsv', 'k', 'shuffle');
% Display the pseudo-colored image.
imshow(coloredLabelsImage);
% Get areas of blobs
props = regionprops(mask, 'Area')
subplot(2, 3, 4);
allAreas = sort([props.Area], 'ascend')
histogram(allAreas, 1000);
grid on;
title('Histogram of final blob areas')
% Get boundaries and display them over original image.
boundaries = bwboundaries(mask);
subplot(2, 3, 5:6);
imshow(gray_image);
title('Individual Cells');
hold on;
visboundaries(boundaries);
  1 Comment
MBP
MBP on 16 Sep 2024
On first glance, this looks like exactly what I was hoping to get...thanks so much for the insight! I'm going to look into your code to better understand the various operations. Really excellent work!

Sign in to comment.

More Answers (1)

Image Analyst
Image Analyst on 14 Sep 2024
I think I can get fairly close. Can you give the code where you start with the image and get the binary/segmented image of the edges? Then I will try inverting the image and calling imerode and then bwmorph to grow them back out without joining them. Then call imclearborder (to get rid of partial blobs) and regionprops (to measure parameters).
By the way, you might like to look at my attached average cell shape demo, and my edge linking demo.
  1 Comment
MBP
MBP on 15 Sep 2024
The code snippet that takes my original image and gets to the segmented image is attached. In the meantime, I'll go through the demos you have attached and try to understand the steps; I'm looking forward to seeing anything you are able to produce using my original image. Thanks in advance!

Sign in to comment.

Categories

Find more on Image Processing Toolbox in Help Center and File Exchange

Products


Release

R2021b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!