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()