Поворот изображения в аффинном преобразовании - PullRequest
0 голосов
/ 03 мая 2019

У меня проблемы с правильным поворотом изображения в аффинном преобразовании. В настоящее время я использую нижеприведенное ниже:

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 голосов
/ 03 мая 2019
# 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

...