图像插值算法¶
概述¶
在图像2D仿射变换一章里, 我们介绍了resize中有若干个插值算法,本节, 阿凯将讲解各种插值算法的实现过程。
keywords 2D仿射变换 插值算法
何为插值?¶
一个图片从4×4 放大到8*8的时候, 就会产生一些新的像素点( 如下图红点所示),
如何给这些值赋值, 就是interpolation
插值所要解决的问题。
插值方法一览¶
全部的插值方式 请见文档 InterpolationFlags
这里我们只讲解五个插值方式。 我们随机生成一个5×5的矩阵, 然后用下面五种方式进行插值, 效果如图所示:
interpolation_algorithm_v1.py
import cv2 import numpy as np from matplotlib import pyplot as plt img = np.uint8(np.random.randint(0,255,size=(5,5))) height,width= img.shape # 声明新的维度 new_dimension = (25, 25) plt.subplot(231) plt.title("SRC Image") plt.imshow(img,cmap='gray') plt.subplot(232) resized = cv2.resize(img, new_dimension, interpolation = cv2.INTER_NEAREST) plt.title("INTER_NEAREST") plt.imshow(resized,cmap='gray') plt.subplot(233) resized = cv2.resize(img, new_dimension, interpolation = cv2.INTER_LINEAR) plt.title("INTER_LINEAR") plt.imshow(resized,cmap='gray') plt.subplot(234) resized = cv2.resize(img, new_dimension, interpolation = cv2.INTER_AREA) plt.title("INTER_AREA") plt.imshow(resized,cmap='gray') plt.subplot(235) resized = cv2.resize(img, new_dimension, interpolation = cv2.INTER_CUBIC) plt.title("INTER_CUBIC") plt.imshow(resized,cmap='gray') plt.subplot(236) resized = cv2.resize(img, new_dimension, interpolation = cv2.INTER_LANCZOS4) plt.title("INTER_LANCZOS4") plt.imshow(resized,cmap='gray') plt.show()
为了更加直观的观察,我们将cmap
换为seismic
分辨率 从5*5 放大到1000*1000
interpolation_algorithm_v2.py
import cv2 import numpy as np from matplotlib import pyplot as plt img = np.uint8(np.random.randint(0,255,size=(5,5))) height,width= img.shape # 声明新的维度 new_dimension = (1000, 1000) plt.subplot(231) plt.title("SRC Image") plt.imshow(img,cmap='seismic') plt.subplot(232) resized = cv2.resize(img, new_dimension, interpolation = cv2.INTER_NEAREST) plt.title("INTER_NEAREST") plt.imshow(resized,cmap='seismic') plt.subplot(233) resized = cv2.resize(img, new_dimension, interpolation = cv2.INTER_LINEAR) plt.title("INTER_LINEAR") plt.imshow(resized,cmap='seismic') plt.subplot(234) resized = cv2.resize(img, new_dimension, interpolation = cv2.INTER_AREA) plt.title("INTER_AREA") plt.imshow(resized,cmap='seismic') plt.subplot(235) resized = cv2.resize(img, new_dimension, interpolation = cv2.INTER_CUBIC) plt.title("INTER_CUBIC") plt.imshow(resized,cmap='seismic') plt.subplot(236) resized = cv2.resize(img, new_dimension, interpolation = cv2.INTER_LANCZOS4) plt.title("INTER_LANCZOS4") plt.imshow(resized,cmap='seismic') plt.show()
关于插值方式的不同与缩放因子的不同对应的时间消耗, 可以查阅下表:
最近邻插值 INTER_NEAREST¶
最近邻插值法, 找到与之距离最相近的邻居(原来就存在的像素点, 黑点), 赋值与其相同。
问题 如果距离四个点都相等(中心处)要如何处理?
效果展示
线性插值(默认)INTER_LINEAR¶
这里的线形插值INTER_LINEAR
其实是Bi-Linear Interpolation
我们先来看一个简单的一维线形插值的例子。
已知两点(红色) ,在给出一个蓝点的x坐标, 求y。
所以需要根据两个红点确定一条直线,求出直线的表达式, 然后再将x坐标带进去。
接下来我们来看Bi-Linear Interpolation
的例子。
下图中 P 点(x,y)周围有
四个点.
又假定我们已知函数
在四个点的取值, 现在需要我们求
思路是我们可以将求解过程分解为两次插值过程。
首先在x轴方向上进行插值,根据点
的取值求得
, 根据点
的取值求得
.
然后在y轴方向上进行插值, 根据点
的取值求得f(P).
**这本质上就是加权平均。以x点到
的距离作为权值,来表示该点受周边两点的影响。**
展开后得到
不知道你有没有发现, 实际上P点的值, 等于周边四点值根据与P点形成的对角矩形面积的加权平均。
效果展示
区域插值 INTER_AREA¶
三次样条插值 INTER_CUBIC¶
由相邻的4*4像素计算得出,公式类似于双线性.
Lanczos插值 INTER_LANCZOS4¶
兰索斯插值:由相邻的8*8像素计算得出,公式类似于双线性
Reference¶
02 sampling quantization interpolation
插值部分讲解的原理图片,主要来自与此课件
Neighborhood Operations - ENDS489 Course Notes - Fall 2000 Section 1-8
三次样条插值(Cubic Spline Interpolation)及代码实现(C语言)
Comparison of OpenCV Interpolation Algorithms
插值算法性能对比来自于此文章
小强学Python+OpenCV之-1.4.1平移、旋转、缩放、翻转-之实践
博客里提到了各种插值算法的运算速度与选择。