插值方法
在图像处理和计算机图形学中,插值(Interpolation)是一种通过已知数据点之间的推断或估计来获取 新数据点的方法。它在图像处理中常用于处理图像的放大、缩小、旋转、变形等操作,以及处理图像中 的像素值。
图像插值算法是为了解决图像缩放或者旋转等操作时,由于像素之间的间隔不一致而导致的信息丢失和 图像质量下降的问题。当我们对图像进行缩放或旋转等操作时,需要在新的像素位置上计算出对应的像 素值,而插值算法的作用就是根据已知的像素值来推测未知位置的像素值。
一、最近邻插值
其中,dstX表示目标图像中某点的x坐标,srcWidth表示原图的宽度,dstWidth表示目标图像的宽度; dstY表示目标图像中某点的y坐标,srcHeight表示原图的高度,dstHeight表示目标图像的高度。而srcX 和srcY则表示目标图像中的某点对应的原图中的点的x和y的坐标。
通俗的讲,该公式就是让目标图像中 的每个像素值都能找到对应的原图中的像素值,这样才能根据不同的插值方法来获取新的像素值。
根据该公式,我们就可以得到每一个目标点所对应的原图像的点。
那么根据公式我们就可以计算出放大后的图像(0,0)点对应的原图像中的坐标为:
也就是原图中的(0,0)点,而最近邻插值的原则是:目标像素点的像素值与经过该公式计算出来的对 应的像素点的像素值相同,如出现小数部分需要进行取整。那么放大后图像的(0,0)坐标处的像素值 就是原图像中(0,0)坐标处的像素值,也就是10。
也就是原图中的(0.5,0)点,因此需要对计算出来的坐标值进行取整,取整后的结果为(0,0),也 就是说放大后的图像中的(1,0)坐标处对应的像素值就是原图中(0,0)坐标处的像素值,其他像素 点计算规则与此相同。
二、双线性插值
双线性插值算法是一种比较好的图像缩放算法,它充分的利用了原图中虚拟点四周的四个真实存在像素 点的值来共同决定目标图中的一个像素点的值,因此缩放效果比简单的最邻近插值要好很多,缩放后图 像质量高,不会出现值不连续的情况。
然后根据Q11、Q21得到R1的插值,根据Q12、Q22得到R2的插值,然后根据R1、R2得到P的插值即 可,这就是双线性插值。
这样就得到了P点的插值。注意此处如果先在y方向插值、再在x方向插值,其结果与按照上述顺序双线 性插值的结果是一样的。
双线性插值的对应关系看似比较清晰,但还是有2个问题。首先是根据坐标系的不同,产生的结果不同, 这张图是左上角为坐标系原点的情况,我们可以发现最左边x=0的点都会有概率直接复制到目标图像中 (至少原点肯定是这样),而且就算不和原图像中的点重合,也相当于进行了1次单线性插值(带入到权 重公式中会发现结果)。
下面这张图是右上角为坐标系原点的情况,我们可以发现最右面的点都会有概率直接复制到目标图像中 (至少原点肯定是这样),而且就算不和原图像中的点重合,也相当于进行了1次单线性插值。那么当我 们采用不同的坐标系时产生的结果是不一样的,而且无论我们采用什么坐标系,最左侧和最右侧(最上 侧和最下侧)的点是“不公平的”,这是第一个问题。
第二个问题时整体的图像相对位置会发生变化。如下图所示,左侧是原图像(3,3),右侧是目标图像(5, 5),原图像的几何中心点是(1,1),目标图像的几何中心点是(2,2),根据对应关系,目标图像的几何中心 点对应的原图像的位置是(1.2,1.2),那么问题来了,目标图像的原点(0,0)和原始图像的原点是重合的, 但是目标图像的几何中心点相对于原始图像的几何中心点偏右下,那么整体图像的位置会发生偏移,所 以参与计算的点相对都往右下偏移会产生相对的位置信息损失。这是第二个问题。
三、像素区域插值
像素区域插值主要分两种情况,缩小图像和放大图像的工作原理并不相同。
当使用像素区域插值方法进行缩小图像时,它就会变成一个均值滤波器(滤波器其实就是一个核,这里 只做简单了解,后面实验中会介绍),其工作原理可以理解为对一个区域内的像素值取平均值。
当使用像素区域插值方法进行放大图像时,如果图像放大的比例是整数倍,那么其工作原理与最近邻插 值类似;如果放大的比例不是整数倍,那么就会调用双线性插值进行放大。
四、双三次插值
与双线性插值法相同,该方法也是通过映射,在映射点的邻域内通过加权来得到放大图像中的像素值。 不同的是,双三次插值法需要原图像中近邻的16个点来加权。
假设原图像A大小为m*n,缩放后的目标图像B的大小为M*N。其中A的每一个像素 点是已知的,B是未知的,我们想要求出目标图像B中每一个像素点(X,Y)的值,必须先找出像素 (X,Y)在原图像A中对应的像素(x,y),再根据原图像A距离像素(x,y)最近的16个像素点作为计算目 标图像B(X,Y)处像素值的参数,利用BiCubic基函数求出16个像素点的权重,图B像素(x,y)的值就等 于16个像素点的加权叠加。
将上面的16个点的坐标带入函数中,获取16像素所对应的权重W(x)。然而BiCubic函 数是一维的,所以我们需要将像素点的行与列分开计算,比如a00这个点,我们需要将x=0带入BiCubic 函数中,计算a00点对于P点的x方向的权重,然后将y=0带入BiCubic函数中,计算a00点对于P点的y方 向的权重,其他像素点也是这样的计算过程。
五、Lanczos插值
Lanczos插值方法与双三次插值的思想是一样的,不同的就是其需要的原图像周围的像素点的范围变成 了8*8,并且不再使用BiCubic函数来计算权重,而是换了一个公式计算权重。
假设原图像A大小为m*n,缩放后的目标图像B的大小为M*N。其中A的每一个像素 点是已知的,B是未知的,我们想要求出目标图像B中每一个像素点(X,Y)的值,必须先找出像素 (X,Y)在原图像A中对应的像素(x,y),再根据原图像A距离像素(x,y)最近的64个像素点作为计算目 标图像B(X,Y)处像素值的参数,利用权重函数求出64个像素点的权重,图B像素(x,y)的值就等于64 个像素点的加权叠加。
假如下图中的P点就是目标图像B在(X,Y)处根据上述公式计算出的对应于原图像A中的位置,P的坐标 位置会出现小数部分,所以我们假设P点的坐标为(x+u,y+v),其中x、y表示整数部分,u、v表示小数 部分,那么我们就可以得到其周围的最近的64个像素的位置。
与双三次插值一样,也需要将像素点分行和列分别带入计算权重值,其他像素点也是这样的计算过 程。
最近邻插值的计算速度最快,但是可能会导致图像出现锯齿状边缘和失真,效果较差。双线性插值的计 算速度慢一点,但效果有了大幅度的提高,适用于大多数场景。
双三次插值、Lanczos插值的计算速度 都很慢,但是效果都很好。
在OpenCV中,关于插值方法默认选择的都是双线性插值,且一般情况下双线性插值已经能满足大部分 需求。