我想使用带有OpenCV包的python3来旋转15度的图像并将其旋转回来。但是,下面的代码似乎不起作用,但我认为代码中没有逻辑错误。在“NEAREST”窗口中,图像正确旋转,但在“NEAREST-OK-RESTORE”窗口中,图像不会旋转回原始位置(显示在“原始”窗口中)。
#! /usr/bin/env python3
#! -*- coding:utf-8 -*-
import cv2
import numpy as np
imgmat = cv2.imread('./lena.jpg',255)
print(hex(id(imgmat)))
cv2.imshow('original',imgmat)
rows,cols = imgmat.shape
M = cv2.getRotationMatrix2D((cols/2,rows/2),-15,1)
dst = cv2.warpAffine(src=imgmat,M=M,dsize=(cols,rows),flags=cv2.INTER_NEAREST)
print(hex(id(dst)))
cv2.imshow('NEAREST',dst)
OKMM = cv2.invertAffineTransform(M)
dst = cv2.warpAffine(dst,OKMM,(cols,rows),flags = cv2.INTER_NEAREST)
print(hex(id(dst)))
cv2.imshow('NEAREST-OK-RESTORE',dst)
cv2.waitKey(0)
答案 0 :(得分:2)
发生这种情况的原因是因为当您执行旋转时,这是在原始图像尺寸的范围内进行的,因此如果您旋转图像并且产生的角点超出范围,则会导致图像剪裁原始图像尺寸。
您需要做的是对图像进行零填充以使旋转的图像完全包含在图像中,旋转此图像,然后在向后旋转时,您必须裁剪结果。
要计算出对图像进行零填充的效果,请注意图像旋转45度时图像的最大可能尺寸。这意味着图像的对角线现在将是图像中的行数。因此,对图像进行零填充,以便我们至少可以在45度旋转时存储图像,旋转此图像,当您向后旋转时,您必须裁剪结果。
您可以使用numpy.pad
为您执行此操作,当您完成后,您可以简单地裁剪结果:
我已对您的代码进行了以下更改:
import cv2
import numpy as np
imgmat = cv2.imread('./lena.jpg',255)
print(hex(id(imgmat)))
cv2.imshow('original',imgmat)
rows,cols = imgmat.shape
# NEW - Determine the diagonal length of the image
diagonal = int(np.ceil(np.sqrt(rows**2.0 + cols**2.0)))
# NEW - Determine how many pixels we need to pad to the top/bottom and left/right
pp_r, pp_c = (diagonal - rows) // 2, (diagonal - cols) // 2
# NEW - Pad the image
imgmat_copy = np.pad(imgmat, ((pp_r, pp_r), (pp_c, pp_c)), 'constant', constant_values=(0,0))
### Your code as before - note we are rotating the zero padded image
rows,cols = imgmat_copy.shape
M = cv2.getRotationMatrix2D((cols/2,rows/2),-15,1)
dst = cv2.warpAffine(src=imgmat_copy,M=M,dsize=imgmat_copy.shape,flags=cv2.INTER_NEAREST)
print(hex(id(dst)))
cv2.imshow('NEAREST',dst)
OKMM = cv2.invertAffineTransform(M)
dst = cv2.warpAffine(dst,OKMM,(cols,rows),flags = cv2.INTER_NEAREST)
print(hex(id(dst)))
# NEW - Crop the image
dst = dst[pp_r:-pp_r+1,pp_c:-pp_c+1]
cv2.imshow('NEAREST-OK-RESTORE',dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
我现在得到: