问题
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);
回答1:
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:
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.
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);
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
来源:https://stackoverflow.com/questions/64630391/rotating-image-with-trigonometric-functions