仿射变换中的旋转图像

时间:2019-05-03 02:23:02

标签: python python-3.x image-rotation affinetransform

我无法在仿射变换中正确旋转图像。目前以下是我正在使用的:

rotation_matrix = np.array([[np.cos(rotation_angle), 
        -np.sin(rotation_angle),0], 
        [np.sin(rotation_angle),
        np.cos(rotation_angle),0], 
        [0,0,1]])

如果我将角度设置为大于约50度的任何角度,我会得到一个全黑的图像,其中没有任何东西(我将新图像设置为全黑,这表示没有翻译的像素落在像素的范围内。新图片)。如果我旋转的角度小于50度,我会得到图像的一部分,但是根据我的判断,它看起来旋转得不正确。此外,原点0,0位于左上角。我希望将图像的一部分旋转到原始图像的边界之外。

在应用旋转之前,我通过

求逆
#get inverse of transform matrix
    inverse_transform_matrix = np.linalg.inv(multiplied_matrices)

发生旋转的位置:

def Apply_Matrix_To_Image(matrix_to_apply, image_map):
    #takes an image and matrices and applies it.  
    x_min = 0
    y_min = 0
    x_max = image_map.shape[0]
    y_max = image_map.shape[1] 

    new_image_map = np.zeros((x_max, y_max), dtype=int)

    for y_counter in range(0, y_max):
        for x_counter in range(0, x_max):
            curr_pixel = [x_counter,y_counter,1]

            curr_pixel = np.dot(matrix_to_apply, curr_pixel)

            print(curr_pixel)

            if curr_pixel[0] > x_max - 1 or curr_pixel[1] > y_max - 1 or x_min > curr_pixel[0] or y_min > curr_pixel[1]:
                next
            else:
                new_image_map[x_counter][y_counter] = image_map[int(curr_pixel[0])][int(curr_pixel[1])] 

    return new_image_map

1 个答案:

答案 0 :(得分:0)

# tested with python3
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image

def GetRotateMatrixWithCenter(x, y, angle):
    # https://math.stackexchange.com/questions/2093314
    move_matrix = np.array(
        [
            [1, 0, x], 
            [0, 1, y], 
            [0, 0, 1]
        ])
    rotation_matrix = np.array(
        [
            [np.cos(angle), -np.sin(angle), 0], 
            [np.sin(angle),  np.cos(angle), 0], 
            [0,                       0,                      1]
        ])
    back_matrix = np.array(
        [
            [1, 0, -x], 
            [0, 1, -y], 
            [0, 0, 1]
        ])

    r = np.dot(move_matrix, rotation_matrix)
    return np.dot(r, back_matrix)

def Apply_Matrix_To_Image(matrix_to_apply, image_map):
    #takes an image and matrices and applies it.  
    x_min = 0
    y_min = 0
    x_max = image_map.shape[0]
    y_max = image_map.shape[1] 

    new_image_map = np.zeros((x_max, y_max), dtype=int)

    for y_counter in range(0, y_max):
        for x_counter in range(0, x_max):
            curr_pixel = [x_counter,y_counter,1]

            curr_pixel = np.dot(matrix_to_apply, curr_pixel)

            # print(curr_pixel)

            if curr_pixel[0] > x_max - 1 or curr_pixel[1] > y_max - 1 or x_min > curr_pixel[0] or y_min > curr_pixel[1]:
                next
            else:
                new_image_map[x_counter][y_counter] = image_map[int(curr_pixel[0])][int(curr_pixel[1])] 

    return new_image_map


# convert image to grayscale
img = Image.open('small.png').convert("L")
img = np.asarray(img)

image_width = img.shape[0]
image_height = img.shape[1] 

plt.subplot(1,2,1)
plt.title('Origin image')
plt.imshow(img, cmap='gray', vmin=0, vmax=255)

plt.subplot(1,2,2)
plt.title('Transformed image')


alpha = 0

while True:
    rotation_angle = 0 + alpha
    alpha = alpha + 1 # increate 1 degree
    rotation_angle = np.deg2rad(rotation_angle) # degree to radian

    rotation_matrix = GetRotateMatrixWithCenter(image_width / 2, image_height / 2, rotation_angle)

    roteated = Apply_Matrix_To_Image(rotation_matrix, img)

    plt.imshow(roteated, cmap='gray', vmin=0, vmax=255)
    plt.pause(0.001)

plt.show()

更新的内容:

  1. 使用np.deg2rad()将度转换为弧度
  2. 使用matplotlib实时绘制旋转图像以进行调试
  3. 使用https://math.stackexchange.com/questions/2093314,可在图片中心旋转

运行屏幕:

Screen