我有一个大小为28x22的矩阵。第一行,最后两行,第一列和最后两列(用红色和绿色标记)为空。这些列和行应该用双三次插值填充。

我已经在SO和Internet上阅读了几篇关于三次三次插值的文章,但不幸的是,我听不懂。此外,我读到三次三次插值需要了解需要插值的像素周围的4x4网格。但是,由于行和列在边界处,所以我周围没有4 x 4网格。

最佳答案

序言

您需要推断未知区域。您需要确定要从哪些信息推断数据。例如,您要使用在unknonw区域附近的点,或者使用在整个已知区域中分散的点。两种方法都是有效的,但具有不同的结果,可以满足不同的需求。

我将使用指向未知区域的近点。让我从一个简单的案例开始:

  • 1D线性外推

    线性外推使用由2个已知点形成的线。因此,假设此 vector :

    opencv - 使用双三次插值法填充矩阵的边界-LMLPHP

    x轴是 vector /数组索引,y轴是单元格的值。所以我取了2个最近知道的点(蓝色),并从中形成一条线(绿色)。它与下一个数组位置相交的地方是您的外推值(红色)。因此,在C++中,它看起来像这样:
    float a[8]={ 1.0,2.0,4.0,8.0,10.0,7.0,0.0,0.0 }; // your vector (last two numbers are unknown)
    a[6]=a[4]+((a[5]-a[4])*2.0); // =4.0
    a[7]=a[4]+((a[5]-a[4])*3.0); // =1.0
    
  • 一维三次外推

    它与#1 相似,但是您使用参数多项式形式的4个控制点三次曲线代替了直线。大多数三次曲线的构建方式是:如果使用t=0参数,则将获得第二个控制点;如果使用t=1参数,则将获得第三个控制点。如果使用t=<0,1>,那么您将在它们之间平滑地迭代。但是,我们需要扩大最后一个控制点之后的范围,因此t>=3和阶跃1用于下一点位置。所以:

    opencv - 使用双三次插值法填充矩阵的边界-LMLPHP
    float a[8]={ 1.0,2.0,4.0,8.0,10.0,7.0,0.0,0.0 }; // your vector (last two numbers are unknown)
    float a0,a1,a2,a3; // your cubic curve polynomial coefficients (computed from 4 control points a[2],a[3],a[4],a[5])
    float t; // curve parameter
    // here compute the a0,a1,a2,a3
    t=3.0; a[6]=a0+a1*t+a2*t*t+a3*t*t*t*t;
    t=4.0; a[7]=a0+a1*t+a2*t*t+a3*t*t*t*t;
    

    现在如何获得a0,a1,a2,a3系数?可以使用任何插值多项式。我最喜欢的是这个(bullet #3 ):
  • Proper implementation of cubic spline interpolation

  • 就是这样(希望我在用a [2 + i]替换pi时没有出现一些愚蠢的索引错误):
    float  d1,d2;
    d1=0.5*(a[4]-a[2]);
    d2=0.5*(a[5]-a[3]);
    a0=a[3];
    a1=d1;
    a2=(3.0*(a[4]-a[3]))-(2.0*d1)-d2;
    a3=d1+d2+(2.0*(-a[4]+a[3]));
    
  • 二维双三次外推

    这只是将问题分为 1D 三次外推集。如果从上方查看#2 的图形,您将看到双三次:

    opencv - 使用双三次插值法填充矩阵的边界-LMLPHP

    因此,首先要计算未知列(可以),然后从中计算缺失的行(反之亦然)。
  • 关于opencv - 使用双三次插值法填充矩阵的边界,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36327520/

    10-09 09:12