Datawhale学习
作者:姚童,Datawhale优秀学习者
寄语:本文梳理了最近邻插值法、双线性插值法和三次样条插值法的原理,并以图像缩放为例,对原理进行了C++及Python实现。
在图像处理中,几何变换是将一幅图像映射到另外一幅图像内的操作,可以大概分为放缩、翻转、仿射(平移、旋转)、透视、重映射几部分。
在几何变换时,无法给有些像素点直接赋值,例如,将图像放大两倍,必然会多出一些无法被直接映射的像素点,对于这些像素点,通过插值决定它们的值。且不同插值方式的结果不同。
在一幅输入图像[u,v]中,灰度值仅在整数位置上有定义。然而,输出图像的坐标映射回原图像后,一般为非整数的坐标。所以输出图像[x,y]的灰度值,一般由非整数坐标来决定,非整数坐标的像素值,就需要插值算法来进行处理。常见的插值算法有最近邻插值、双线性插值和三次样条插值。
本文目标
了解插值算法与常见几何变换之间的关系
理解插值算法的原理
掌握OpenCV框架下插值算法API的使用
插值算法原理介绍
近邻插值算法
1. 原理简介
将目标图像中的点,对应到原图像中后,找到最相邻的整数坐标点的像素值,作为该点的像素值输出。
如上图所示,目标图像中的某点投影到原图像中的位置为点P,与P距离最近的点为Q11,此时易知,f(P)=f(Q11)。
2. 例子说明
如图所示:
将一幅3*3图像放大到4*4,用f(x , y)表示原图像,h(x ,y)表示目标图像,我们有如下公式:
3. 缺点
由最邻近插值法,放大后的图像有很严重的马赛克,会出现明显的块状效应;缩小后的图像有很严重的失真。
这是一种最基本、最简单的图像缩放方式。变换后的每个像素点的像素值,只由原图像中的一个像素点确定。例如上面,点(0,0.75)的像素只由(0,1)确定,这样的效果显然不好。点(0,0.75)的像素不止和(0,1)有关,和(0,0)也有关,只是(0,1)的影响更大。如果可以用附近的几个像素点按权重分配,共同确定目标图像某点的像素,效果会更好。下面的双线性插值就解决了这个问题。
双线性插值算法
1. 线性插值
在讲双线性插值之前先了解一下线性插值。线性插值:使用连接两个已知量的直线来确定在这两个已知量之间的一个未知量的值。线性插值形式:
如下图所示:
线性插值多项式:
其实,即使x不在x0到x1之间,这个公式也是成立的。在这种情况下,这种方法叫作线性外插。
线性插值的误差:线性插值其实就是拉格朗日插值有2个结点时的情况。插值余项为:
从插值余项可以看出,随着二阶导数的增大,线性插值的误差增大。即函数的曲率越大,线性插值近似的误差也越大。
举个例子。下图中,左边为原图像,拉伸后,理想的输出图像的像素分布应该为绿色箭头指向的,但是按照线性插值,会得到红色箭头指向的结果。