OpenCV自帶的旋轉圖像方法 (有損)
原圖像:
如果用OpenCV自帶cv2.warpAffine接口來實現圖片旋轉:
import cv2 # 讀取原圖像 img = cv2.imread("./girl.jpg") h, w = img.shape[:2] center = (w // 2, h // 2) # 逆時針-90°(即順時針90°)旋轉圖片 M = cv2.getRotationMatrix2D(center, -90, 1) rotated_img = cv2.warpAffine(img, M, (w, h)) cv2.imwrite("./rotated_img.jpg", rotated_img)
處理後的結果:
可以明顯看出,原圖像左右兩邊的像素信息(黃色框內)全部丟失,損失嚴重:
無損旋轉
我自己想到了一種無損旋轉的方法,分爲以下五步。
- 首先讀取原圖像: img = cv2.imread("./girl.jpg")
- 獲取輸入圖像的信息,生成旋轉操作所需的參數: h, w = img.shape[:2] padding = (w - h) // 2 center = (w // 2, w // 2) 其中,padding: 指定零填充的寬度; canter: 指定旋轉的軸心座標。
- 在原圖像兩邊做對稱的零填充,使得圖片由矩形變爲方形: img_padded = np.zeros(shape=(w, w, 3), dtype=np.uint8) img_padded[padding:padding+h, :, :] = img
- 逆時針-90°(即順時針90°)旋轉填充後的方形圖片 M = cv2.getRotationMatrix2D(center, -90, 1) rotated_padded = cv2.warpAffine(img_padded, M, (w, w))
- 從旋轉後的圖片中截取出我們需要的部分,作爲最終的輸出圖像: output = rotated_padded[:, padding:padding+h, :] cv2.imwrite("./output.jpg", output)
Code
完整源碼如下:
import cv2 import numpy as np # 讀取原圖像 img = cv2.imread("./girl.jpg") cv2.imshow("", img) cv2.waitKey(1000) # 獲取輸入圖像的信息,生成旋轉操作所需的參數(padding: 指定零填充的寬度; canter: 指定旋轉的軸心座標) h, w = img.shape[:2] padding = (w - h) // 2 center = (w // 2, w // 2) # 在原圖像兩邊做對稱的零填充,使得圖片由矩形變爲方形 img_padded = np.zeros(shape=(w, w, 3), dtype=np.uint8) img_padded[padding:padding+h, :, :] = img cv2.imshow("", img_padded) cv2.waitKey(1000) cv2.imwrite("./img_padded.jpg", img_padded) # 逆時針-90°(即順時針90°)旋轉填充後的方形圖片 M = cv2.getRotationMatrix2D(center, -90, 1) rotated_padded = cv2.warpAffine(img_padded, M, (w, w)) cv2.imshow("", rotated_padded) cv2.waitKey(1000) cv2.imwrite("./rotated_padded.jpg", rotated_padded) # 從旋轉後的圖片中截取出我們需要的部分,作爲最終的輸出圖像 output = rotated_padded[:, padding:padding+h, :] cv2.imshow("", output) cv2.waitKey(1000) cv2.imwrite("./output.jpg", output) cv2.destroyAllWindows()