圖像插值算法¶
概述¶
在圖像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平移、旋轉、縮放、翻轉-之實踐
博客里提到了各種插值算法的運算速度與選擇。
?