图像处理: 无损地旋转图像

OpenCV自带的旋转图像方法 (有损)

原图像:
图像处理: 无损地旋转图像_第1张图片

如果用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)

处理后的结果:
图像处理: 无损地旋转图像_第2张图片

可以明显看出,原图像左右两边的像素信息(黄色框内)全部丢失,损失严重:
图像处理: 无损地旋转图像_第3张图片

无损旋转

我自己想到了一种无损旋转的方法,分为以下五步。

  1. 首先读取原图像:

    img = cv2.imread("./girl.jpg")

    图像处理: 无损地旋转图像_第4张图片

  2. 获取输入图像的信息,生成旋转操作所需的参数:

    h, w = img.shape[:2]
    padding = (w - h) // 2
    center = (w // 2, w // 2)

    其中,padding: 指定零填充的宽度; canter: 指定旋转的轴心坐标。

  3. 在原图像两边做对称的零填充,使得图片由矩形变为方形:

    img_padded = np.zeros(shape=(w, w, 3), dtype=np.uint8)
    img_padded[padding:padding+h, :, :] = img

    图像处理: 无损地旋转图像_第5张图片

  4. 逆时针-90°(即顺时针90°)旋转填充后的方形图片

    M = cv2.getRotationMatrix2D(center, -90, 1)
    rotated_padded = cv2.warpAffine(img_padded, M, (w, w))

    图像处理: 无损地旋转图像_第6张图片

  5. 从旋转后的图片中截取出我们需要的部分,作为最终的输出图像:

    output = rotated_padded[:, padding:padding+h, :]
    
    cv2.imwrite("./output.jpg", output)

    图像处理: 无损地旋转图像_第7张图片

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

你可能感兴趣的:(图像处理)