Find centroid of curve
8 次查看(过去 30 天)
显示 更早的评论
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
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/732184/image.png)
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?
0 个评论
采纳的回答
Bjorn Gustavsson
2021-9-8
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 个评论
Bjorn Gustavsson
2021-9-8
The choise of the starting-point and initial step-direction was simply to find "the natural end-point" of the 'h' character at the "red +". That just conveniently happened to be the max y-value of the perimeter, and the initial step ought to be perpendicular to the curve at that point (I think it mathematically has to, but are too lazy to prove this) - therefore it should be in the downward direction at -pi/2. So for your "M" character you will have to pick some point on either left or right foot and set a phi0 corresponding to a stepping-direction perpendicular to the perimeter there. However, I'm not entirely sure this algorithm will be general enough to handle the branching of "M" and "R" seems to be an even tricker problem. For that case you might need a completely different approach, I recall Steve Eddins making blog-posts about this, what I find in a hurry are his series on detecting the US continental divide (continental-divide-1-intro) and river-drainage basins (upslope-area). Exactly how complicated curves you will be determined by how complicated characters you need to simplify...
HTH
Bjorn Gustavsson
2021-9-8
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.
更多回答(1 个)
Image Analyst
2021-9-8
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.
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!