1

Hello I want to ratate image with only using trigonometric functions.

Assume "q" as a "theta"

y'=x*sin(q) + y(-tan(q/2))*sin(q)+y

x'=x+2y(-tan(q/2)) + xsin(q)(-tan^2(q/2)) + y

x' and y' is going to be our new x and y values.

I am quite new in image proccesiing but i wrote a code which i think is kind of right.

In this example "theta" is considered "30 degrees" but i will develop the code and it will work for any other degrees...

So basically, I want from u to find my misake or if the code is totally wrong show me to right way to do it, please.

im1=zeros(64*64);

subplot(1,2,1);
imshow(im1);

[x,y]=size(im1);
    
%Let theta=30 degrees

for i=1:64
    for j=1:64
        
        x2(i,j)=x+2*y*(-tand(15))+ x*sind(30)*(-tand(15).^2)+y;
        
        y2(i,j)=x*sind(30)+y*(-tand(15))*sind(30)+y;

 % i'm not sure about where to put i and j, but i prefer like this.
        
    end
   
end

im2=[x2,y2];

subplot(1,2,2);
imshow(im2);
  • Have you ever debugged your code? Put a break point on very first line and run your code line by line to see if each line works as you expect. For example check size of variables, none of `im1` and `im2` will be `64 by 64`. – saastn Nov 01 '20 at 09:41

1 Answers1

2

Rotating Images Using Trigonometric Functions

Rotating an image can be done using trigonometric functions by decomposing the rotation matrix. The rotation matrix can be described as matrices and the corresponding code snippet below:

Rotattion Matrix

The code will iterate to populate the rotated image by evaluating the corresponding point in the original image. Some things to note is that padding the image with zeroes is required to allow for the picture not to be clipped after rotation. For a more detailed derivation of the rotation matrix please check out this post: How do rotation matrices work?

Code Snippet:

X_Displacement = Row - X_Midpoint;
Y_Displacement = Column - Y_Midpoint;

X_Prime = X_Displacement*cosd(Angle) + Y_Displacement*sind(Angle); 
Y_Prime = -X_Displacement*sind(Angle) + Y_Displacement*cosd(Angle);

In the above code snippet cosd() and sind() are used so that angles can be accepted in terms of degrees. If you'd like to alternatively use radians use the standard cos() and sin() functions. Here nearest-neighbour interpolation is applied when round() is used. This is due to the nature of rotating an image. A small case is rotating a 3 by 3 image. This brings an issue to light where you essentially can only pivot the pixels surrounding the centre pixel in 9 different ways which not representative of all the possible angles.

Rotated Image Figure 1 Exported Image with Transparency:

Exported Image with Transparency

For Greyscale Images:

clear;
Angle = 30;

[Original_Image] = imread("cameraman.tif");
subplot(1,2,1); imshow(Original_Image);
title("Original Image");

[Image_Height,Image_Width] = size(Original_Image);

%Padding Image%
Padding_Bottom_And_Top = zeros(round(Image_Height/2),Image_Width);
Side_Padding = zeros(Image_Height+2*size(Padding_Bottom_And_Top,1),Image_Width/2);
Padded_Image = [Padding_Bottom_And_Top; Original_Image];
Padded_Image = [Padded_Image; Padding_Bottom_And_Top];
Padded_Image = [Side_Padding Padded_Image];
Padded_Image = [Padded_Image Side_Padding];

[Padded_Image_Height,Padded_Image_Width] = size(Padded_Image);
Rotated_Image = zeros(Image_Height,Image_Width);

%Finding the centre points%
X_Midpoint = Padded_Image_Height/2;
Y_Midpoint = Padded_Image_Width/2;


for Row = 1: Padded_Image_Height
    for Column = 1: Padded_Image_Width
    
    X_Displacement = Row - X_Midpoint;
    Y_Displacement = Column - Y_Midpoint;
    
    X_Prime = X_Displacement*cosd(Angle) + Y_Displacement*sind(Angle); 
    Y_Prime = -X_Displacement*sind(Angle) + Y_Displacement*cosd(Angle);
    
    X_Prime = round(X_Prime + X_Midpoint);
    Y_Prime = round(Y_Prime + Y_Midpoint);

    if(X_Prime >= 1 && Y_Prime >= 1 && X_Prime <= Padded_Image_Height && Y_Prime <= Padded_Image_Width)
        Rotated_Image(Row,Column) = Padded_Image(X_Prime,Y_Prime);
    end

    
    end 
end

Rotated_Image = uint8(Rotated_Image);
subplot(1,2,2); imshow(Rotated_Image);
title("Rotated Image"); 

%Saving rotated image with transparency%
Transparent_Region = (Rotated_Image ~= 0);
Transparent_Region = uint8(255.*Transparent_Region);
imwrite(Rotated_Image,'Rotated.png','Alpha',Transparent_Region);

Rotated Image Figure 2 Exported Colour Image with Transparency:

Exported Colour Image with Transparency

For Coloured Images:

clear;
Angle = 30;

[Original_Image] = imread("peppers.png");
subplot(1,2,1); imshow(Original_Image);
title("Original Image");

[Image_Height,Image_Width,~] = size(Original_Image);

%Padding Image%
Padding_Bottom_And_Top = zeros(round(Image_Height/2),Image_Width,3);
Side_Padding = zeros(Image_Height+2*size(Padding_Bottom_And_Top,1),Image_Width/2,3);
Padded_Image = [Padding_Bottom_And_Top; Original_Image];
Padded_Image = [Padded_Image; Padding_Bottom_And_Top];
Padded_Image = [Side_Padding Padded_Image];
Padded_Image = [Padded_Image Side_Padding];

[Padded_Image_Height,Padded_Image_Width,~] = size(Padded_Image);
Rotated_Image = zeros(Image_Height,Image_Width,3);

%Finding the centre points%
X_Midpoint = Padded_Image_Height/2;
Y_Midpoint = Padded_Image_Width/2;


for Row = 1: Padded_Image_Height
    for Column = 1: Padded_Image_Width
    
    X_Displacement = Row - X_Midpoint;
    Y_Displacement = Column - Y_Midpoint;
    
    X_Prime = X_Displacement*cosd(Angle) + Y_Displacement*sind(Angle); 
    Y_Prime = -X_Displacement*sind(Angle) + Y_Displacement*cosd(Angle);
    
    X_Prime = round(X_Prime + X_Midpoint);
    Y_Prime = round(Y_Prime + Y_Midpoint);

    if(X_Prime >= 1 && Y_Prime >= 1 && X_Prime <= Padded_Image_Height && Y_Prime <= Padded_Image_Width)
        Rotated_Image(Row,Column,:) = Padded_Image(X_Prime,Y_Prime,:);
    end

    
    end 
end

Rotated_Image = uint8(Rotated_Image);
subplot(1,2,2); imshow(Rotated_Image);
title("Rotated Image"); 

%Saving rotated image with transparency%
Transparent_Region = (Rotated_Image(:,:,1) ~= 0);
Transparent_Region = uint8(255.*Transparent_Region);
imwrite(Rotated_Image,'Rotated.png','Alpha',Transparent_Region);

Ran using MATLAB R2019b

MichaelTr7
  • 4,737
  • 2
  • 6
  • 21
  • Thank u for your work, it's amazing. I want to learn something in detail. Padding image is new thing for me what is that part of code doing can u sum it? – Abdulkadir Arslan Nov 05 '20 at 05:50
  • 1
    @AbdulkadirArslan Yeah sure, padding the image is important when rotating the image since if you were to pivot an image say 45 degrees the corners would be cut-off. Padding the image with a bunch of black pixels before rotating gives us a margin that allows the image to be rotated without clipping any corners/edges. – MichaelTr7 Nov 05 '20 at 06:08
  • If you'd like more insight plotting the padded image with `imshow()` might give more perspective. – MichaelTr7 Nov 05 '20 at 06:09
  • You may also attempt to try to rotate the image without padding to get an idea of how clipping may occur. – MichaelTr7 Nov 05 '20 at 06:14
  • Hello again Michael, I was looking back to codes u wrote. I figured out that i didn't understand the most important part clearly. The 6 rows in the for loops. So, if you can elaborate this part for me I will be glad... X_Displacement = Row - X_Midpoint; Y_Displacement = Column - Y_Midpoint; X_Prime = X_Displacement*cosd(Angle) + Y_Displacement*sind(Angle); Y_Prime = -X_Displacement*sind(Angle) + Y_Displacement*cosd(Angle); X_Prime = round(X_Prime + X_Midpoint); Y_Prime = round(Y_Prime + Y_Midpoint); – Abdulkadir Arslan Dec 30 '20 at 21:44
  • To make it more clear... I actually didn't understand why we used X_Displacement = Row- X_Midpoint Why we used X_Midpoint there and what makes these lines X_Prime = round(X_Prime + X_Midpoint); Y_Prime = round(Y_Prime + Y_Midpoint); Thank u in advance. – Abdulkadir Arslan Dec 30 '20 at 22:09
  • @AbdulkadirArslan `X_Displacement = Row- X_Midpoint` is specifically used to find how far horizontally a given pixel is from the centre of the image. After transforming and getting the corresponding `X_Prime` (the position of the rotated pixel) we need to add the midpoint and round since we cannot guarantee the pixel position will land on a perfect pixel index. – MichaelTr7 Dec 31 '20 at 05:30
  • Not sure if you had the chance to check out the question: [How do rotation matrices work?](https://math.stackexchange.com/questions/716585/how-do-rotational-matrices-work). This shows a great derivation. – MichaelTr7 Dec 31 '20 at 05:31