Task 1 opencv框架与图像插值算法

opencv的线性插值和halcon的哪个快 opencv图像插值_双线性插值


1.最邻近插值算法:

不需要计算,在待求象素的四邻象素中,将距离待求象素最近的邻象素灰度赋给待求象素设i+u, j+v(i, j为正整数, u, v为大于零小于1的小数,下同)为待求象素坐标,则待求象素灰度的值 f(i+u, j+v)。

公式:srcX=dstX* (srcWidth/dstWidth) , srcY = dstY * (srcHeight/dstHeight)

dst是目标坐标,src是原图坐标

代码实现:

import cv2
if __name__ == "__main__":	   
    img = cv2.imread('D:/image/yuner.jpg', cv2.IMREAD_UNCHANGED)
    scale_percent = 30 
    width = int(img.shape[1] * scale_percent / 100)
    height = int(img.shape[0] * scale_percent / 100)
    dim = (width, height)
    resized = cv2.resize(img, dim, interpolation = cv2.INTER_LINEAR)
    fx = 1.5
    fy = 1.5
    resized1 = cv2.resize(resized, dsize=None, fx=fx, fy=fy, interpolation = cv2.INTER_NEAREST)
    cv2.imshow("INTER_NEAREST image", resized1)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

opencv的线性插值和halcon的哪个快 opencv图像插值_插值_02


2.双线性插值法

opencv的线性插值和halcon的哪个快 opencv图像插值_双线性插值_03


假设源图像大小为mxn,目标图像为axb。那么两幅图像的边长比分别为:m/a和n/b。注意,通常这个比例不是整数,编程存储的时候要用浮点型。目标图像的第(i,j)个像素点(i行j列)可以通过边长比对应回源图像。其对应坐标为(im/a,jn/b)。显然,这个对应坐标一般来说不是整数,而非整数的坐标是无法在图像这种离散数据上使用的。双线性插值通过寻找距离这个对应坐标最近的四个像素点,来计算该点的值(灰度值或者RGB值)。 若图像为灰度图像,那么(i,j)点的灰度值的数学计算模型是:f(x,y)=b1+b2x+b3y+b4xy其中b1,b2,b3,b4是相关的系数。关于其的计算过程如下如下: 如图,已知Q12,Q22,Q11,Q21,但是要插值的点为P点,这就要用双线性插值了,首先在x轴方向上,对R1和R2两个点进行插值,这个很简单,然后根据R1和R2对P点进行插值,这就是所谓的双线性插值。

双线性插值,又称为双线性内插。在数学上,双线性插值是有两个变量的插值函数的线性插值扩展,其核心思想是在两个方向分别进行一次线性插值。假如我们想得到未知函数 在点 的值,假设我们已知函数 f 在 Q11=(x1,y1),Q12=(x1,y2) ,Q21=(x2,y1) ,Q22=(x2,y2) 及 四个点的值。首先在 x 方向进行线性插值,得到

opencv的线性插值和halcon的哪个快 opencv图像插值_线性插值_04


opencv的线性插值和halcon的哪个快 opencv图像插值_线性插值_05


然后在 y 方向进行线性插值,得到

opencv的线性插值和halcon的哪个快 opencv图像插值_插值_06


这样就得到所要的结果f(x,y),

opencv的线性插值和halcon的哪个快 opencv图像插值_深度学习_07


opencv的线性插值和halcon的哪个快 opencv图像插值_插值_08


这种插值方法的结果通常不是线性的,线性插值的结果与插值的顺序无关。首先进行 y 方向的插值,然后进行 x 方向的插值,所得到的结果是一样的。

代码实现:

resized2 = cv2.resize(resized, dsize=None, fx=fx, fy=fy, interpolation = cv2.INTER_LINEAR)
cv2.imshow("INTER_LINEAR image", resized2)
cv2.waitKey(0)
cv2.destroyAllWindows()

opencv的线性插值和halcon的哪个快 opencv图像插值_深度学习_09


向前映射法:

输入图像上整数点坐标映射到输出图像之后,变成了非整数点坐标。因此,需要将其像素值按一定权重分配到其周围四个像素点上。对于输出图像而言,其整数点像素值周围会有很多输入图像像素映射过来,每个到其周围的非整数点像素值都会分配一定的灰度值到它上面,将这些分配而来的像素值叠加,就是输出图像整数点位置的像素值。由于这个分配、叠加的特性,向前映射法有时也叫像素移交映射。

下图为向前映射的示意图。

opencv的线性插值和halcon的哪个快 opencv图像插值_线性插值_10


因此,对于向前映射而言,输出图像某一点的像素值不能直接得到,需要遍历输入图像的所有像素值,对其进行坐标变换,分配像素值到整数位置,才能得到输出图像各像素点的像素值。这是向前映射法的缺点。

向后映射:

相比之下,向后映射法就比较直观。在这种情况下,我们知道输出图像上整数点位置(x’,y’)在变换前位于输入图像上的位置(x,y),一般来说这是个非整数点位置,利用其周围整数点位置的输入图像像素值进行插值,就得到了该点的像素值。我们遍历输出图像,经过坐标变换、插值两步操作,我们就能将其像素值一个个地计算出来,因此向后映射又叫图像填充映射。如下图所示。

opencv的线性插值和halcon的哪个快 opencv图像插值_插值_11


插值算法我们采用双线性插值,如下图所示

opencv的线性插值和halcon的哪个快 opencv图像插值_深度学习_12


这次我们先看向后插值。这种情况下输出图像上某点的像素值I’(x’,y’)映射到f(x,y),而f(x,y)由输入图像上四点像素值叠加而成 。

总结:向后映射比较直观,计算量也小,我们经常使用的图像变换都是采用向后映射的方法来处理。但向后映射需要知道变换的反变换公式,在上面旋转变换的情况,反变换很容易求出来。但在有些变换比较复杂的场合,这个反变换是很难得到的。此时就需要采用前向映射的方法进行变换了。从实验结果看,向前映射得到的结果与向后映射是一样的。