Image analysis. Measure the radius of a bending filament as a function of arc length

5 views (last 30 days)
bernardo palacios muniz
bernardo palacios muniz on 3 Sep 2021
Answered: darova on 6 Sep 2021
I need help measuring the radius of the filament on the image bellow.
So far my approach is to binarize the image and fill holes, which results in the next image BW
What I am trying to do next is to find the centerline and measure the radius normal to that center line. However this is where I fail. To find the centerline I first tried using bwskel, but the results where unsatisfactory.
I followed the suggested approach by ̌Image Analyst to find the centerline of the filament on his answer to this very related question https://nl.mathworks.com/matlabcentral/answers/508300-how-to-find-the-centreline-of-two-curves?s_tid=mwa_osa_a . Howerve for me, the radius is changing so the minimum distance approach is not working great.
%Find the 2 edges and label them
BWE=edge(BW);
BWE=bwlabel(BWE);
%obtain the points for each edge
[row,col]=find(BWE==1);
edge1=[col,row];
[row,col]=find(BWE==2);
edge2=[col,row];
x1=edge1(:,1);
y1=edge1(:,2);
x2=edge2(:,1);
y2=edge2(:,2);
%find the closest point on edge 1 for each point of edge 2
[D,idx]=pdist2(edge1,edge2,"euclidean","Smallest",1);
edge1_closest=edge1(idx,:);
%plot the edges and the minimum distance between them over the original image
imshow(I)
hold on
plot(edge1(:,1),edge1(:,2),'*b')
plot(edge2(:,1),edge2(:,2),'*r')
for c=1:size(edge1,1)
plot([edge1_closest(c,1);edge2(c,1)],[edge1_closest(c,2);edge2(c,2)],'g')
end
hold off
The result is
If I close in yu can see that the center of the green lines do not represent the centerline :(
And this is where I stand. Any hep to obtain a better centerline or to find a way to measure the radius as a function of the arc length is very much apreaciated
Thank you all for your help,
Bernardo

Answers (1)

darova
darova on 6 Sep 2021
See this example. Red lines are normals from first edge/curve. I'd use polyxpoly to calculate intersections between normals and the right(second) edge
BW = imread('image.jpeg');
BW1 = im2bw(BW,0.65);
[col1,col2] = deal(zeros(size(BW1,1),1));
for i = 1:size(BW1,1) % read each row of the image
col1(i) = find(~BW1(i,:),1,'first'); % find first black pixel (left edge)
col2(i) = find(~BW1(i,:),1,'last'); % find last black pixel (right edge
end
% take only n-th element and interpolate curves (to smooth)
x1 = col1;
y1 = 1:numel(col1);
ii = 1:20:numel(col1);
x1 = spline(y1(ii),x1(ii),y1); % interpolation (taking each 20th element)
x2 = col2;
y2 = 1:numel(col2);
ii = 1:20:numel(col2);
x2 = spline(y2(ii),x2(ii),y2);
% find tangent
dx1 = diff(x1);
dy1 = diff(y1);
dx2 = diff(x2);
dy2 = diff(y2);
ii = 1:50:numel(x1);
imshow(BW1)
line(x1,y1)
line([x1(ii); x1(ii)+dy1(ii)*100], [y1(ii); y1(ii)-dx1(ii)*100],'color','r')
line(x2,y2)

Community Treasure Hunt

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

Start Hunting!