在使用opencv對圖片進行旋轉縮放的過程中會出現原圖截斷的問題,這個問題其實可以直接通過設置參數解決。
一般使用opencv對圖片進行旋轉縮放的流程是首先調用“getRotationMatrix2D”獲得仿射變換矩陣,然後調用“warpAffine”對圖片進行變換。其中“warpAffine”有一個參數可以用來控制變換後的圖片大小,但變換後的圖片大小如何獲得呢?
一個可行的方法是我們知道圖片的尺寸,對這個尺寸進行相同的仿射變換,然後就可以得到變換後的圖片尺寸。代碼如下:
origin_corner_position = [[0, 0], [0, image_height], [image_width, 0], [image_height, image_width]]
mat = cv2.getRotationMatrix2D((image_height/2, image_width/2), 30, 1.2)
for index, point in enumerate(origin_corner_position):
origin_corner_position[index] = np.matmul(mat, np.array([point[0], point[1], 1]).T)
boundingBox = cv2.boundingRect(np.array(origin_corner_position, dtype=np.int32))
如此就可以獲得變換後的圖片尺寸,但僅知道變換後的圖片尺寸還不夠,因爲圖片旋轉縮放後,座標系原點也發生改變,因此還需要進行如下操作對座標系原點進行平移:
mat[0][2] += (boundingBox[2] - image_width)/2
mat[1][2] += (boundingBox[3] - image_height) / 2
仿射變換矩陣中mat[0][2],mat[1][2]兩個量控制平移參數。
new_image = cv2.warpAffine(image, mat, (boundingBox[2], boundingBox[3]))
此時再調用warpAffine就可以獲得經過變換且圖片不會截斷的新圖片。
對於這個問題其實還有一個解決方法,直接把原圖片貼到一張新大小的全0背景圖片上去,然後對新圖片進行旋轉縮放,要注意的一點是新圖片的旋轉中心發生了改變,變爲新圖片的中心。代碼如下:
origin_corner_position = [[0, 0], [0, image_height], [image_width, 0], [image_height, image_width]]
mat = cv2.getRotationMatrix2D((256, 256), 30, 1.2)
for index, point in enumerate(origin_corner_position):
origin_corner_position[index] = np.matmul(mat, np.array([point[0], point[1], 1]).T)
boundingBox = cv2.boundingRect(np.array(origin_corner_position, dtype=np.int32))
background = np.zeros((boundingBox[2], boundingBox[3]), dtype=np.uint8)
startX = int((boundingBox[2] - image_width)/2)
startY = int((boundingBox[3] - image_height) / 2)
background[startX: startX + image_width, startY: startY + image_height] = image
mat = cv2.getRotationMatrix2D((boundingBox[2]/2, boundingBox[3]/2), 30, 1.2)
new_image = cv2.warpAffine(background, mat, (boundingBox[2], boundingBox[3]))