opencv 圖像變換原理詳解 圖像平移 圖像旋轉 圖像縮放


常見的2D圖像變換從原理上講主要包括基於2×3矩陣的仿射變換和基於3×3矩陣透視變換。

仿射變換

原理

基本的圖像變換就是二維坐標的變換:從一種二維坐標(x,y)到另一種二維坐標(u,v)的線性變換:
圖像仿射變換公式
如果寫成矩陣的形式,就是:
仿射變換矩陣表示
作如下定義:
仿射變換矩陣表示各部分描述
矩陣T(2×3)就稱為仿射變換的變換矩陣,R為線性變換矩陣,t為平移矩陣,簡單來說,仿射變換就是線性變換+平移。變換后直線依然是直線,平行線依然是平行線,直線間的相對位置關系不變,因此非共線的三個對應點便可確定唯一的一個仿射變換,線性變換4個自由度+平移2個自由度→仿射變換自由度為6。

opencv中實現仿射變換

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt

img = cv.imread('drawing.jpg')
rows, cols = img.shape[:2]

# 變換前的三個點
pts1 = np.float32([[50, 65], [150, 65], [210, 210]])
# 變換后的三個點
pts2 = np.float32([[50, 100], [150, 65], [100, 250]])

# 生成變換矩陣
M = cv.getAffineTransform(pts1, pts2)
# 第三個參數為dst的大小
dst = cv.warpAffine(img, M, (cols, rows))

plt.subplot(121), plt.imshow(img), plt.title('input')
plt.subplot(122), plt.imshow(dst), plt.title('output')
plt.show()

實驗結果

仿射變換前后對比圖

應用opencv中現成的圖像平移、旋轉、縮放、翻轉

請參考 opencv實現圖像幾何變換

平移

圖解平移
平移就是x和y方向上的直接移動,可以上下/左右移動,自由度為2,變換矩陣可以表示為:
平移變換矩陣表示

旋轉

圖解旋轉
旋轉是坐標軸方向饒原點旋轉一定的角度θ,自由度為1,不包含平移,如順時針旋轉可以表示為:
旋轉變換矩陣表示

翻轉

翻轉是x或y某個方向或全部方向上取反,自由度為2,比如這里以垂直翻轉為例:
垂直翻轉變換矩陣表示

剛體變換

旋轉+平移也稱剛體變換(Rigid Transform),就是說如果圖像變換前后兩點間的距離仍然保持不變,那么這種變化就稱為剛體變換。剛體變換包括了平移、旋轉和翻轉,自由度為3。由於只是旋轉和平移,剛體變換保持了直線間的長度不變,所以也稱歐式變換(變化前后保持歐氏距離)。變換矩陣可以表示為:
剛體變換矩陣表示

縮放

圖解縮放縮放是x和y方向的尺度(倍數)變換,在有些資料上非等比例的縮放也稱為拉伸/擠壓,等比例縮放自由度為1,非等比例縮放自由度為2,矩陣可以表示為:
縮放變換矩陣表示

相似變換

相似變換又稱縮放旋轉,相似變換包含了旋轉、等比例縮放和平移等變換,自由度為4。在OpenCV中,旋轉就是用相似變換實現的:
若縮放比例為scale,旋轉角度為θ,旋轉中心是(centerx,centery),則仿射變換可以表示為:
相似變換矩陣表示
其中:
上述公式中的α和β計算公式
相似變換相比剛體變換加了縮放,所以並不會保持歐氏距離不變,但直線間的夾角依然不變。

透視變換

前面仿射變換后依然是平行四邊形,並不能做到任意的變換。
各種透視變換

原理

透視變換(Perspective Transformation)是將二維的圖片投影到一個三維視平面上,然后再轉換到二維坐標下,所以也稱為投影映射(Projective Mapping)。簡單來說就是二維→三維→二維的一個過程。
透視變換公式:
透視變換公式
透視變換矩陣表示:
透視變換矩陣表示
仿射變換是透視變換的子集。接下來再通過除以Z軸轉換成二維坐標:
透視變換中的三維->二維
透視變換相比仿射變換更加靈活,變換后會產生一個新的四邊形,但不一定是平行四邊形,所以需要非共線的四個點才能唯一確定,原圖中的直線變換后依然是直線。因為四邊形包括了所有的平行四邊形,所以透視變換包括了所有的仿射變換。

opencv中實現透視變換

OpenCV中首先根據變換前后的四個點用cv.getPerspectiveTransform()生成3×3的變換矩陣,然后再用cv.warpPerspective()進行透視變換。

import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
img = cv.imread('card.jpg')

# 原圖中卡片的四個角點
pts1 = np.float32([[148, 80], [437, 114], [94, 247], [423, 288]])
# 變換后分別在左上、右上、左下、右下四個點
pts2 = np.float32([[0, 0], [320, 0], [0, 178], [320, 178]])

# 生成透視變換矩陣
M = cv.getPerspectiveTransform(pts1, pts2)
# 進行透視變換,參數3是目標圖像大小
dst = cv.warpPerspective(img, M, (320, 178))

plt.subplot(121), plt.imshow(img[:, :, ::-1]), plt.title('input')
plt.subplot(122), plt.imshow(dst[:, :, ::-1]), plt.title('output')
plt.show()

實驗結果

圖片矯正結果

總結

圖解圖像各種變換
圖解圖像各種變換
圖像仿射變換和透視變換性質總結


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM