Mikkel G Hansen
Mikkel G Hansen

Reputation: 77

Getting a incorrect picture output when running my self-made rotation algorithm

In order to better understand how image manipulation works, I've decided to create my own image rotation algorithm rather than using cv2.rotate() However, I'm encountering a weird picture cropping and pixel misplacement issue.

I think it may have something to do with my padding, but there may be other errors

import cv2

import math

import numpy as np
# Load & Show original image
img = cv2.imread('Lena.png', 0)
cv2.imshow('Original', img)

# Variable declarations
h = img.shape[0]  # Also known as rows

w = img.shape[1]  # Also known as columns

cX = h / 2 #Image Center X

cY = w / 2 #Image Center Y

theta = math.radians(100) #Change to adjust rotation angle

imgArray = np.array((img))

imgArray = np.pad(imgArray,pad_width=((100,100),(100,100)),mode='constant',constant_values=0) 
  #Add padding in an attempt to prevent image cropping

# loop pixel by pixel in image
for x in range(h + 1):

 for y in range(w + 1):

  try:
   TX = int((x-cX)*math.cos(theta)+(y-cY)*math.sin(theta)+cX) #Rotation formula 

   TY = int(-(x-cX)*math.sin(theta)+(y-cY)*math.cos(theta)+cY) #Rotation formula

   imgArray[x,y] = img[TX,TY]

  except IndexError as error:

   print(error)

cv2.imshow('Rotated', imgArray)

cv2.waitKey(0)

Edit:

I think the misplaced image position may have something to do with lack of proper origin point, however I cannot seem to find a functioning solution to that problem.

Upvotes: 2

Views: 109

Answers (1)

Geeocode
Geeocode

Reputation: 5797

Though I didn't dive in the math part of the domain, but based on the given information I think the matrix rotating formula should work like this:

UPDATE:

As I promised I dived a bit into the domain and got to the solution you can see as follows. The main trick that I've swapped the source and destination indices in the looping too, so the rounding doesn't mean any problem ever:

import cv2
import math
import numpy as np


# Load & Show original image
img = cv2.imread('/home/george/Downloads/lena.png', 0)
cv2.imshow('Original', img)


# Variable declarations
h = img.shape[0]  # Also known as rows
w = img.shape[1]  # Also known as columns

p = 120
h += 2 * p 
w += 2 * p

cX = h / 2 #Image Center X
cY = h / 2 #Image Center Y

theta = math.radians(45) #Change to adjust rotation angle

imgArray = np.zeros_like((img))  

#Add padding in an attempt to prevent image cropping
imgArray = np.pad(imgArray, pad_width=p, mode='constant', constant_values=0)   
img = np.pad(img, pad_width=p, mode='constant', constant_values=0)   

# loop pixel by pixel in image
for TX in range(h + 1):
    for TY in range(w + 1):
        try:
            x = int( +(TX - cX) * math.cos(theta) + (TY - cY) * math.sin(theta) + cX) #Rotation formula 
            y = int( -(TX - cX) * math.sin(theta) + (TY - cY) * math.cos(theta) + cY) #Rotation formula

            imgArray[TX, TY] = img[x, y]

        except IndexError as error:
           pass
#           print(error)

cv2.imshow('Rotated', imgArray)
cv2.waitKey(0)
exit()

enter image description here

Note: See usr2564301 comment too, if you want to dive deeper in the domain.

Upvotes: 2

Related Questions