Reputation: 61
I have a problem that I think is pretty simple, but I am stuck. Help would be appreciated.
I have two outlines of a structure that are closed but not circular as x/y coordinates. One of them is completely within the area of the other, so they don't intersect and have different lengths (think of two deformed, concentric cirlces). My goal is to find the line that traces the middle of the two lines, like the "ridge" between them. I have tried different approaches (like, for example, using rotating lines, determining the intersections and taking the mean of the two coordinates). I have the feeling that this is not complicated and that there maybe even some built-in method, but I simply don't find the solution...
Thanks for your help!
edit: something like the attached image - blue and red are the two outlines, green is my (manually;)) inserted center line.
Upvotes: 4
Views: 96
Reputation: 125854
A general approach that should work whether you have outline points at regular grid locations (like in your example) or not is as follows. I'll start with a set of coordinate points for an inner polygon (xInner
and yInner
, 18 points) and an outer polygon (xOuter
and yOuter
, 22 points) selected from within the unit square:
plot(xOuter([1:end 1]), yOuter([1:end 1]), 'b*-');
hold on;
plot(xInner([1:end 1]), yInner([1:end 1]), 'r*-');
Then we create a grid across the region using meshgrid
, interpolate the values at each point using griddata
(assigning a value of 1
to the outer polygon points and 2
to the inner polygon points), and plot the contour line corresponding to the value 1.5
:
[X, Y] = meshgrid(linspace(0, 1, 101));
Z = griddata([xInner; xOuter], ...
[yInner; yOuter], ...
[2.*ones(size(xInner)); ones(size(xOuter))], X, Y);
[C, H] = contour(X, Y, Z, [1.5 1.5]);
This gives a higher resolution contour between the two curves in C
.
Upvotes: 2
Reputation: 26069
here's an algorithm for lack of minimal example:
find all indices (X1,Y1) of curve1
find all indices (X2,Y2) of curve2
loop over all points in curve 1, and for each point in curve 1 find the minimal distance to curve 2 and the direction, the minimization is done via d=min(sqrt((X2-X1)^2+(Y2-Y1)^2))
.
The direction is given by theta=atan2((Y1-Y2)/(X1-X2))
.
once you have that, the curve you seek is at half the minimal distance with the same theta...
EDIT: as @m7913d pointed out correctly, once you have found the minimal distance between each X1,Y1 and X2,Y2 you can take the avg to get the X3,Y3 of the curve you want... no real need for angle estimation...
Here's an example:
c=fspecial('gaussian',51,5);
c1=edge(c>1e-3);
c2=edge(c>1e-4);
[x1 y1]=find(c1);
[x2 y2]=find(c2);
for n=1:numel(x2)
[val id]=min(sqrt((x2(n)-x1).^2+(y2(n)-y1).^2));
x3(n)=(x2(n)+x1(id))/2;
y3(n)=(y2(n)+y1(id))/2;
end
imagesc(c2+c1*2); hold on
plot(y3,x3,'w.');
Upvotes: 1