我有一张512x512像素的2D图像,我想围绕某个特定原点(旋转中心)以特定角度旋转它。一直以来,我都是使用Scipy的rotate方法旋转图像。但是,我遇到了一个问题,旋转总是在图像的中心完成。对于512x512像素的图像,旋转中心应该位于点(x,y)128,128。我如何使用自定义旋转中心(比如(x,y)20,128)旋转图像呢?
我有一张512x512像素的2D图像,我想围绕某个特定原点(旋转中心)以特定角度旋转它。一直以来,我都是使用Scipy的rotate方法旋转图像。但是,我遇到了一个问题,旋转总是在图像的中心完成。对于512x512像素的图像,旋转中心应该位于点(x,y)128,128。我如何使用自定义旋转中心(比如(x,y)20,128)旋转图像呢?
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)
请注意,我们禁止对图像进行重塑,因为我们会自行裁剪图像。
将图像裁剪到枢轴点处的原始位置。因此,我们只需从步骤1中反向填充:
imgC = imgR[padY[0] : -padY[1], padX[0] : -padX[1]]
你可以在以下图表中看到不同的步骤(原始图像、填充、旋转、裁剪;45度绕(100,300)旋转)。
将其包装成一个方便的函数:
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')
不要忘记在“before”和“after”填充时都使用0
。否则,你会得到一个ValueError
。