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

Hab*_*yad 6 python numpy image rotation scipy

我有一个512x512像素的2D图像,我想在某个原点(旋转中心)旋转一定角度.这一次,我使用Scipy用旋转方法旋转图像.但是,我被绊倒了,因为旋转总是在图像中心周围完成.对于512x512像素,旋转中心应该在点(x,y)128,128附近.如何使用自定义旋转中心旋转图像,让我们说围绕(x,y)20,128?

Fal*_*lko 18

如果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')
    
    Run Code Online (Sandbox Code Playgroud)

    (虽然图像形状按行列顺序,但pivot在此处是XY或列行顺序.您可能希望以不同方式定义它.)

  2. 围绕中心旋转图像(此处旋转角度为45度):

    imgR = ndimage.rotate(imgP, 45, reshape=False)
    
    Run Code Online (Sandbox Code Playgroud)

    请注意,我们不允许重塑图像,因为我们会自己裁剪图像.

  3. 裁剪图像,使枢轴点位于其原始位置.因此,我们只需从第1步中反转填充:

    imgC = imgR[padY[0] : -padY[1], padX[0] : -padX[1]]
    
    Run Code Online (Sandbox Code Playgroud)

您可以在下图中看到不同的步骤(原始图像,填充,旋转,裁剪; 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]]
Run Code Online (Sandbox Code Playgroud)

更新

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

imgP = np.pad(img, [padY, padX, [0, 0]], 'constant')
Run Code Online (Sandbox Code Playgroud)

不要忘记0在"之前"和"之后"填充中使用a .否则你会得到一个ValueError.