35 views (last 30 days)

Show older comments

Given this curve,I would like to find the centroid of the curve.

Currently I am selecting the piece wise splines and using the Inter X module to find out where the projection of one spline will intersect the other spline.

However the issue with this method is that some points are not matched properly.

Therefore is there a way to find the centroid of the following set of spline points.

Result figure

As you can see at some points interX returns Null I tried doing it from right to left,but that gives indice exceeds error.

Also given the set of points can I skeletonize them?

Bjorn Gustavsson
on 8 Sep 2021

Something like this ought to work:

[~,iEnd] = max(spline_pts(1,:));

[~,iStart] = max(spline_pts(2,:));

R1 = spline_pts(:,iStart:iEnd);

R2 = fliplr([spline_pts(1,[iEnd:end,1:iStart]);spline_pts(2,[iEnd:end,1:iStart])]);

xC = spline_pts(1,:);

yC = spline_pts(2,:);

r0 = R1(:,1)';

phi0 = -pi/2;

h = 0.5;

r_next = @(phi,r0,h) r0 + h*[cos(phi),sin(phi)]; % function for dr in x-y plane

r_n = r_next(phi0,r0,h);

r_N = [];

clf

plot(R1(1,:),R1(2,:),'r','linewidth',2)

hold on

plot(R2(1,:),R2(2,:),'g','linewidth',2)

plot(R1(1,1),R1(2,1),'r.','markersize',15)

plot(R2(1,1),R2(2,1),'g.','markersize',12)

plot(r0(1),r0(2),'k.')

OPS = optimoptions('fsolve');

OPS.Display = 'off';

while inpolygon(r_n(1),r_n(2),xC,yC) % while the next step is inside

% look for the h-long step with the same shortest distance to R1 and R2

phi_n = fsolve(@(phi) min(distance2curveBG(R1',r_next(phi,r0,h))) - ...

min(distance2curveBG(R2',r_next(phi,r0,h))),...

phi0,OPS);

% calculate

r_n = r_next(phi_n,r0,h);

r_N = [r_N;r_n]; % yeah, yeah, dynamically appending etc...

r0 = r_n; % move r0 one step forward

phi0 = phi_n;

plot(r_n(1),r_n(2),'k.')

drawnow

end

This worked on a very simple test-case I tried, and for your curve. Here I used distance2curve from the file exchange, but in order to use it here I had to swap the order of the first and second output argument of that function, hence the name-change.

HTH

Bjorn Gustavsson
on 8 Sep 2021

Image Analyst
on 8 Sep 2021

Maybe you can convert the points to a digital image and then skeletonize it. Something like

binaryImage = poly2mask(x, y, rows, columns);

skelImage = bwskel(binaryImage);

% Get rows and columns of the skeleton

[rows, columns] = find(skelImage);

Requires the Image Processing Toolbox.

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

Start Hunting!