【OpenCv-Python】十一、Geometric Transformations of Images 圖像的幾何變換

原文鏈接:Geometric Transformations of Images

圖像的幾何變換

目標

  • 在本教程中,你將學習幾種簡單變換。如:移動、旋轉、仿射變換。
  • 你將學習這些函數:cv2.getPerspectiveTransform等。

變換

openCv 提供了兩種變換函數,cv2.warpAffine 和 cv2.warpPerspective。通過這兩個函數,你可以實現所有的圖像變換。cv2.warpAffine接受的參數是2x3的變換矩陣。cv2.warpPerspective 接受的參數是3x3的變換矩陣。

擴展縮放

擴展縮放只是改變圖像的尺寸大小。OpenCV 提供的函數 cv2.resize() 可以實現這個功能。圖像的尺寸可以自己手動設置,你也可以指定縮放因子。我們可以選擇使用不同的插值方法。在縮放時我們推薦使用 cv2.INTER_AREA 。在擴展時我們推薦使用 v2.INTER_CUBIC(慢) 和 v2.INTER_LINEAR。默認情況下所有改變圖像尺寸大小的操作使用的插值方法都是 cv2.INTER_LINEAR。 你可以使用下面任意一種方法改變圖像的尺寸:

import cv2
import numpy as np

img = cv2.imread('./image/messi5.jpg')

res = cv2.resize(img,None,fx=2, fy=2, interpolation = cv2.INTER_CUBIC)

#或者

height, width = img.shape[:2]
res = cv2.resize(img,(2*width, 2*height), interpolation = cv2.INTER_CUBIC)

while(1):
    cv2.imshow('res',res)
    cv2.imshow('img',img)
    if cv2.waitKey(1) & 0xFF == 27: 
        break
cv2.destroyAllWindows()

平移

平移是轉換一個對象的位置。如果你沿(x ,y) 方向移動,移動的距離是(tx,ty)({t_x},{t_y})你可以用下面的方式構建移動矩陣:M = $ \begin{bmatrix} 1 & 0 & t_x \ 0 & 1 & t_y \ \end{bmatrix} $你可以使用 Numpy 數組構建一個矩陣數據類型是 np.float32 ,然後把它傳給函數 cv2.warpAffine()。看下面的這個例子,它移動了(100,50)個像素。

import cv2
import numpy as np

img = cv2.imread('image/messi5.jpg',0)
rows,cols = img.shape

M = np.float32([[1,0,100],[0,1,50]])
dst = cv2.warpAffine(img,M,(cols,rows))

cv2.imshow('img',dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

警告

函數 cv2.warpAffine() 的第三個參數的是輸出圖像的大小,它的格式應該是圖像的寬和高。應記住的是圖像的寬對應的是列數,高對應的是行數。

看結果展示:在這裏插入圖片描述

旋轉

對一個圖像旋角度 θ,需要使用到下面形式的旋轉矩陣:M = $ \begin{bmatrix} cos𝛳 & -sin𝛳 \ sin𝛳 & cos𝛳 \ \end{bmatrix} $ 但是OpenCV提供了可調旋轉中心的縮放旋轉,這樣你可以在任何你喜歡的位置旋轉。修正後的變換矩陣爲:$ \begin{bmatrix} å & ß & (1-å)·center.x - ß·center.y \ -ß & å & ß·center.x + (1-å)center.y \ \end{bmatrix} $其中,å = scale·cos𝛳,ß = scale·sin𝛳

爲了構建這個旋轉矩陣 OpenCV 提供了一個函數 cv2.getRotationMatrix2D。 下面的例子是在不縮放的情況下將圖像旋 90 度。

img = cv2.imread('messi5.jpg',0)
rows,cols = img.shape

M = cv2.getRotationMatrix2D((cols/2,rows/2),90,1)
dst = cv2.warpAffine(img,M,(cols,rows))

看這個結果:
在這裏插入圖片描述

仿射變換

在仿射變換中,原圖中所有的平行線在結果圖像中同樣平行。爲了創建這個個矩陣我們從原圖像中找到三個點以及他們在輸出圖像中的位置。然後 cv2.getAffineTransform 會創建一個 2X3 的矩陣。最後這個矩陣會傳給函數 cv2.warpAffine。

來看看下面的例子,以及我選擇的點(被標記爲綠色的點 )

img = cv2.imread('drawing.png')
rows,cols,ch = img.shape

pts1 = np.float32([[50,50],[200,50],[50,200]])
pts2 = np.float32([[10,100],[200,50],[100,250]])

M = cv2.getAffineTransform(pts1,pts2)

dst = cv2.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()

看下面結果,
在這裏插入圖片描述

透視變換

對於透視變換,我們需要一個 3X3 變換矩陣。在變換前後直線還是直線。要構建這個變換矩,你需要在在輸入圖像上找 4 個點,以及他們在輸出圖像上對應的位置。 四個點中的任意三個不能共線。這個變換矩陣可以由函數 cv2.getPerspectiveTransform() 構建。然後把這個矩陣傳給函數 cv2.warpPerspective。

代碼如下:



img = cv2.imread('sudokusmall.png')
rows,cols,ch = img.shape

pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])
pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]])

M = cv2.getPerspectiveTransform(pts1,pts2)

dst = cv2.warpPerspective(img,M,(300,300))

plt.subplot(121),plt.imshow(img),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')
plt.show()

結果:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章