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

13

我有一张512x512像素的2D图像,我想围绕某个特定原点(旋转中心)以特定角度旋转它。一直以来,我都是使用Scipy的rotate方法旋转图像。但是,我遇到了一个问题,旋转总是在图像的中心完成。对于512x512像素的图像,旋转中心应该位于点(x,y)128,128。我如何使用自定义旋转中心(比如(x,y)20,128)旋转图像呢?


1
如果OpenCV可用,您可以在此处找到解决方案:https://dev59.com/a2ox5IYBdhLWcg3wr2Po。 - Falko
1个回答

27
如果无法使用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 是按 X-Y 或者列-行顺序排列的。你可能想要根据需要重新定义它。)

  2. 将图像围绕其中心旋转(这里的旋转角度为45度):

  3. imgR = ndimage.rotate(imgP, 45, reshape=False)
    

    请注意,我们禁止对图像进行重塑,因为我们会自行裁剪图像。

  4. 将图像裁剪到枢轴点处的原始位置。因此,我们只需从步骤1中反向填充:

  5. imgC = imgR[padY[0] : -padY[1], padX[0] : -padX[1]]
    
    你可以在以下图表中看到不同的步骤(原始图像、填充、旋转、裁剪;45度绕(100,300)旋转)。

    enter image description here

    将其包装成一个方便的函数:

    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


1
我尝试了这段代码,但在所有的图片上都出现了ValueError错误:“无法创建正确形状的元组”。这是因为它们是彩色图像而lena是黑白图像吗? - Fight Fire With Fire
@FightFireWithFire: 我能够复现你的错误并相应地修改了我的答案。 - Falko

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接