图像插值
图像插值是图像处理领域比较热门的话题。其目的在于利用已知邻近像素点的灰度值。预估未知像素点的灰度值。从而把一副低分辨率的图像变成相应高分辨率版本以改善图像的视觉效果。
图像插值算法分类
其中,图像插值算法主要分为两类:
-
线性图像插值方法
常见的有最近邻插值、双线性插值以及双三次插值等等。 -
非线性图像插值方法
线性图像插值方法
最近邻插值法
最近邻插值算法,又称零阶插值。它是一种比较容易实现,且算法复杂度较低的插值算法。其原是取代插值点周围四个相邻像素点中欧式距离最短的一个邻点的灰度值作为该点的灰度值。此算法由于仅用对插值点影响最大的(即最近的)像素的灰度值作为该点的值。
图像实现:
当我们插入一个为点PPP,矩阵Q11,Q21,Q12,Q22Q_{11},Q_{21},Q_{12},Q_{22}Q11,Q21,Q12,Q22可等分切为四块
显而易见,其中点PPP与Q11Q_{11}Q11点的欧式距离最短,此时PPP点的图像灰度值等于Q11Q_{11}Q11点的灰度值
如下图所示,将一幅3∗33*33∗3的图像放大到4∗44*44∗4,用f(x,y)f(x, y)f(x,y)表示目标图像,h(x,y)h(x, y)h(x,y)表示原图像,我们有如下公式:
f(dstX,dstY)=h(dstXsrcWidthdstWidth,dstYsrcHeightdstHeight) \begin{array}{c} f(dst_{X}, dst_{Y}) = h(\frac{dst_{X}src_{Width}} {dst_{Width}}, \frac{dst_{Y}src_{Height}} {dst_{Height}}) \end{array} f(dstX,dstY)=h(dstWidthdstXsrcWidth,dstHeightdstYsrcHeight)
f(0,0)=h(0,0) f(0,0)=h(0,0)f(0,0)=h(0,0)f(0,1)=h(0,0.75)=h(0,1)f(0,1)=h(0,0.75)=h(0,1) f(0,1)=h(0,0.75)=h(0,1)f(0,2)=h(0,1.50)=h(0,2) f(0,2)=h(0,1.50)=h(0,2)f(0,2)=h(0,1.50)=h(0,2)f(0,3)=h(0,2.25)=h(0,2) f(0,3)=h(0,2.25)=h(0,2)f(0,3)=h(0,2.25)=h(0,2)以此类推计算得4∗44*44∗4的图像
最近邻插值缺点
此算法由于仅用考虑最近的像素插值,没有考虑其他相邻像素的影响,因此插值后得到的图像。容易产生块效应,造成图像模糊,放大效果一般不够理想。
双线性插值算法
为了改善最近邻插值算法的不足,提出了一种新的插值方法。即双线性插值算法。双线性插值又称一阶插值。其插值原理是。待插点像素值取原图像中与其相邻的四个像素值的水平、垂直两个方向上的线性内插。即根据待采样点与周围四个邻点的距离。确定相应的权重,从而计算出待采样点的像素值。会产生许多新的像素值,它们主要有插值点周围像素的灰度值通过插值运算获得。
在深度学习模型的upsample上采样模块中,常用的就是BiLinear双线性插值
线性插值
先了解一下基础的线性插值
已知点(x0,y0),(x1,y1)(x_0,y_0),(x_1,y_1)(x0,y0),(x1,y1)求取插值点xxx处的yyy,推导如下:y−y0x−x0=y1−y0x1−x0\frac{y-y_0}{x-x_0}=\frac{y_1-y_0}{x_1-x_0}x−x0y−y0=x1−x0y1−y0
由于xxx值已知,可得:y=y0+(x−x0)y1−y0x1−x0=x1−xx1−x0y0+x−x0x1−x0y1y=y_0+(x-x_0)\frac{y_1-y_0}{x_1-x_0}=\frac{x_1-x}{x_1-x_0}y_0+\frac{x-x_0}{x_1-x_0}y_1y=y0+(x−x0)x1−x0y1−y0=x1−x0x1−xy0+x1−x0x−x0y1
假如已知yyy求xxx也是以上相同的推导过程。
双线性插值
已知Q12,Q22,Q11,Q21Q_{12},Q_{22},Q_{11},Q_{21}Q12,Q22,Q11,Q21四个点的值,求PPP点值。
双线性插值求解过程:
首先在Q11Q21、Q12Q22Q_{11}Q_{21}、Q_{12}Q_{22}Q11Q21、Q12Q22方向上进行两次线性插值,得到R1、R2R_1、R_2R1、R2;然后在R1R2R_1R_2R1R2方向再做一次线性插值,得到PPP点。这就是双线性插值。
假如我们定义一个函数f(x,y)f(x,y)f(x,y),且Q11Q21、Q12Q22Q_{11}Q_{21}、Q_{12}Q_{22}Q11Q21、Q12Q22都在该函数上,此时我们求解PPP点f(x,y)f(x,y)f(x,y)的值呢?
如上述的双线性插值求解:f(R1)=x2−xx2−x1f(Q11)+x−x1x2−x1f(Q11)f(R_1)=\frac{x_2-x}{x_2-x_1}f(Q_{11})+\frac{x-x_1}{x_2-x_1}f(Q_{11})f(R1)=x2−x1x2−xf(Q11)+x2−x1x−x1f(Q11)f(R2)=x2−xx2−x1f(Q12)+x−x1x2−x1f(Q22)f(R_2)=\frac{x_2-x}{x_2-x_1}f(Q_{12})+\frac{x-x_1}{x_2-x_1}f(Q_{22})f(R2)=x2−x1x2−xf(Q12)+x2−x1x−x1f(Q22)f(P)=y2−yy2−y1f(R1)+y−y1y2−y1f(R2)f(P)=\frac{y_2-y}{y_2-y_1}f(R_1)+\frac{y-y_1}{y_2-y_1}f(R_2)f(P)=y2−y1y2−yf(R1)+y2−y1y−y1f(R2)
最后即f(x,y)f(x,y)f(x,y)f(x,y)=f(Q11)(x2−x1)(y2−y1)(x2−x)(y2−y)+f(Q21)(x2−x1)(y2−y1)(x−x1)(y2−y)+f(Q12)(x2−x1)(y2−y1)(x2−x)(y−y1)+f(Q22)(x2−x1)(y2−y1)(x−x1)(y−y1)f(x,y)=\frac{f(Q_{11})}{(x_2-x_1)(y_2-y_1)}(x_2-x)(y_2-y)+\frac{f(Q_{21})}{(x_2-x_1)(y_2-y_1)}(x-x_1)(y_2-y)+\frac{f(Q_{12})}{(x_2-x_1)(y_2-y_1)}(x_2-x)(y-y_1)+\frac{f(Q_{22})}{(x_2-x_1)(y_2-y_1)}(x-x_1)(y-y_1)f(x,y)=(x2−x1)(y2−y1)f(Q11)(x2−x)(y2−y)+(x2−x1)(y2−y1)f(Q21)(x−x1)(y2−y)+(x2−x1)(y2−y1)f(Q12)(x2−x)(y−y1)+(x2−x1)(y2−y1)f(Q22)(x−x1)(y−y1)
双线性插值缺点
经过此算法处理后的图像会产生许多新像素值。他们主要由插值点周围像素的灰度值通过插值运算获得。由于此算法没有考虑相邻点的灰度值变化率的影响。因此具有低通滤波器性质。会使放大后图像的重要细节受到损失。图像变得模糊不清。
向前映射与向后映射
我们知道,通常情况下,一个整数位置(x,y)(x,y)(x,y)经过图像变换后,往往都位于非整数位置。此时就要采用插值技术。此时对于向前映射和向后映射,需要采取不同的策略。
向前映射
可以将几何运算想象成一次一个象素地转移到输出图象中。如果一个输入象素被映射到四个输出象素之间的位置,则其灰度值就按插值算法在4个输出象素之间进行分配,这些分配而来的像素值叠加,就是输出图像整数点位置的像素值称为向前映射法,或象素移交影射。
向前映射中每个输出像素灰度值需要经过多次运算
向后映射
向后映射法(或象素填充算法)是输出象素一次一个地映射回到输入象素中,以便确定其灰度级。如果一个输出象素被映射到4个输入象素之间,则其灰度值插值决定,然后再遍历输出图像,经过坐标变换、插值两步操作,我们就能将其像素值一个个地计算出来,向后空间变换是向前变换的逆
注:从结果图象的坐标计算原图象的坐标
向后映射中每个输出像素灰度值只需要经过一次运算