# -*-coding:utf-8# 幾何變換# 目標:# 幾個變換,移動,旋轉,仿射變換等# 函數:cv2.getPerspectiveTransform()# 變換 OpenCV提供了兩個變換函數,cv2.warpA?ne和cv2.warpPerspective# 使用這兩個函數你可以實現所有類型的變換# cv2.warpA?ne 接收的參數是 2×3 的變換矩陣# cv2.warpPerspective 接收的參數是 3×3 的變換矩陣# 擴展縮放:cv2.resize()import cv2import numpy as np# img = cv2.imread("02.jpg")# # PRint img.shape# # # (1378L, 960L, 3L)## # # 下面的None本應該是輸出圖像的尺寸,但是因為后邊我們設置了縮放因子(fx,fy)# # # 因此這里為None# res = cv2.resize(img, None, fx=0.5, fy=0.5, interpolation=cv2.INTER_CUBIC)# # # 另一種表達方式# # width, height = img.shape[:2]# # res = cv2.resize(img, (0.5*width, 0.5*height),interpolation=cv2.INTER_CUBIC)# print res.shape# # (689L, 480L, 3L)# cv2.imshow("img", img)# cv2.imshow("res", res)# if cv2.waitKey(0) & 0xFF == 27:# cv2.destroyAllWindows()# 平移# 平移就是將對象換一個位置。如果你要沿(x,y)方向移動,移動的距離 是(tx,ty),# 你可以以下面的方式構建移動矩陣:# |1 0 tx|# M = | |# |0 1 ty|? ?# 你可以使用 Numpy 數組構建這個矩陣(數據類型是 np.?oat32)# 然后把它傳給函數 cv2.warpA?ne()# img = cv2.imread("02.jpg")# rows, cols, ch = img.shape# M = np.float32([[1, 0 , 100],[0, 1, 50]]) # 構建矩陣# res = cv2.warpAffine(img, M, (cols, rows))# cv2.imshow("img", img)# cv2.imshow("res", res)# if cv2.waitKey(0)&0xFF == 27:# cv2.destroyAllWindows()# 函數 cv2.warpA?ne() 的第三個參數的是輸出圖像的大小,格式應該是圖像的(寬,高)# 應該記住的是圖像的寬對應的是列數,高對應的是行數# 旋轉# 對一個圖像旋轉角度 θ, 需要使用到下面形式的旋轉矩陣。# M = cosθ ?sinθ# sinθ cosθ ? ?# 但是 OpenCV 允許你在任意地方進行旋轉,但是旋轉矩陣的形式應該修# 改為 ? ?# M = α β (1?α)·center.x?β ·center.y# ?β α β ·center.x + (1?α)·center.x ? ?# 其中:# α = scale·cosθ# β = scale·sinθ# 為了構建這個旋轉矩陣,OpenCV提供了一個函數:cv2.getRotationMatrix2D。## f_img = cv2.imread("02.jpg")# img = cv2.resize(f_img, None, fx=0.5, fy=0.5, interpolation=cv2.INTER_CUBIC)# rows, cols, ch = img.shape# # 這里的第一個參數為旋轉中心,第二個為旋轉角度,第三個為旋轉后的縮放因子# # 可以通過設置旋轉中心,縮放因子,以及窗口大小來防止旋轉后超出邊界的問題# M = cv2.getRotationMatrix2D((cols/2, rows/2), 45, 0.6)# # 第三個參數是輸出圖像的尺寸中心# dst=cv2.warpAffine(img,M,(2*cols,2*rows))# while(1):# cv2.imshow('img',dst)# if cv2.waitKey(1)&0xFF==27:# break# cv2.destroyAllWindows()# 仿射變換(Affine Transformation或 Affine Map)是一種二維坐標到二維坐標之間的線性變換,# 它保持了二維圖形的“平直性”(即:直線經過變換之后依然是直線)和# “平行性”(即:二維圖形之間的相對位置關系保持不變,平行線依然是平行線,且直線上點的位置順序不變)。# 放射變換可以寫為如下的形式:# x1 = a1*x0 + b1*y0 + c1# y1 = a2*x0 + b2*y0 + c2# 或者用矩陣表示(意思一下)# |x1| |a1 b1 c1| |x|# | | = | |* |y|# |y1| |a2 b2 c2| |1|# 仿射變換簡單點說可以是有平移、錯切、縮放、反轉、旋轉復合而成# 在OpenCV中為了創建這個矩陣需要從原圖像中找到三個點以及他們在輸出圖像中的位置# 然后 cv2.getA?neTransform 會創建一個 2x3 的矩陣# 最后這個矩陣會被傳給函數 cv2.warpA?ne()# img = cv2.imread("02.jpg")# rows, cols, ch = img.shape## pos1 = np.float32([[50, 50], [200, 50], [50, 200]]) # 原始圖像中的點# pos2 = np.float32([[10, 100], [200, 50], [100, 250]]) # 變換后原圖中的點應該在的位置## M = cv2.getAffineTransform(pos1, pos2)## dst = cv2.warpAffine(img, M, (cols, rows)) # (寬, 高)的形式# cv2.imshow("img", img)# cv2.imshow("dst", dst)# if cv2.waitKey(0)&0xFF == 27:# cv2.destroyAllWindows()# 透視變換:在不同的視覺拍攝同一個物體,會有不同的圖像,透視變換就是類似于改變拍攝物體的角度(視覺),故稱透視變換# 對于視角變換,我們需要一個 3x3 變換矩陣。在變換前后直線還是直線# 要構建這個變換矩陣,你需要在輸入圖像上找 4 個點,以及他們在輸出圖 像上對應的位置# 這四個點中的任意三個都不能共線# 這個變換矩陣可以有 函數 cv2.getPerspectiveTransform() 構建# 然后把這個矩陣傳給函數 cv2.warpPerspectiveimg = cv2.imread("02.jpg")rows, cols, ch = img.shapepos1 = np.float32([[56, 65], [368, 52], [28, 387], [398, 390]]) # 原圖像的點pos2 = np.float32([[0, 0], [300, 0], [0, 300], [300, 300]]) # 變換后pos1點在新圖上點的位置M = cv2.getPerspectiveTransform(pos1, pos2) # 形成透視變換的矩陣dst = cv2.warpPerspective(img, M, (cols, rows))cv2.imshow("img", img)cv2.imshow("dst", dst)if cv2.waitKey(0)&0xFF == 27: cv2.destroyAllWindows()
新聞熱點
疑難解答