OpenCV python3无法正确旋转图像 [英] OpenCV python3 cannot rotate image back correctly

查看:258
本文介绍了OpenCV python3无法正确旋转图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将python3与OpenCV软件包一起使用,以将图像旋转15度并将其旋转回去.但是,下面的代码似乎不起作用,但是我认为代码中没有逻辑错误.在"NEAREST"窗口中,图像已正确旋转,但在"NEAREST-OK-RESTORE"窗口中,图像未旋转回到其原始位置(显示在原始"窗口中).

I want to use python3 with OpenCV packages to rotate an image in a degree 15 and rotate it back. However, the code below seem does not work but I think there no logic error in the codes. In the "NEAREST" window, the image is rotated correctly but in the "NEAREST-OK-RESTORE" window the image is not rotate back to its original position ( showed in "original" window ).

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

测试图像在这里:

推荐答案

发生这种情况的原因是,当您执行旋转时,这是在原始图像尺寸范围内进行的,因此会产生图像如果您正在旋转图像,则会进行剪切,并且所产生的角点会超出原始图像的尺寸.

The reason why this is happening is because when you are performing the rotation, this is doing it within the span of the original image dimensions, so this results in image clipping if you are rotating the image and the resulting corner points extend beyond the original image dimensions.

您要做的是对图像进行零填充,以便将旋转后的图像完全包含在其中,然后旋转该图像,然后向后旋转时,您将不得不裁剪结果.

What you have to do is zero pad the image so that the rotated image is fully contained within it, rotate this image then when you rotate back, you will have to crop the result.

要弄清楚对图像进行零填充的程度,请注意,图像旋转45度时,图像的最大尺寸可能会最大.这意味着图像的对角线现在将是图像中的行数.因此,请对图像进行零填充,以便我们至少可以在进行45度旋转时存储图像,旋转该图像,然后向后旋转,则必须裁剪结果.

To figure out how much to zero pad your image by, note that the largest possible dimensions of your image will be when the image is at a 45 degree rotation. This means that the diagonal of the image would now be the number of rows in the image. Therefore, zero pad your image so that we can at least store the image when subject to a 45 degree rotation, rotate this image and when you rotate back you'll have to crop the result.

您可以使用 numpy.pad 来为您执行此操作,完成后,您可以简单地裁剪结果:

You can use numpy.pad to do this for you and when you're done you can simply crop the result:

为此,我对您的代码进行了以下更改:

I've made the following changes to your code to do this:

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

我现在得到:

这篇关于OpenCV python3无法正确旋转图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆