4
votes

I've got a series of XY point pairs in MATLAB. These pairs describe points around a shape in an image; they're not a function, meaning that two or more y points may exist for each x value.

I can plot these points individually using something like

plot(B(:,1),B(:,2),'b+');

I can also use plot to connect the points:

plot(B(:,1),B(:,2),'r');

What I'm trying to retrieve are my own point values I can use to connect the points so that I can use them for further analysis. I don't want a fully connected graph and I need something data-based, not just the graphic that plot() produces. I'd love to just have plot() generate these points (as it seems to do behind the scenes), but I've tried using the linseries returned by plot() and it either doesn't work as I understand it or just doesn't give me what I want.

I'd think this was an interpolation problem, but the points don't comprise a function; they describe a shape. Essentially, all I need are the points that plot() seems to calculate; straight lines connecting a series of points. A curve would be a bonus and would save me grief downstream.

How can I do this in MATLAB?

Thanks!

Edit: Yes, a picture would help :)

The blue points are the actual point values (x,y), plotted using the first plot() call above. The red outline is the result of calling plot() using the second approach above. I'm trying to get the point data of the red outline; in other words, the points connecting the blue points. alt text

3
A sample image would help immensely... you know, worth a thousand words and all. ;)gnovice
@Mike O'Malley: see mathworks.com/help/techdoc/ref/interp1.html for linear interpolation. This is what plot does by connecting adjacent data points.zellus
Are these points ordered, such that each point i follows the last point i-1 around the edge of the shape in the same direction (i.e. clockwise or counter-clockwise)? Or could some of those closely clustered points reverse direction?gnovice
I suppose at the stage where you are plotting the points they must be ordered for achieving a shape as shown in your plot. I guess a piecewise interpolation should be feasable.zellus
@Mike: Zellus is actually right, you just have to think outside the box and forget about y being a function of x. Just use some parametric coordinate along the plot line. (see answer below).Adrien

3 Answers

6
votes

Adrien definitely has the right idea: define a parametric coordinate then perform linear interpolation on the x and y coordinates separately.

One thing I'd like to add is another way to define your parametric coordinate so you can create evenly-spaced interpolation points around the entire shape in one pass. The first thing you want to do, if you haven't already, is make sure the last coordinate point reconnects to the first by replicating the first point and adding it to the end:

B = [B; B(1,:)];

Next, by computing the total distance between subsequent points then taking the cumulative sum, you can get a parametric coordinate that makes small steps for points close together and larger steps for points far apart:

distance = sqrt(sum(diff(B,1,1).^2,2));  %# Distance between subsequent points
s = [0; cumsum(distance)];               %# Parametric coordinate

Now, you can interpolate a new set of points that are evenly spaced around the edge along the straight lines joining your points using the function INTERP1Q:

sNew = linspace(0,s(end),100).';   %'# 100 evenly spaced points from 0 to s(end)
xNew = interp1q(s,B(:,1),sNew);     %# Interpolate new x values
yNew = interp1q(s,B(:,2),sNew);     %# Interpolate new y values

These new sets of points won't necessarily include the original points, so if you want to be sure the original points also appear in the new set, you can do the following:

[sAll,sortIndex] = sort([s; sNew]);  %# Sort all the parametric coordinates
xAll = [B(:,1); xNew];               %# Collect the x coordinates
xAll = xAll(sortIndex);              %# Sort the x coordinates
yAll = [B(:,2); yNew];               %# Collect the y coordinate
yAll = yAll(sortIndex);              %# Sort the y coordinates


EXAMPLE:

Here's an example to show how the above code performs (I use 11 pairs of x and y coordinates, one of which is repeated for the sake of a complete example):

B = [0.1371 0.1301; ...  %# Sample data
     0.0541 0.5687; ...
     0.0541 0.5687; ...  %# Repeated point
     0.0588 0.5863; ...
     0.3652 0.8670; ...
     0.3906 0.8640; ...
     0.4090 0.8640; ...
     0.8283 0.7939; ...
     0.7661 0.3874; ...
     0.4804 0.1418; ...
     0.4551 0.1418];
%# Run the above code...
plot(B(:,1),B(:,2),'b-*');  %# Plot the original points
hold on;                    %# Add to the plot
plot(xNew,yNew,'ro');       %# Plot xNew and yNew

alt text

2
votes

I'd first define some parametric coordinate along the different segments (i.e. between the data points)

s = 1:size(B,1);

Then, just use interp1 to interpolate in s space. e.g. If you want to generate 10 values on the line between data point 5 and 6 :

s_interp = linspace(5,6,10); % parametric coordinate interpolation values
x_coord = interp1(s,B(:,1),s_interp,'linear');
y_coord = interp1(s,B(:,2),s_interp,'linear');

This should do the trick.

A.

0
votes

Actually there is a MATLAB function "improfile", which might help you in your problem. Lets say these are the 4 coordinates which you want to find the locations between these coordinates.

xi=[15 30 20 10];
yi=[5 25 30 50];

figure;
plot(xi,yi,'r^-','MarkerSize',12)
grid on

enter image description here

Just generate a random image and run the function

n=50; % total number of points between initial coordinates
I=ones(max([xi(:);yi(:)]));
[cx,cy,c] = improfile(I,xi,yi,n);

hold on, plot(cx,cy,'bs-','MarkerSize',4)

enter image description here

Hope it helps