0

我在仿射变换中正确旋转图像时遇到问题。目前以下是我正在使用的:

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
4

1 回答 1

2
# 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,与图像中心一起旋转

**运行画面:**

屏幕

于 2019-05-03T19:11:09.880 回答