MATLAB Answers

how to measure the diameter of a circle

31 views (last 30 days)
Victor Falola
Victor Falola on 14 Nov 2019
Answered: Image Analyst on 19 Nov 2019
im trying to write a script to measure the diameter of this photo and dont know how to go about it.

  2 Comments

Rik
Rik on 14 Nov 2019
I think I would go for an iterative approach where I would increase the circle radius. For every iteration, check if moving the center would decrease the number of white pixels inside the circle. When the number of white pixels starts to increase dramatically, stop the process.
What would be a good cutoff for that increase probably depends on the seed location and how much noise you expect inside the circle.
Once you have the circle, calculating the diameter is of course trivial.
Image Analyst
Image Analyst on 16 Nov 2019
Rik, you put this up in the comments, when I think it should be down in the Answers section.

Sign in to comment.

Answers (3)

Walter Roberson
Walter Roberson on 14 Nov 2019
bwareafilt to remove the small noise objects inside the circle. Invert the result so the open area becomes white. bwareafilt for the largest area. Now regionprops equivalent diameter.

  5 Comments

Show 2 older comments
Image Analyst
Image Analyst on 16 Nov 2019
Something like (untested):
binaryImage = bwareafilt(~binaryImage);
binaryImage = imfill(binaryImage, 'holes');
binaryImage = bwareafilt(binaryImage, 1);
props = regionprops(binaryImage, 'EquivDiameter');
diameter = props.EquivDiameter
There might be a better way. I highly doubt that the best first step was to take an edge image. Can you post the original gray scale image.

Sign in to comment.


Image Analyst
Image Analyst on 19 Nov 2019
Try this code:
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clearvars;
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 16;
%=======================================================================================
% Have user browse for a file, from a specified "starting folder."
% For convenience in browsing, set a starting folder from which to browse.
startingFolder = pwd; % or 'C:\wherever';
if ~exist(startingFolder, 'dir')
% If that folder doesn't exist, just start in the current folder.
startingFolder = pwd;
end
% Get the name of the file that the user wants to use.
defaultFileName = fullfile(startingFolder, 'n*.*');
[baseFileName, folder] = uigetfile(defaultFileName, 'Select a file');
if baseFileName == 0
% User clicked the Cancel button.
return;
end
fullFileName = fullfile(folder, baseFileName);
rgbImage = imread(fullFileName);
% rgbImage = decorrstretch(rgbImage,'tol',0.01);
% imwrite(rgbImage, 'test.png');
% Get the dimensions of the image.
[rows1, columns1, numberOfColorChannels1] = size(rgbImage)
% Display the original image.
subplot(2, 2, 1);
imshow(rgbImage, []);
axis('on', 'image');
caption = sprintf('Original Color Image "%s"', baseFileName);
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
hp = impixelinfo(); % Set up status line to see values when you mouse over the image.
% Set up figure properties:
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0 0.05 1 0.95]);
% Get rid of tool bar and pulldown menus that are along top of figure.
% set(gcf, 'Toolbar', 'none', 'Menu', 'none');
% Give a name to the title bar.
set(gcf, 'Name', 'Demo by Image Analyst', 'NumberTitle', 'Off')
% Do a color segmentation
[mask,maskedRGBImage] = createMask(rgbImage);
% Display the mask image.
subplot(2, 2, 2);
imshow(mask, []);
axis('on', 'image');
caption = sprintf('Color Segmentation');
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
% Delete blobs touching the border.
mask = imclearborder(mask);
% Fill holes, and take the largest blob.
subplot(2, 2, 3);
mask = imfill(mask, 'holes');
mask = bwareafilt(mask, 1);
% Display the image.
subplot(2, 2, 3);
imshow(mask, []);
axis('on', 'image');
title('Final Mask Image', 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
hp = impixelinfo(); % Set up status line to see values when you mouse over the image.
% Measure the equivalent circular diameter.
props = regionprops(mask, 'EquivDiameter', 'Centroid');
% Plot these over the upper left image.
subplot(2, 2, 1);
hold on;
xCentroid = props.Centroid(1)
yCentroid = props.Centroid(2)
diameter = props.EquivDiameter
viscircles([xCentroid, yCentroid], props.EquivDiameter/2);
plot(xCentroid, yCentroid, 'r+', 'LineWidth', 2, 'MarkerSize', 100);
% Mask the image using bsxfun() function to multiply the mask by each channel individually.
maskedRgbImage = bsxfun(@times, rgbImage, cast(mask, 'like', rgbImage));
% Display the image.
subplot(2, 2, 4);
imshow(maskedRgbImage, []);
axis('on', 'image');
caption = sprintf('Masked Image. Spot Diameter = %.2f', diameter);
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
hp = impixelinfo(); % Set up status line to see values when you mouse over the image.
% Set up figure properties:
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0 0.05 1 0.95]);
% Get rid of tool bar and pulldown menus that are along top of figure.
% set(gcf, 'Toolbar', 'none', 'Menu', 'none');
% Give a name to the title bar.
set(gcf, 'Name', 'Demo by Image Analyst', 'NumberTitle', 'Off')
function [BW,maskedRGBImage] = createMask(RGB)
%createMask Threshold RGB image using auto-generated code from colorThresholder app.
% [BW,MASKEDRGBIMAGE] = createMask(RGB) thresholds image RGB using
% auto-generated code from the colorThresholder app. The colorspace and
% range for each channel of the colorspace were set within the app. The
% segmentation mask is returned in BW, and a composite of the mask and
% original RGB images is returned in maskedRGBImage.
% Auto-generated by colorThresholder app on 19-Nov-2019
%------------------------------------------------------
% Convert RGB image to chosen color space
I = rgb2hsv(RGB);
% Define thresholds for channel 1 based on histogram settings
channel1Min = 0.000;
channel1Max = 0.175;
% Define thresholds for channel 2 based on histogram settings
channel2Min = 0.366;
channel2Max = 1.000;
% Define thresholds for channel 3 based on histogram settings
channel3Min = 0.512;
channel3Max = 1.000;
% Create mask based on chosen histogram thresholds
sliderBW = (I(:,:,1) >= channel1Min ) & (I(:,:,1) <= channel1Max) & ...
(I(:,:,2) >= channel2Min ) & (I(:,:,2) <= channel2Max) & ...
(I(:,:,3) >= channel3Min ) & (I(:,:,3) <= channel3Max);
BW = sliderBW;
% Initialize output masked image based on input image.
maskedRGBImage = RGB;
% Set background pixels where BW is false to zero.
maskedRGBImage(repmat(~BW,[1 1 3])) = 0;
end
0001 Screenshot.png

  0 Comments

Sign in to comment.



Translated by