7. 影象的幾何變換-cv2.resize()、cv2.warpAffine()、cv2.getRotationMatrix2D()、cv2.getAffineTransform()、透視變換
1. 改變影象的大小-cv2.resize()
函式原型:cv2.resize(src, dst, Size, fx, fy, interpolation)
引數說明:1. src 輸入圖片 2. dst 輸出圖片 3.size 輸出圖片的大小 4. fx、fy:沿水平軸、垂直軸的縮放因子(寬度、高度) 5.插入方式,預設為INTER_LINEAR.
插入方式interpolation有以下幾種:
INTER_NEAREST | 最近鄰插值 |
INTER_LINEAR | 雙線性插值(預設設定) |
INTER_AREA | 使用畫素區域關係進行重取樣。 |
INTER_CUBIC | 4x4畫素鄰域的雙三次插值 |
INTER_LANCZOS4 | 8x8畫素鄰域的Lanczos插值 |
程式碼如下:
def resize_demo(image): print("Origin size:", image.shape) # 第一種方法:通過fx,fy縮放因子 res = cv.resize(image, None, fx=1, fy=3, interpolation=cv.INTER_CUBIC) # fx寬 fy高 print("After resize 1 size:", res.shape) # 第二種方法:直接設定輸出影象的尺寸,所以不用設定縮放因子 height,width = image.shape[:2] res=cv.resize(image,(2*width,2*height),interpolation=cv.INTER_CUBIC) print("After resize 2 size:", res.shape) while(1): cv.imshow('res',res) cv.imshow('img',image) if cv.waitKey(1) & 0xFF == 27: break
2. 影象的偏移- cv2.warpAffine()
影象的平移也分為兩步:首先定義好影象的平移矩陣,分別指定x方向(寬)和y方向上(高)的平移量tx和ty,平移矩陣(2 X 3)的形式如下:
程式碼如下:
def move_demo(image): rows, cols = image.shape[:2] M = np.float32([[1, 0, 100], [0, 1, 50]]) # M為平移矩陣,100為寬移動的距離,50為高 dst = cv.warpAffine(image, M, (cols, rows)) # 仿射變換函式 (cols, rows):平移後圖像的大小 cv.imshow('image', dst)
3. 影象的旋轉- cv2.getRotationMatrix2D()
這個函式可以在任何位置進行旋轉變換,它的旋轉矩陣為:
這個函式有三個引數:旋轉中心,旋轉角度,旋轉後圖像的縮放比例。
然後再使用函式cv2.warpAffine()利用得到的M對原始影象進行變換即可。
程式碼如下:
def rotation_demo(img):
rows, cols = img.shape[:2]
# 將影象相對於中心旋轉90度,而不進行任何縮放。旋轉中心,角度,縮放比率
M = cv.getRotationMatrix2D((cols / 2, rows / 2), 90, 1)
dst = cv.warpAffine(img, M, (cols, rows))
cv.imshow('original', img)
cv.imshow('result', dst)
cv.waitKey(0)
cv.destroyAllWindows()
4. 影象的仿射變換-cv2.getAffineTransform()
仿射變換,又稱仿射對映,是指在幾何中,一個向量空間進行一次線性變換並接上一個平移,變換為另一個向量空間。仿射變換需要一個M矩陣,但是由於仿射變換比較複雜,一般直接找很難找到這個矩陣,opencv提供了根據變換前後三個點的對應關係來自動求解M的函式,這個函式就是:cv2.getAffineTransform(),引數如下:
- src:原始影象中的三個點的座標
- dst:變換後的這三個點對應的座標
- M:根據三個對應點求出的仿射變換矩陣
然後再使用函式cv2.warpAffine()利用得到的M對原始影象進行變換即可。
程式碼如下:
def affine_demo(img):
rows, cols, ch = img.shape
pts1 = np.float32([[50, 50], [200, 50], [50, 200]])
pts2 = np.float32([[10, 100], [200, 50], [100, 250]])
M = cv.getAffineTransform(pts1, pts2)
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()
5. 透視變換-cv2.getPerspectiveTransform()、cv2.warpPerspective()
透視變換(Perspective Transformation)是將成像投影到一個新的視平面(Viewing Plane),也稱作投影對映(Projective Mapping)。
5.1cv2.getPerspectiveTransform(src, dst)
引數說明:
-
src:源影象中待測矩形的四點座標
-
sdt:目標影象中矩形的四點座標
-
返回值:由源影象中矩形到目標影象矩形變換的矩陣 ,得到變換矩陣。
5.2cv2.warpPerspective(src, M, dsize, dst=None, flags=None, borderMode=None, borderValue=None)
引數說明:
-
src:輸入影象
-
M:變換矩陣
-
dsize:目標影象shape
-
flags:插值方式,interpolation方法INTER_LINEAR或INTER_NEAREST
-
borderMode:邊界補償方式,BORDER_CONSTANT or BORDER_REPLICATE
-
borderValue:邊界補償大小,常值,預設為0
-
作用:進行透視變換。
程式碼如下:
def perspective_demo(img):
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 = cv.getPerspectiveTransform(pts1, pts2)
dst = cv.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()