简体   繁体   中英

Rotate Image in Affine Transformation

I am having trouble correctly rotating an image in an affine transformation. Currently the below below is what i'm using:

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]])

If I set the angle to anything greater than approximately 50 degrees I get an entirely black image without anything in it (I set the new image as entirely black, which indicates that none of the translated pixels are falling within the range of the new image). If i rotate less than 50 degrees I get some portion of the image, but it doesn't look correctly rotated from what I can tell. Also, origin 0,0 is in the top left corner. I want part of the image to be obscured if it is rotated outside of the bounds of the original image.

Prior to applying the the rotation, I am taking the inverse via

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

Where rotation occurs:

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
# 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()

Updated Contents:

  1. transform Degree to radian with np.deg2rad()
  2. Realtime draw rotated image with matplotlib for debug
  3. With https://math.stackexchange.com/questions/2093314 , roate with image center

Running screen:

屏幕

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM