【问题标题】:interpolating or fitting spline issues插值或拟合样条问题
【发布时间】:2015-08-31 04:31:21
【问题描述】:

我在插值和/或拟合样条曲线时遇到了一些问题。我的问题有两个方面。

我正在手动选择图像上的点,并希望在它们之间插入点。我点击的点是固定的,任何插值都必须经过这些点。没有固定的点数。一个图像可能有 5 个,另一个可能有 20 个(尽管我保持至少 5 个)。这些点不是均匀分布在需要插值的直线上。事实上,大多数时候都有很大的空白需要填补。所有点都记录为xy 坐标值,使用:

[x,y] = ginput; 

每个(完整)样条线的长度必须为 szG(通常为 100)。所以我计算了xy 插值,并且yy 被反转,因为它被覆盖在图像上并且绘图/图像索引被反转:

xx = min(x):(max(x)-min(x)-1)/(szG-1):max(x);
yy = max(y):-(max(y)-min(y)-1)/(szG-1):min(y);

然后我计算曲线:

newX = interp1(y,x,yy, 'cubic');
newY = interp1(x,y,xx, 'cubic');

但是,当我绘制这些图时,插值线不会通过初始点。很多时候它实际上很远。

第二个问题是通常两个选定的点具有相同的xy 值。这意味着在插值时我会遇到错误,因为值需要不同。

如何确保插值线穿过选定的数据点?另外,如何解决不同价值的问题?

【问题讨论】:

    标签: matlab interpolation


    【解决方案1】:

    您遇到的一个问题是您没有正确地反转图像坐标。你的轴的原点需要在左上角,而不是左下角,所以简单地否定y不会为你做这项工作。您需要确保原点位于左上角,因此您需要获取 y 坐标并减去总行数以方便此操作。但是,无需手动操作即可反转坐标的一个技巧是在图形本身上进行。这样,您不必担心进行任何计算来反转y 轴。只需在图形打开后执行此操作:

    axis ij;
    

    要恢复到原点位于左下角的原始系统,只需执行以下操作:

    axis xy;
    

    但是,如果您使用imshow 来显示图像,那么绝对不需要反转y 坐标,因为这在您显示图像时已经生效(又名axis ij 在后台调用)。

    如果您确实想自己手动反转坐标,只需假设您的图像存储在 im 中即可:

    y = size(im, 1) - y;
    

    此外,您没有正确使用interp1。您使用xy 指定控制点,并使用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 函数来做到这一点。具体来说,将xy 坐标放入二维数组,并根据行过滤掉点。这样,您将消除任何非唯一的 xy 对,以便在 interp1 中使用。像这样的:

    out = unique([x(:) y(:)], 'rows', 'stable');
    x = out(:,1);
    y = out(:,2);
    

    unique 也有一个副作用,即点按排序顺序排列,因此第一列用作排序键。您可能不希望这样,并且希望保持与单击该图时相同的点顺序。因此,您需要使用'stable' 标志来确保不会发生这种情况。在此操作之后,xy 现在将包含 distinct 坐标以用于interp1


    希望这会有所帮助。祝你好运!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-12-21
      • 1970-01-01
      • 2018-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-26
      • 2021-02-23
      相关资源
      最近更新 更多