在Python中围绕指定原点旋转2D图像
我有一张512x512像素的二维图像,我想要在一个特定的角度和一个特定的原点(旋转中心)进行旋转。之前我一直使用Scipy的rotate方法来旋转图像。但是,我遇到了问题,因为旋转总是围绕图像的中心进行的。对于512x512像素的图像,旋转中心应该在点(x,y)128,128的位置。我该如何在自定义的旋转中心,比如(x,y)20,128的位置旋转这张图像呢?
1 个回答
27
如果你不能使用OpenCV,可以用NumPy(import numpy as np
)和SciPy(from scipy import ndimage
)来实现图像的旋转,方法如下:
首先给图像
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
是按X-Y或列行顺序来定义的。你可能想用不同的方式来定义它。接着,围绕图像的中心进行旋转(这里旋转的角度是45度):
imgR = ndimage.rotate(imgP, 45, reshape=False)
要注意的是,我们不允许改变图像的形状,因为我们会自己裁剪图像。
最后,裁剪图像,使得旋转中心点回到它原来的位置。因此,我们只需将第一步的边框去掉即可:
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]]
更新
对于彩色图像,你需要在加边框时避免增加更多的通道(在第三个维度上进行零填充):
imgP = np.pad(img, [padY, padX, [0, 0]], 'constant')
别忘了在“之前”和“之后”的填充中都使用0
。否则你会遇到ValueError
错误。