opencv提供了2個轉換函數,可以對圖像進行任意轉換。
cv.warpAffine和cv.warpPerspective.第一種采取2*3的矩陣作為輸入。第二種采取3*3的矩陣作為輸入。
1.縮放
函數:
cv.resize(src, dsize[, dst[, fx[, fy[, interpolation]]]])
參數:
src:輸入圖像
dsize:目標尺寸,整形,非0
dst:目標圖像,大小為dsize,或由src.size()計算而來
fx:水平軸縮放比例,非0
fy:垂直軸縮放比例,非0
interpolation:插值算法,分為以下幾種
INTER_NEAREST
Python: cv.INTER_NEAREST
|
nearest neighbor interpolation最鄰近插值 |
INTER_LINEAR
Python:
cv.INTER_LINEAR
|
bilinear interpolation雙線性插值 |
INTER_CUBIC
Python: cv.INTER_CUBIC
|
bicubic interpolation雙三次插值 |
INTER_AREA
Python: cv.INTER_AREA
|
resampling using pixel area relation. It may be a preferred method for image decimation, as it gives moire'-free results. But when the image is zoomed, it is similar to the INTER_NEAREST method.基於局部像素的重采樣 |
INTER_LANCZOS4
Python: cv.INTER_LANCZOS4
|
Lanczos interpolation over 8x8 neighborhood.基於8x8像素鄰域的Lanczos插值 |
INTER_LINEAR_EXACT
Python: cv.INTER_LINEAR_EXACT
|
Bit exact bilinear interpolation.位精確雙線性插值 |
INTER_MAX
Python: cv.INTER_MAX
|
mask for interpolation codes.插補碼掩碼 |
WARP_FILL_OUTLIERS
Python: cv.WARP_FILL_OUTLIERS
|
flag, fills all of the destination image pixels. If some of them correspond to outliers in the source image, they are set to zero |
WARP_INVERSE_MAP
Python: cv.WARP_INVERSE_MAP
|
flag, inverse transformation For example, linearPolar or logPolar transforms:
|
舉例
import numpy as np import cv2 as cv src = cv.imread('4.jpg') # method 1 res1 = cv.resize(src, None, fx=1.2, fy=1.2, interpolation=cv.INTER_CUBIC) # method 2 直接設置輸出尺寸 height, width = src.shape[:2] # 獲得原尺寸 res2 = cv.resize(src, (int(0.5*width), int(0.5*height)),interpolation=cv.INTER_CUBIC) while(1): cv.imshow("src", src) cv.imshow("res1", res1) cv.imshow("res2", res2) if cv.waitKey(1) & 0xFF == 27: break cv.destroyAllWindows()
平移
平移是物體的移動,如果知道物體平移的坐標(tx,ty),可以創建如下變換矩陣
將其放入類型為np.float32的數組中,將M矩陣賦值給 cv.warpAffine() 函數。即可實現平移
函數
dst=cv.warpAffine(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]])
參數:
src | 輸入圖像 |
dst | 與src同類型的輸出圖像 |
M | 2×3 的變換矩陣 |
dsize | 輸出圖像尺寸大小 |
flags | combination of interpolation methods (see InterpolationFlags) and the optional flag WARP_INVERSE_MAP that means that M is the inverse transformation ( dst→src ).插值矩陣,上一章的表。 |
borderMode | 邊界像素模式,默認為BORDER_CONSTANT ,邊界按常數填充 |
borderValue | 邊界填充值; 默認為0,所以默認情況下填充為黑色 |
特別注意:dsize參數是指輸出圖像的寬高,即對應圖像的列,行。
舉例
import numpy as np import cv2 as cv img = cv.imread('4.jpg', 0) rows, cols = img.shape M = np.float32([[1, 0, 300], [0, 1, 50]])
dst = cv.warpAffine(img, M, (cols, rows)) cv.imshow('img', dst) cv.waitKey(0) cv.destroyAllWindows()
旋轉
平移和旋轉都是仿射變換的特例,所用函數都是cv2.warpAffine,只是轉換矩陣M有所不同。
圖像旋轉θ度是由變換矩陣 M 得到的
但是opencv改進了這個矩陣,如下圖。使得提供了縮放旋轉與可調的旋轉中心。
上述矩陣表示繞 center.x,center.y 旋轉 θ度
函數:
retval=cv.getRotationMatrix2D(center, angle, scale)獲取變換矩陣M
參數:
center | 旋轉中心 |
angle | Rotation angle in degrees. Positive values mean counter-clockwise rotation (the coordinate origin is assumed to be the top-left corner).旋轉角度,角度為正則表示逆時針旋轉 |
scale | 旋轉后的縮放系數 |
舉例:
import numpy as np import cv2 as cv src = cv.imread('4.jpg', 0) rows, cols = src.shape # 旋轉中心 旋轉角度 縮放系數 M = cv.getRotationMatrix2D(((cols-1) / 2.0,(rows-1)/2.0), 90,1) # 原圖像 變換矩陣 輸出圖像尺寸中心 dst = cv.warpAffine(src, M, (cols, rows)) while(1): cv.imshow('src', src) cv.imshow('dst', dst) if cv.waitKey(1) & 0xFF == 27: break cv.destroyAllWindows()
仿射變換
在仿射變換中,原圖像中的所有平行線在輸出圖像中仍然是平行的,直線仍然是直線,為了找到變換矩陣,我們需要從輸入圖像中選取三個點,以及它們在輸出圖像中的對應位置。利用 cv.getAffineTransform創建一個2*3 的變換矩陣,賦值給cv.warpAffine。
函數
retval=cv.getAffineTransform(src, dst),獲取仿射矩陣M
參數:
src | Coordinates of triangle vertices in the source image.原圖中3個點所組成的矩陣,數據類型為np.float32 |
dst | Coordinates of the corresponding triangle vertices in the destination image.目標圖中對應的3個點所組成的矩陣,數據類型為np.float32 |
舉例
import numpy as np import cv2 as cv import matplotlib.pyplot as plt img = cv.imread('4.jpg') rows, cols, ch = img.shape
#原圖3個點的矩陣
pts1 = np.float32([[50, 50], [200, 50], [50, 200]])
#輸出圖3個點的矩陣
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()
透視變換
透視變換。需要一個3*3的變換矩陣,直線在變換之后仍然是直線,但不能保證平行。為了找到這個變換矩陣,我們需要輸入圖像的4個點和對應的輸出圖像的點。在4個點中,其中的任意三個點不能連成直線,然后利用 cv.getPerspectiveTransform函數求出變換矩陣。最后3*3的變換矩陣作為函數 cv.warpPerspective 的輸入,進行變換。
函數:
retval=cv.getPerspectiveTransform(src, dst[, solveMethod])獲取轉換矩陣M
參數:
src | 原圖像四邊形頂點坐標,數據類型為np.float32 |
dst | 目標圖像對應四邊形頂點坐標,數據類型為np.float32 |
solveMethod | DecompTypes |
dst=cv.warpPerspective(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]])
參數:
src | 輸入圖像 |
dst | 和src具有相同類型具有dsize大小的輸出圖像 |
M | 3×3 變換矩陣 |
dsize | 輸出圖像大小 |
flags | 插值方法,見頁首 |
borderMode | pixel extrapolation method (BORDER_CONSTANT or BORDER_REPLICATE).邊界像素模式,默認為BORDER_CONSTANT |
borderValue | 邊界填充值; 默認為0,所以默認情況下填充為黑色 |
舉例:
import numpy as np import cv2 as cv import matplotlib.pyplot as plt img = cv.imread('4.jpg') 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()