OpenCV python3无法正确旋转图像

时间:2018-03-27 15:14:31

标签: python image opencv image-processing image-rotation

我想使用带有OpenCV包的python3来旋转15度的图像并将其旋转回来。但是,下面的代码似乎不起作用,但我认为代码中没有逻辑错误。在“NEAREST”窗口中,图像正确旋转,但在“NEAREST-OK-RESTORE”窗口中,图像不会旋转回原始位置(显示在“原始”窗口中)。

enter image description here

#! /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)

测试图像在这里: enter image description here

1 个答案:

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

我现在得到:

enter image description here