4

I have a set of 2D points (not ordered) forming a closed contour, and I would like to resample them to 14 equally spaced points. It is a contour of a kidney on an image. Any ideas?

chappjc
  • 30,359
  • 6
  • 75
  • 132
user1367988
  • 383
  • 1
  • 4
  • 9
  • Your asking about a 2D contour (I think), so this is not exactly a duplicate, but perhaps it's helpful: http://stackoverflow.com/q/19532906/2778484 – chappjc Dec 11 '14 at 18:33
  • The contour is a kidney contour, so it is not a straight line, but more os less like a circle. – user1367988 Dec 11 '14 at 18:36
  • But is the intent to have a closed contour (with an area associated) or just a curve in 2D space? – chappjc Dec 11 '14 at 18:37
  • The contour is closed and formed by points that are attached to each other. Now I just want to select 14 of them. – user1367988 Dec 11 '14 at 18:42
  • It's probably not a matter of just selecting 14. Resampling involves interpolation unless you are doing nearest neighbor interpolation, which will not guarantee equally spaced points. – chappjc Dec 11 '14 at 18:50

2 Answers2

5

One intuitive approach (IMO) is to create an independent variable for both x and y. Base it on arc length, and interpolate on it.

% close the contour, temporarily
xc = [x(:); x(1)];
yc = [y(:); y(1)];

% current spacing may not be equally spaced
dx = diff(xc);
dy = diff(yc);

% distances between consecutive coordiates
dS = sqrt(dx.^2+dy.^2);
dS = [0; dS];     % including start point

% arc length, going along (around) snake
d = cumsum(dS);  % here is your independent variable
perim = d(end);

Now you have an independent variable and you can interpolate to create N segments:

N = 14;
ds = perim / N;
dSi = ds*(0:N).'; %' your NEW independent variable, equally spaced

dSi(end) = dSi(end)-.005; % appease interp1

xi = interp1(d,xc,dSi);
yi = interp1(d,yc,dSi);

xi(end)=[]; yi(end)=[];

Try it using imfreehand:

figure, imshow('cameraman.tif');
h = imfreehand(gca);
xy = h.getPosition; x = xy(:,1); y = xy(:,2);
% run the above solution ...
chappjc
  • 30,359
  • 6
  • 75
  • 132
  • This is great, but do note that the OP mentioned that the set of points is not ordered. In that case, you need to order the points first, and there isn't a unique way to do that. You can look at [Sorting of Points in 2D space](http://stackoverflow.com/questions/4861595/sorting-of-points-in-2d-space) for cues. – Pepe Mandioca Aug 02 '15 at 16:08
  • 1
    @facuq Thanks for pointing that out. I suppose I missed that part, but I didn't even remember this question to be honest. Thanks for the link too. [This](http://www.mathworks.com/help/matlab/math/computing-the-convex-hull.html) may also be helpful. I wonder if the OP had an ordered set after all? Oh well... – chappjc Aug 02 '15 at 16:34
  • I just pointed it out for future reference, your response was great, the op probably figured it out. Computing the convex hull is useful if the polygon is convex, which probably isn't. In that case, you can use [this matlab code to do it](https://gist.github.com/facundoq/39b4772151291fd41543) – Pepe Mandioca Aug 03 '15 at 00:35
-1

Say your contour is defined by independent vector x and dependent vector y.

You can get your resampled x vector using linspace:

new_x = linspace(min(x),max(x),14); %14 to get 14 equally spaced points

Then use interp1 to get new_y values at each new_x point:

new_y = interp1(x,y,new_x);

There are a few interpolation methods to choose from - default is linear. See interp1 help for more info.

Steve Osborne
  • 680
  • 4
  • 12
  • That will get you points uniformly distributed in the x dimension, but not uniformly distiributed in the contour, which is what the OP was looking for. – Pepe Mandioca Aug 02 '15 at 16:10