MATLAB Answers

Find centroid of curve

35 views (last 30 days)
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?

Accepted Answer

Bjorn Gustavsson
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
  4 Comments
Bjorn Gustavsson
Bjorn Gustavsson on 8 Sep 2021
If you check some combinations of where to put the end-points of the cuts to split the curve in two and build up the two sides, and then make sure that the first initial step points into the closed curve by chosing a proper phi0 then the method works as well as can be expected for all characters - however the "R" will for obvious reasons be "challenging" for this method. For that some ridge-detection or skelletoning seems more likely to give you the solution you want.

Sign in to comment.

More Answers (1)

Image Analyst
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.
  2 Comments
sparsh garg
sparsh garg on 9 Sep 2021
I was able to order them,but the ordered plot is flipped by 360 degree
R_skeleton is BW_Thinned
R_exact_skeleton is the points shown in the previous comment
and ordred_R_skeleton is the plot in this comment.
I would appreciate it if we can discuss this as per your conveninece.

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!