I'm having some trouble with interpolating and/or fitting splines. There are two aspects to my issue.
I am selecting points on an image manually, and want to interpolate the points between. The points I am clicking on are fixed, and any interpolation MUST go through these points. There is not a fixed number of points. One image may have 5, another may have 20 (although I keep to a minimum of 5). The points are not evenly distributed alone the line that needs interpolating. In fact, most of the time there are large gaps to be filled. All points are recorded as x
and y
coordinate values using:
[x,y] = ginput;
Each (full) spline needs to be of length szG
(normally 100). So I calculate the x
and y
interpolants, and the yy
is reversed as its to be overlaid on the image and plot/image indexes are reversed:
xx = min(x):(max(x)-min(x)-1)/(szG-1):max(x);
yy = max(y):-(max(y)-min(y)-1)/(szG-1):min(y);
I then calculate the curve with:
newX = interp1(y,x,yy, 'cubic');
newY = interp1(x,y,xx, 'cubic');
However, when I plot these, the interpolated line doesn't go through the initial points. It's actually quite far away a lot of the time.
The second problem is that often two selected points have the same x
or y
value. This means that I get an error when it comes to interpolation as the values need to be distinct.
How can you ensure the interpolated line goes through selected data points? Also, how can the distinct value issue be resolved?
One problem that you have is that you aren't reversing the image coordinates properly. The origin of your axis needs to be at the top left, rather than the bottom left and so simply negating the
y
axis doesn't do the job for you. You need to make sure that the origin is at the top left, and so you need to take youry
coordinates and subtract by the total number of rows to facilitate this. However, a trick to reversing the coordinates without you having to do it manually is to do it on the figure itself. This way, you don't have to worry about doing any calculations to reversing they
axis. Simply do this once the figure is open:To revert back to the original system where the origin is at the bottom left, simply do:
However, if you are using
imshow
to display your images, then there's absolutely no need to reverse they
coordinates because this is already in effect when you show the image (a.k.aaxis ij
is called under the hood).If you do want to reverse the coordinates manually yourself, simply do this assuming your image is stored in
im
:In addition, you're not using
interp1
correctly. You specify control points withx
andy
, and you usexx
as the new input coordinates. The output will give you newy
coordinates that interpolate along this line, withxx
being the query points to be interpolated. Therefore, you can just use the output ofinterp1
directly for your result and you only need to call it once.Here's a reproducible example. Assuming you have the image processing toolbox:
Here, I'm choosing 5 points. Note that I don't need to reverse the
y
axis becauseimshow
already does that for you. I've chosen these 5 coordinates:Now let's make the spline out of these points:
If I can make a minor point, you can do the same thing for your
xx
coordinates by usinglinspace
by:Now let's show these points where the keypoints are in blue with large circles and red is the interpolated line:
This is what I get:
I get the points to go through the control points, and it's probably because you're not using
interp1
properly. Now, to fix the issue where you have duplicate points. This isn't useful at all forinterp1
, so one thing I suggest is to filter out any 2D points that are not unique and you can do this by using theunique
function. Specifically, place thex
andy
coordinates into a 2D array and filter out the points based on the rows. This way, you'll eliminate any non-uniquex
andy
pairs for use ininterp1
. Something like this:unique
also has a side-effect where the points are arranged in sorted order, such that the first column is used as a sorting key. You probably don't want this and you want to maintain the same order of points as you had when you clicked on the figure. Therefore, you need to use the'stable'
flag to ensure this doesn't happen. After this operation,x
andy
will now contain distinct coordinates for use ininterp1
.Hope this helps. Good luck!