一尘不染

在Python中围绕指定的原点旋转2D图像

python

我有一个512x512像素的2D图像,我想在某个原点(旋转中心)以某个角度旋转。一直以来,我都使用Scipy的旋转方法来旋转图像。但是,我迷迷糊糊,因为旋转始终围绕图像的中心进行。对于512x512像素,旋转中心应围绕点(x,y)128,128。如何使用自定义旋转中心旋转图像,比方说(x,y)20,128?


阅读 548

收藏
2021-01-20

共1个答案

一尘不染

如果不能使用OpenCV,则可以使用NumPy(import numpy as np)和SciPy(from scipy import ndimage)通过以下方式围绕所谓的枢轴点进行图像旋转:

  1. 填充图像img,使枢轴点位于图像中心,并且图像大小加倍:
    padX = [img.shape[1] - pivot[0], pivot[0]]
    

    padY = [img.shape[0] - pivot[1], pivot[1]]
    imgP = np.pad(img, [padY, padX], ‘constant’)

(虽然pivot此处的图像形状按行-列顺序,但按XY或列-行顺序。您可能需要不同地定义它。)

  1. 围绕图像中心旋转图像(此处旋转角度为45度):
    imgR = ndimage.rotate(imgP, 45, reshape=False)
    

请注意,由于我们将自己裁剪图像,因此不允许重塑图像。

  1. 裁剪图像,使枢轴点位于其原始位置。因此,我们只需将步骤1的填充反转即可:
    imgC = imgR[padY[0] : -padY[1], padX[0] : -padX[1]]
    

您可以在以下绘图中看到不同的步骤(原始图像,填充,旋转,裁剪;在(100,300)周围45度)。

在此处输入图片说明

将其包装在一个方便的函数中可得出:

def rotateImage(img, angle, pivot):
    padX = [img.shape[1] - pivot[0], pivot[0]]
    padY = [img.shape[0] - pivot[1], pivot[1]]
    imgP = np.pad(img, [padY, padX], 'constant')
    imgR = ndimage.rotate(imgP, angle, reshape=False)
    return imgR[padY[0] : -padY[1], padX[0] : -padX[1]]

更新资料

对于彩色图像,您必须避免在填充时添加更多通道(第3维为零填充):

imgP = np.pad(img, [padY, padX, [0, 0]], 'constant')

不要忘记对0“ before”和“ after”填充都使用a 。否则你会得到一个ValueError

2021-01-20