簡介
在圖像處理中,平移變換、旋轉變換以及放縮變換是一些基礎且常用的操作。這些幾何變換並不改變圖象的象素值,只是在圖象平面上進行象素的重新排列。在一幅輸入圖象中,灰度值僅在整數位置上有定義。然而,輸出圖象[x,y]的灰度值一般由處在非整數座標上的值來決定。這就需要插值算法來進行處理,常見的插值算法有最近鄰插值、雙線性插值和三次樣條插值。
學習目標
- 瞭解插值算法與常見幾何變換之間的關係
- 理解插值算法的原理
- 掌握OpenCV框架下插值算法API的使用
內容介紹
- 插值算法原理介紹
- 最近鄰插值算法
- 雙線性插值算法
- OpenCV代碼實踐
- cv.resize()各項參數及含義
- 動手實現(由讀者自己完成)
算法理論介紹與推薦
最近鄰插值算法原理
最近鄰插值,是指將目標圖像中的點,對應到源圖像中後,找到最相鄰的整數點,作爲插值後的輸出。
如上圖所示,目標圖像中的某點投影到原圖像中的位置爲點P,此時易知,.
一個例子:
如下圖所示,將一幅3X3的圖像放大到4X4,用表示目標圖像,表示原圖像,我們有如下公式:
缺點: 用該方法作放大處理時,在圖象中可能出現明顯的塊狀效應
雙線性插值
在講雙線性插值之前先看以一下線性插值,線性插值多項式爲:
雙線性插值就是線性插值在二維時的推廣,在兩個方向上做三次線性插值,具體操作如下圖所示:
令爲兩個變量的函數,其在單位正方形頂點的值已知。假設我們希望通過插值得到正方形內任意點的函數值。則可由雙線性方程:
來定義的一個雙曲拋物面與四個已知點擬合。
首先對上端的兩個頂點進行線性插值得:
類似地,再對底端的兩個頂點進行線性插值有:
最後,做垂直方向的線性插值,以確定:
整理得:
映射方法
向前映射法
可以將幾何運算想象成一次一個象素地轉移到輸出圖象中。如果一個輸入象素被映射到四個輸出象素之間的位置,則其灰度值就按插值算法在4個輸出象素之間進行分配。稱爲向前映射法,或象素移交影射。
注:從原圖象座標計算出目標圖象座標鏡像、平移變換使用這種計算方法
向後映射法
向後映射法(或象素填充算法)是輸出象素一次一個地映射回到輸入象素中,以便確定其灰度級。如果一個輸出象素被映射到4個輸入象素之間,則其灰度值插值決定,向後空間變換是向前變換的逆。
注:從結果圖象的座標計算原圖象的座標
- 旋轉、拉伸、放縮可以使用
- 解決了漏點的問題,出現了馬賽克
基於OpenCV的實現(Python)
函數原型:
cv2.resize(src, dsize[, dst[, fx[, fy[, interpolation]]]])
參數:
參數 | 描述 |
---|---|
src | 【必需】原圖像 |
dsize | 【必需】輸出圖像所需大小 |
fx | 【可選】沿水平軸的比例因子 |
fy | 【可選】沿垂直軸的比例因子 |
interpolation | 【可選】插值方式 |
src | 【必需】原圖像 |
插值方式:
cv.INTER_NEAREST | 最近鄰插值 |
cv.INTER_LINEAR | 雙線性插值 |
cv.INTER_CUBIC | 基於4x4像素鄰域的3次插值法 |
cv.INTER_AREA | 基於局部像素的重採樣 |
通常,縮小使用cv.INTER_AREA,放縮使用cv.INTER_CUBIC(較慢)和cv.INTER_LINEAR(較快效果也不錯)。默認情況下,所有的放縮都使用cv.INTER_LINEAR。
代碼實踐:
import cv2
img = cv2.imread('./erkang.jpg', cv2.IMREAD_UNCHANGED)
print('Original Dimensions : ',img.shape)
scale_percent = 30 # percent of original size
width = int(img.shape[1] * scale_percent / 100)
height = int(img.shape[0] * scale_percent / 100)
dim = (width, height)
# resize image
resized = cv2.resize(img, dim, interpolation = cv2.INTER_LINEAR)
fx = 1.5
fy = 1.5
resized1 = cv2.resize(resized, dsize=None, fx=fx, fy=fy, interpolation = cv2.INTER_NEAREST)
resized2 = cv2.resize(resized, dsize=None, fx=fx, fy=fy, interpolation = cv2.INTER_LINEAR)
print('Resized Dimensions : ',resized.shape)
cv2.imshow("Resized image", resized)
cv2.imshow("INTER_NEAREST image", resized1)
cv2.imshow("INTER_LINEAR image", resized2)
cv2.waitKey(0)
cv2.destroyAllWindows()
Original Dimensions : (360, 640, 3)
Resized Dimensions : (108, 192, 3)
0.3倍縮小,雙線性插值
1.5倍放大,最近鄰插值
1.5倍放大,雙線性插值
推薦書籍:學習OpenCV中文版
推薦博客:https://blog.csdn.net/hongbin_xu/category_6936122.html
總結
插值算法是很多幾何變換的基礎和前置條件,對插值算法細節的掌握有助於對其他算法的理解,爲自己的學習打下堅實的基礎。
關於Datawhale:
Datawhale是一個專注於數據科學與AI領域的開源組織,彙集了衆多領域院校和知名企業的優秀學習者,聚合了一羣有開源精神和探索精神的團隊成員。Datawhale以“for the learner,和學習者一起成長”爲願景,鼓勵真實地展現自我、開放包容、互信互助、敢於試錯和勇於擔當。同時Datawhale 用開源的理念去探索開源內容、開源學習和開源方案,賦能人才培養,助力人才成長,建立起人與人,人與知識,人與企業和人與未來的聯結。