您遇到的一个问题是您没有正确地反转图像坐标。你的轴的原点需要在左上角,而不是左下角,所以简单地否定y 轴不会为你做这项工作。您需要确保原点位于左上角,因此您需要获取 y 坐标并减去总行数以方便此操作。但是,无需手动操作即可反转坐标的一个技巧是在图形本身上进行。这样,您不必担心进行任何计算来反转y 轴。只需在图形打开后执行此操作:
axis ij;
要恢复到原点位于左下角的原始系统,只需执行以下操作:
axis xy;
但是,如果您使用imshow 来显示图像,那么绝对不需要反转y 坐标,因为这在您显示图像时已经生效(又名axis ij 在后台调用)。
如果您确实想自己手动反转坐标,只需假设您的图像存储在 im 中即可:
y = size(im, 1) - y;
此外,您没有正确使用interp1。您使用x 和y 指定控制点,并使用xx 作为新的输入坐标。输出将为您提供 new y 沿这条线插值的坐标,xx 是要插值的查询点。因此,您可以直接使用interp1 的输出作为结果,并且只需要调用一次。
这是一个可重现的示例。假设你有图像处理工具箱:
im = imread('cameraman.tif');
imshow(im);
[x,y] = ginput(5);
在这里,我选择 5 分。请注意,我不需要反转 y 轴,因为 imshow 已经为您做到了。我选择了这 5 个坐标:
>> x
x =
23.0000
71.0000
143.0000
200.0000
238.0000
>> y
y =
75
43
27
47
77
现在让我们用这些点制作样条线:
szG = 100;
xx = min(x):(max(x)-min(x)-1)/(szG-1):max(x);
yy = interp1(x, y, xx, 'cubic');
如果我能说明一点,您可以使用linspace 为您的xx 坐标做同样的事情:
xx = linspace(min(x), max(x), szG);
现在让我们显示这些点,其中关键点用蓝色大圆圈表示,红色是插值线:
hold on;
plot(x, y, 'b.', 'MarkerSize', 16);
plot(xx, yy, 'r');
这是我得到的:
我得到了通过控制点的点,这可能是因为你没有正确使用interp1。现在,要解决您有重复点的问题。这对interp1 一点用处都没有,所以我建议的一件事是过滤掉任何不唯一的二维点,您可以使用unique 函数来做到这一点。具体来说,将x 和y 坐标放入二维数组,并根据行过滤掉点。这样,您将消除任何非唯一的 x 和 y 对,以便在 interp1 中使用。像这样的:
out = unique([x(:) y(:)], 'rows', 'stable');
x = out(:,1);
y = out(:,2);
unique 也有一个副作用,即点按排序顺序排列,因此第一列用作排序键。您可能不希望这样,并且希望保持与单击该图时相同的点顺序。因此,您需要使用'stable' 标志来确保不会发生这种情况。在此操作之后,x 和 y 现在将包含 distinct 坐标以用于interp1。
希望这会有所帮助。祝你好运!