双线性图像插值/缩放 - 计算示例

Puc*_*acz 10 interpolation image image-processing linear-interpolation image-scaling

我想问你一些双线性插值/缩放细节.我们假设我们有这个矩阵:

|100 | 50 |
|70  | 20 |
Run Code Online (Sandbox Code Playgroud)

这是一个2 x 2灰度图像.现在,我想将它缩放两倍,我的矩阵看起来像这样:

| 100   | f1 | 50 | f2 |
| f3    | f4 | f5 | f6 |
| 70    | f7 | 20 | f8 |
Run Code Online (Sandbox Code Playgroud)

所以如果我们想计算f4,计算定义为

f1 = 100 + 0.5(50 - 100) = 75
f7 = 70 +  0.5(20 - 70) = 45
Run Code Online (Sandbox Code Playgroud)

现在终于:

f4 = 75 + 0.5(45 - 75) = 60
Run Code Online (Sandbox Code Playgroud)

但是,我无法真正理解f3f1适合的计算

我们是否分别在每个方向进行双线性缩放?因此,这意味着:

f3 = 100 + 0.5(70 - 100) = 85
f1 = 100 + 0.5(50 - 100) = 75
Run Code Online (Sandbox Code Playgroud)

另外,我应该如何对待f2,f6,f8.这些点是否像最近邻算法一样被复制?

ray*_*ica 33

我想向您指出维基百科中这个非常有见地的图形,它说明了如何对一点进行双线性插值:

资料来源:维基百科

如您所见,这四个红点是众所周知的.这些你事先知道P的点是我们想要插入的点.因此,我们必须做两个步骤(正如您在帖子中指出的那样).要处理x坐标(水平),我们必须计算内插值对于红点的顶行和红点的底行的行.这导致两个蓝点R1R2.为了处理y坐标(垂直),我们使用两个蓝点并垂直插值以获得最终P点.

当您调整图像大小时,即使我们没有在视觉上看到我要说的内容,但想象这个图像是3D信号 f.矩阵中的每个点实际上是3D坐标,其中列位置是x值,行位置是y值,z值是矩阵本身的数量/灰度值.因此,do z = f(x,y)是矩阵中位置(x,y)处的矩阵的值.在我们的例子中,因为你正在处理图像,所以每个值(x,y)都是整数,从1到最多行/列,取决于你正在查看的维度.

因此,给定您想要插入的坐标(x,y),并给出上图中的红色坐标,我们x1,y1,x2,y2根据图表调用它们- 特别是遵循图的约定并参考图像的访问方式:x1 = 1, x2 = 2, y1 = 2, y2 = 1,蓝色坐标R1R2通过1D插值列使用相同的行计算两个点重合:

R1 = f(x1,y1) + (x - x1)/(x2 - x1)*(f(x2,y1) - f(x1,y1))
R2 = f(x1,y2) + (x - x1)/(x2 - x1)*(f(x2,y2) - f(x1,y2))
Run Code Online (Sandbox Code Playgroud)

需要注意的是很重要的(x - x1) / (x2 - x1)重量/比例如何混合的多输出包括在看到这两个值之间f(x1,y1)f(x2,y1)用于R1f(x1,y2)f(x2,y2)R2.具体来说,x1是起点,(x2 - x1)x值的差异.您可以验证代x1作为x给我们0,而x2作为x为我们提供了1这个重量之间波动,[0,1]这为计算工作是必需的.

应该注意的是,图像的原点位于左上角,左上角也是如此(1,1).一旦找到R1并且R2,我们可以P通过行插入来找到:

P = R2 + (y - y2)/(y2 - y1)*(R1 - R2)
Run Code Online (Sandbox Code Playgroud)

再次,(y - y2) / (y2 - y1)表示多少的比例/组合R1以及R2对最终输出的贡献P.因此,您f5正确计算,因为您使用了四个已知点:左上角是100,右上角是50,左下角是70,右下角是20.具体来说,如果你想计算f5,这意味着(x,y) = (1.5,1.5)因为我们正在中途因为您将图像缩放了两个,所以在100到50之间.如果将这些值插入上述计算中,您将获得预期的值60.两个计算的权重也将导致0.5,这是您在计算中得到的,这就是我们所期望的.

如果你计算f1,这对应于(x,y) = (1.5,1)并且如果你将它代入上面的等式,你会看到它(y - y2)/(y2 - y1)给你0或权重是0,所以计算的只是R2,对应于仅沿顶行的线性插值.同样,如果我们计算f7,这意味着我们想要插值(x,y) = (1.5,2).在这种情况下,您将看到(y - y2) / (y2 - y1)为1或权重为1,因此P = R2 + (R1 - R2),这简化为R1仅沿底行的线性插值.

现在有f3和的情况f5.这两者分别对应于(x,y) = (1,1.5)(x,y) = (2,1.5).在这些值代R1R2P这两种情况下给予:

f3

R1 = f(1,2) + (1 - 1)/(2 - 1)*(f(2,2) - f(1,2)) = f(1,2)
R2 = f(1,1) + (1 - 1)/(2 - 1)*(f(1,2) - f(1,1)) = f(1,1)
P = R1 + (1.5 - 1)*(R1 - R2) = f(1,2) + 0.5*(f(1,2) - f(1,1))

P = 70 + 0.5*(100 - 70) = 85
Run Code Online (Sandbox Code Playgroud)

f5

R1 = f(1,2) + (2 - 1)/(2 - 1)*(f(2,2) - f(1,2)) = f(2,2)
R2 = f(1,1) + (2 - 1)/(2 - 1)*(f(1,2) - f(1,1)) = f(1,2)
P = R1 + (1.5 - 1)*(R1 - R2) = f(2,2) + 0.5*(f(2,2) - f(1,2))

P = 20 + 0.5*(50 - 20) = 35
Run Code Online (Sandbox Code Playgroud)

那告诉我们什么呢?这意味着您仅沿y方向进行插值.当我们看一看时,这是显而易见的P.更彻底的检查计算P为每个f3f5,你看,我们正在考虑只沿着垂直方向的值.

因此,如果您想要一个明确的答案,f1并且只能沿着/ column方向沿同一行f7进行插值x. f3f5通过y沿同一列插值/行方向找到. f4使用的混合物f1,并f7以计算最终值,你已经看到了.


要回答你的最后一个问题,f2,f6f8填充在根据个人喜好.这些值被认为是超出范围的,其中xy值都在2.5我们的[1,2]网格之外(x,y).在MATLAB中,默认实现是将定义的边界之外的任何值填充为非数字(NaN),但有时,人们使用线性插值进行外推,复制边界值,或执行一些精细的填充,如对称或圆形填充物.这取决于你所处的情况,但是没有关于如何填写的正确和明确的答案f2,f6而且f8- 这一切都取决于你的应用程序以及对你来说最有意义的东西.


作为奖励,我们可以在MATLAB中验证我的计算是否正确.我们首先定义范围内的(x,y)点网格[1,2],然后调整图像的大小,使其大两倍,我们指定每点0.5的分辨率而不是1.我将调用您定义的矩阵A:

A = [100 50; 70 20]; %// Define original matrix
[X,Y] = meshgrid(1:2,1:2); %// Define original grid of points
[X2,Y2] = meshgrid(1:0.5:2.5,1:0.5:2.5) %// Define expanded grid of points
B = interp2(X,Y,A,X2,Y2,'linear'); %// Perform bilinear interpolation
Run Code Online (Sandbox Code Playgroud)

(x,y)点的原始网格看起来像:

>> X

X =

     1     2
     1     2

>> Y

Y =

     1     1
     2     2
Run Code Online (Sandbox Code Playgroud)

扩展网格将矩阵的大小扩展两倍,如下所示:

>> X2

X2 =

    1.0000    1.5000    2.0000    2.5000
    1.0000    1.5000    2.0000    2.5000
    1.0000    1.5000    2.0000    2.5000
    1.0000    1.5000    2.0000    2.5000

>> Y2

Y2 =

    1.0000    1.0000    1.0000    1.0000
    1.5000    1.5000    1.5000    1.5000
    2.0000    2.0000    2.0000    2.0000
    2.5000    2.5000    2.5000    2.5000
Run Code Online (Sandbox Code Playgroud)

B是使用XY作为原始网格点的输出,X2并且Y2是我们想要插入的点.

我们得到:

>> B

B =

   100    75    50   NaN
    85    60    35   NaN
    70    45    20   NaN
   NaN   NaN   NaN   NaN
Run Code Online (Sandbox Code Playgroud)

  • Aaah其中一个答案值得+10票! (3认同)