如果 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)
请注意,我们不允许重塑图像,因为我们会自己裁剪图像。
-
裁剪图像,使枢轴点位于其原始位置。因此,我们只需将步骤 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]]
更新
对于彩色图像,您必须避免在填充时添加更多通道(第三维中的零填充):
imgP = np.pad(img, [padY, padX, [0, 0]], 'constant')
不要忘记为“之前”和“之后”填充使用0。否则你会得到一个ValueError。