Plotting a graph of the distance between the centroid of an irregular shaped particle and its contour (radius) versus angle (equal intervals of theta from zero to 360 degrees)

9 views (last 30 days)
I am trying to plot a graph between the radius of an irregular shaped particle (from the centroid to a point on the contour) at equal intervals of theta around the particle (from zero to 360 degrees).
My code (I actually got most of it from here) is not giving me what I want. I would like the graph to look like that of a typical signal but with angles (0 to 360 degrees) on the x-axis and radius on the y-axis.
I would really appreciate if someone could help me get this graph so that I can proceed with further operations using the fast fourier transform algorithm
Thanks!
%Image Threshholding
clc; clearvars; clear all;
img = imread('1_50.jpg'); %Read image
BW = im2bw(img,0.45); %binarize image with a threshold value of 0.45
img2= bwareaopen (BW, 1000); %Remove small objects
img2= imfill(BW, 'holes'); %fill holes
centriod_value= regionprops(img2, 'Centroid'); %Finds centroid of image
centroid = centriod_value.Centroid; %Returns centroid in [row, column]
%Display the binary image with the centroid locations superimposed
subplot(1,3,1)
imshow(img2);
hold on
plot(centroid(:,1),centroid(:,2),'b.')
hold on
%tracing the boundary of image
p_boundary= bwboundaries(img2); % in row, column order, not x,y
number_of_boundaries = size(p_boundary,1); %one boundary
for k = 1 : length(p_boundary);
thisBoundary = p_boundary{k};
y = thisBoundary(:,2);
x = thisBoundary(:,1);
subplot(1,3,2)
plot(x, y, 'g', 'LineWidth', 2);
hold on
plot(centroid(:,1),centroid(:,2),'b.')
hold on
end
hold on
% Calculate the angles in degrees
deltaY = thisBoundary(:,1) - centroid(1);
deltaX = thisBoundary(:,2) - centroid(2);
angles = atand(deltaY ./ deltaX);
% Calculate the distances.
distances = sqrt((thisBoundary(:,1) - centroid(1)).^2 + (thisBoundary(:,2) - centroid(2)).^2);
% Plot distance vs. angle.
angle=0:360/128:360;
for i=1:length(p_boundary);
angles(i)+360/128;
subplot(1,3,3)
plot(angles,distances)
end
  2 Comments
Johnson
Johnson on 29 Mar 2024
Edited: Johnson on 29 Mar 2024
Hi, I have uploaded the image. I snipped it from a scanning electron microscope (SEM) micrograph so it's quite small.
The second image illustrates what I'm trying to do.
Thanks!

Sign in to comment.

Accepted Answer

Voss
Voss on 29 Mar 2024
Edited: Voss on 29 Mar 2024
%Image Threshholding
clc; clearvars; clear all;
img = imread('1_50.JPG'); %Read image
BW = im2bw(img,0.45); %binarize image with a threshold value of 0.45
% this does nothing useful, since img2 is overwritten in the next line:
% img2= bwareaopen (BW, 1000); %Remove small objects
img2= imfill(BW, 'holes'); %fill holes
centriod_value= regionprops(img2, 'Centroid'); %Finds centroid of image
centroid = cat(1,centriod_value.Centroid);
%Display the binary image with the centroid locations superimposed
subplot(1,3,1)
imshow(img2);
hold on
plot(centroid(:,1),centroid(:,2),'b.')
% hold on % don't need to call hold on more than once on the same axes
% for plotting into multiple axes in one loop, it's convenient to set up
% all the axes first, before anything is plotted into them
% set up the 2nd axes:
ax2 = subplot(1,3,2);
hold on
box on
axis image
set(ax2,'YDir','reverse')
% set up the 3rd axes:
ax3 = subplot(1,3,3);
hold on
%tracing the boundary of image
p_boundary= bwboundaries(img2); % in row, column order, not x,y
number_of_boundaries = size(p_boundary,1); %one boundary
for k = 1 : number_of_boundaries % use number_of_boundaries, which was just calculated
thisBoundary = p_boundary{k};
y = thisBoundary(:,1); % rows
x = thisBoundary(:,2); % columns (these were swapped)
plot(ax2, x, y, 'g', 'LineWidth', 2);
plot(ax2, centroid(:,1),centroid(:,2),'b.')
% Calculate the angles in degrees
deltaY = thisBoundary(:,1) - centroid(k,2); % boundary(:,1) is y, but centroid(k,2) is y
deltaX = thisBoundary(:,2) - centroid(k,1); % boundary(:,2) is x, but centroid(k,1) is x
% angles = atand(deltaY ./ deltaX); % atand gives angles in range [-90,90]
angles = atan2d(deltaY,deltaX); % use atan2d to get angles in range [-180,180]
% Calculate the distances.
distances = sqrt(deltaY.^2 + deltaX.^2); % use deltaX and deltaY, which were just calculated
% add 360 degrees to negative angles so that range is [0,360] instead of [-180,180]
idx = angles < 0;
angles(idx) = angles(idx)+360;
% sort the angles, so the first one is smallest (closest to zero)
% and the last one is largest (closest to 360)
% this is useful for getting a smooth line that goes from 0 to 360 in the plot
[angles,idx] = sort(angles);
% reorder distances the same way angles was reordered
distances = distances(idx);
% Plot distance vs. angle.
plot(ax3,angles,distances)
end
In your original code, after the first for loop, thisBoundary has the value corresponding to the last boundary. In this image there's only one boundary, so it doesn't matter, but in general the calculations that depend on thisBoundary (i.e., distances and angles) need to be done in a loop so that you're calculating for each boundary, not just the last one. That's why I'm doing it all in one loop.
  14 Comments
Voss
Voss on 17 May 2024
I'm not sure. I would ask your professor/advisor what exactly is involved in that.
There are others on here who know more than I do about signal processing and could probably help. But it seems to me that you probably should be using both the distances and the angles, not just the distances, in the FFT calculation. I recommend talking to your advisor and/or posting a new question about the FFT reconstruction part.

Sign in to comment.

More Answers (0)

Tags

Community Treasure Hunt

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

Start Hunting!