Estimation of particle size in the image

11 views (last 30 days)
Hi,
I am trying to estimate size of the particle in the attached image. As this image has both the particles and other shapes, hence, it is bit difficult to estimate the size of the particle alone. Could someone help with this?

Accepted Answer

Image Analyst
Image Analyst on 2 May 2024
Yes, it's pretty easy. Would be better if you could also post an image with just the background in there. Can we assume that the stream is always in a v ertical line along the same column numbers in the image? Might not need the background image if we can just mask out a thin strip in the middle.
It's a generic, general purpose demo of how to threshold an image to find blobs, and then measure things about the blobs, and extract certain blobs based on their areas or diameters.
If you still need help, post your original image -- not the one with a huge white surrounding frame on it.
  2 Comments
Turbulence Analysis
Turbulence Analysis on 3 May 2024
Hi Image Analyst,
Thanks very much for the suggestion. I indeed tried your Image segmentation tutorial, it's very helpful. Infact I had used it in the past for other applications.
In the current application, the issue I am facing is background correction, for e.g. In the image there are some inherent particles present which is actually originaed from the dust in the lens. This shouldn't be accounted while calculating the size.
I am attaching you here the actual and background images. Moreover, the stream is relatively verticaly, but not always in the same line (for e.g. please refer Image 2).
Turbulence Analysis
Turbulence Analysis on 3 May 2024
Sorry forgot to mention, another major issue is presence of thin strip in the middle.

Sign in to comment.

More Answers (1)

Image Analyst
Image Analyst on 3 May 2024
Try this:
% Demo by Image Analyst
% Initialization steps:
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 16;
%--------------------------------------------------------------------------------------------------------
% READ IN BACKGROUND IMAGE
folder = pwd;
baseFileName = "BACKGROUND.bmp";
fullFileName = fullfile(folder, baseFileName);
% Check if file exists.
if ~isfile(fullFileName)
% The file doesn't exist -- didn't find it there in that folder.
% Check the entire search path (other folders) for the file by stripping off the folder.
fullFileNameOnSearchPath = baseFileName; % No path this time.
if ~exist(fullFileNameOnSearchPath, 'file')
% Still didn't find it. Alert user.
errorMessage = sprintf('Error: %s does not exist in the search path folders.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
% Read in image file.
backgroundImage = imread(fullFileName);
% Get size
[rows, columns, numberOfColorChannels] = size(backgroundImage)
if numberOfColorChannels == 3
% Convert to gray scale if needed.
backgroundImage = rgb2gray(backgroundImage);
end
% Display the image.
subplot(2, 3, 1);
imshow(backgroundImage);
axis('on', 'image');
impixelinfo;
title('Background Image', 'FontSize', fontSize, 'Interpreter', 'None');
% Maximize window.
g = gcf;
g.WindowState = 'maximized';
g.Name = 'Demo by Image Analyst';
g.NumberTitle = 'off';
drawnow;
%--------------------------------------------------------------------------------------------------------
% READ IN TEST IMAGE
folder = pwd;
baseFileName = "image 1.bmp";
fullFileName = fullfile(folder, baseFileName);
% Check if file exists.
if ~isfile(fullFileName)
% The file doesn't exist -- didn't find it there in that folder.
% Check the entire search path (other folders) for the file by stripping off the folder.
fullFileNameOnSearchPath = baseFileName; % No path this time.
if ~exist(fullFileNameOnSearchPath, 'file')
% Still didn't find it. Alert user.
errorMessage = sprintf('Error: %s does not exist in the search path folders.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
% Read in image file.
grayImage = imread(fullFileName);
% Get size
[rows, columns, numberOfColorChannels] = size(grayImage)
if numberOfColorChannels == 3
% Convert to gray scale if needed.
grayImage = rgb2gray(grayImage);
end
% Display the image.
subplot(2, 3, 2);
imshow(grayImage);
axis('on', 'image');
impixelinfo;
title('Original Image', 'FontSize', fontSize, 'Interpreter', 'None');
%--------------------------------------------------------------------------------------------------------
% DIVIDE THE TEST IMAGE BY THE BACKGROUND IMAGE.
backgroundCorrectedImage = double(grayImage) ./ double(backgroundImage);
% Crop out middle part
backgroundCorrectedImage = backgroundCorrectedImage(:, 400:600);
subplot(2, 3, 3);
imshow(backgroundCorrectedImage, []);
axis('on', 'image');
impixelinfo;
title('Background corrected Image', 'FontSize', fontSize, 'Interpreter', 'None');
subplot(2, 3, 4);
% Show histogram.
histogram(backgroundCorrectedImage)
grid on;
title('Histogram of Background Image', 'FontSize', fontSize, 'Interpreter', 'None');
%--------------------------------------------------------------------------------------------------------
% CREATE MASK
% It's where the image is not near 1.
tolerance = 0.4; % Adjust as needed.
mask = abs(backgroundCorrectedImage - 1) > tolerance;
subplot(2, 3, 5);
imshow(mask);
axis('on', 'image');
impixelinfo;
title('Initial Mask Image', 'FontSize', fontSize, 'Interpreter', 'None');
%--------------------------------------------------------------------------------------------------------
% Fill any holes.
mask = imfill(mask, 'holes');
% Delete top stream and any blobs touching the edge of the image (because they are partial droplets not full droplets).
mask = imclearborder(mask);
% 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 mask image.
subplot(2, 3, 6);
imshow(coloredLabelsImage);
axis('on', 'image');
impixelinfo;
%--------------------------------------------------------------------------------------------------------
% GET AREAS AND DIAMETERS
blobMeasurements = regionprops(mask, 'Area', 'EquivDiameter');
numberOfDroplets = size(blobMeasurements, 1)
allAreas = [blobMeasurements.Area]
allDiameters = [blobMeasurements.EquivDiameter]
caption = sprintf('Final Mask Image with %d Droplets', numberOfDroplets);
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
numberOfDroplets =
5
allAreas =
586 561 447 569 55
allDiameters =
Columns 1 through 4
27.3151674571987 26.7261554398762 23.8566149421207 26.9160417029382
Column 5
8.368283871884
Answers are in pixels. Multiply by microns per pixel to get your answers in microns or square microns.
  25 Comments
Turbulence Analysis
Turbulence Analysis on 14 May 2024
with command props = regionprops(binaryImage , 'BoundingBox'); I just got the below shown values, in which column 4 representing the y bottom value and the value in the column 1 may be representing the x position, but I looked on the attached image, unfortunately although Y position is correct but not the x value.
Turbulence Analysis
Turbulence Analysis on 14 May 2024
Finally, I found it. The X values are in props.Extrema;
The below command would do
props = regionprops(binaryImage , 'all');
B1 = props.Extrema;
X = mean (B1(:,1);

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!