轉(zhuǎn)換
OpenCV提供了兩個(gè)轉(zhuǎn)換函數(shù),cv2.warpAffine和cv2.warpPerspective,通過(guò)他們你可以進(jìn)行各種轉(zhuǎn)換,cv2.warpAffine接受2x3的轉(zhuǎn)換矩陣二cv2.warpPerspective接受3x3的轉(zhuǎn)換矩陣做為輸入。
縮放
OpenCV有一個(gè)函數(shù)cv2.resize()來(lái)干這個(gè),圖片的大小可以人工指定,或者你可以指定縮放因子。有不同的差值方式可以使用,推薦的插值方法是縮小時(shí)用cv2.INTER_AREA,放大用cv2.INTER_CUBIC(慢)和cv2.INTER_LINEAR。默認(rèn)情況下差值使用cv2.INTER_LINEAR。你可以使用下面兩種方法來(lái)改變圖片大小:
import cv2
import numpy as np
img = cv2.imread('messi5.jpg')
res = cv2.resize(img, None, fx=2, fy=2, interpolation=cv2.INTER_CUBIC)
#OR
height, width = img.shape[:2]
res = cv2.resize(img, (2*width, 2*height), interpolation=cv2.INTER_CUBIC)
平移
平移是改變物體的位置。如果你知道在(x, y)方向的變化是(tx, ty),你可以創(chuàng)建轉(zhuǎn)換矩陣M:
你可以把它變成Numpy的數(shù)組,類(lèi)型是np.float32的,然后把它傳給cv2.warpAffine()函數(shù),下面的例子平移(100, 50):
import cv2
import numpy as np
img = cv2.imread('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()函數(shù)的第三個(gè)參數(shù)是輸出圖片的大小,應(yīng)該是(width, height)的形式,記住width=列數(shù),height=行數(shù)
旋轉(zhuǎn)
對(duì)一個(gè)圖片旋轉(zhuǎn)一個(gè)θ角是通過(guò)下面這個(gè)形式的轉(zhuǎn)換矩陣實(shí)現(xiàn)的:
但是OpenCV提供了可選中心的縮放旋轉(zhuǎn),所以你可以按任意點(diǎn)旋轉(zhuǎn)。轉(zhuǎn)換矩陣變?yōu)椋?/p>
其中:
要找到這個(gè)轉(zhuǎn)換矩陣,OpenCV提供了一個(gè)函數(shù),cv2.getRotationMatrix2D。看下面的例子,把圖片旋轉(zhuǎn)了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))
結(jié)果:
仿射變換
在仿射變換里,所有原始圖片里的平行線在輸出的圖片里仍然平行,要找到轉(zhuǎn)換矩陣,我們需要輸入圖片的三個(gè)點(diǎn),和他們?cè)谳敵鰣D片里的對(duì)應(yīng)位置,然后cv2.getAffineTransform會(huì)創(chuàng)建一個(gè)2x3的矩陣,然后把這個(gè)矩陣傳給cv2.warpAffine.
看下面的例子,注意我選的三個(gè)點(diǎn)(綠色的點(diǎn))
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()
結(jié)果:
對(duì)于透視變換,你需要一個(gè)3x3的轉(zhuǎn)換矩陣。轉(zhuǎn)換后直線仍然保持直線。要得到這個(gè)轉(zhuǎn)換矩陣,你需要輸入圖片上的4個(gè)點(diǎn),以及輸出圖片上對(duì)應(yīng)的點(diǎn)。在這四個(gè)點(diǎn)中,3個(gè)不能同線。然后cv2.getPerspectiveTransform函數(shù)就能得到轉(zhuǎn)換矩陣了,再用cv2.warpPerspective來(lái)接收這個(gè)3x3的轉(zhuǎn)換矩陣。
代碼:
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()
END