opencv 在python中还原旋转后的图像,使其不带黑色边框

thtygnil  于 2022-12-04  发布在  Python
关注(0)|答案(1)|浏览(242)

我使用了以下代码来旋转图像(initial image)并进行一些处理:

def rotate_image(mat, angle):
    """
    Rotates an image (angle in degrees) and expands image to avoid cropping
    """

    height, width = mat.shape[:2] # image shape has 3 dimensions
    image_center = (width/2, height/2) # getRotationMatrix2D needs coordinates in reverse order (width, height) compared to shape

    rotation_mat = cv2.getRotationMatrix2D(image_center, angle, 1.)

    # rotation calculates the cos and sin, taking absolutes of those.
    abs_cos = abs(rotation_mat[0,0]) 
    abs_sin = abs(rotation_mat[0,1])

    # find the new width and height bounds
    bound_w = int(height * abs_sin + width * abs_cos)
    bound_h = int(height * abs_cos + width * abs_sin)

    # subtract old image center (bringing image back to origo) and adding the new image center coordinates
    rotation_mat[0, 2] += bound_w/2 - image_center[0]
    rotation_mat[1, 2] += bound_h/2 - image_center[1]

    # rotate image with the new bounds and translated rotation matrix
    rotated_mat = cv2.warpAffine(mat, rotation_mat, (bound_w, bound_h))
    return rotated_mat

ModifiedVersionRotation = rotate_image(img, 35)
cv2.imwrite("lenarot.jpg", ModifiedVersionRotation)

这个函数在图像上添加了黑色边框,这样它就不会在旋转rotated image时被裁剪,这正是我真正需要的。但是,我如何旋转回图像并删除黑色边框呢?

vohkndzv

vohkndzv1#

对于旋转回来,我们可以计算逆变换,并将其应用于旋转后的图像:
示例:

inv_rotation_mat = cv2.invertAffineTransform(rotation_mat)  # Get inverse transformation matrix
unrotated_mat = cv2.warpAffine(rotated_mat, inv_rotation_mat, (mat.shape[1], mat.shape[0]))  # Apply warp (and set the destination size to original size of mat).

完整代码示例:

import cv2

img = cv2.imread('lena.jpg')

def rotate_image(mat, angle):
    """
    Rotates an image (angle in degrees) and expands image to avoid cropping
    """

    height, width = mat.shape[:2] # image shape has 3 dimensions
    image_center = (width/2, height/2) # getRotationMatrix2D needs coordinates in reverse order (width, height) compared to shape

    rotation_mat = cv2.getRotationMatrix2D(image_center, angle, 1.)

    # rotation calculates the cos and sin, taking absolutes of those.
    abs_cos = abs(rotation_mat[0,0]) 
    abs_sin = abs(rotation_mat[0,1])

    # find the new width and height bounds
    bound_w = int(height * abs_sin + width * abs_cos)
    bound_h = int(height * abs_cos + width * abs_sin)

    # subtract old image center (bringing image back to origo) and adding the new image center coordinates
    rotation_mat[0, 2] += bound_w/2 - image_center[0]
    rotation_mat[1, 2] += bound_h/2 - image_center[1]

    # rotate image with the new bounds and translated rotation matrix
    rotated_mat = cv2.warpAffine(mat, rotation_mat, (bound_w, bound_h))
    return (rotated_mat, rotation_mat)  # Also return rotation_mat

ModifiedVersionRotation, T = rotate_image(img, 35)

iT = cv2.invertAffineTransform(T)

unrotated_img = cv2.warpAffine(ModifiedVersionRotation, iT, (img.shape[1], img.shape[0]))

#cv2.imwrite("lenarot.jpg", ModifiedVersionRotation)
#cv2.imwrite("lenarotback.jpg", unrotated_img)
cv2.imwrite("lenarot.png", ModifiedVersionRotation)
cv2.imwrite("lenarotback.png", unrotated_img)


# Show images for testing
cv2.imshow('ModifiedVersionRotation', ModifiedVersionRotation)
cv2.imshow('img', img)
cv2.imshow('unrotated_img', unrotated_img)
cv2.waitKey()
cv2.destroyAllWindows()

ModifiedVersionRotation

unrotated_img

原始图像:

“恢复”的图像看起来很模糊,因为每个扭曲(向前和向后)都应用了双线性插值,使图像有点模糊。

相关问题