【问题标题】:Rotating image with trigonometric functions使用三角函数旋转图像
【发布时间】:2020-11-01 09:27:59
【问题描述】:

您好,我想只使用三角函数来评估图像。

假设“q”为“theta”

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

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

x' 和 y' 将成为我们的新 x 和 y 值。

我是图像处理方面的新手,但我写了一个我认为是正确的代码。

在本例中,“theta”被认为是“30 度”,但我将开发代码,它适用于任何其他度...

所以基本上,我希望你能找出我的错误,或者如果代码完全错误,请告诉我正确的方法。

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

【问题讨论】:

  • 你调试过你的代码吗?在第一行设置一个断点并逐行运行您的代码,以查看每一行是否按预期工作。例如检查变量的大小,im1im2 都不是64 by 64

标签: matlab image-processing trigonometry image-rotation


【解决方案1】:

使用三角函数旋转图像

可以使用三角函数通过分解旋转矩阵来旋转图像。旋转矩阵可以用矩阵来描述,对应的代码sn-p如下:

代码将通过计算原始图像中的对应点进行迭代以填充旋转后的图像。需要注意的一点是,需要用零填充图像,以使图片在旋转后不被剪裁。有关旋转矩阵的更详细推导,请查看此帖子:How do rotation matrices work?

代码片段:

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

在上面的代码中,使用了sn-p cosd()sind(),以便可以接受角度的度数。如果您想使用弧度或者使用标准的cos()sin() 函数。当使用round() 时,这里应用最近邻插值。这是由于旋转图像的性质。一个小机箱正在旋转 3 x 3 图像。这带来了一个问题,您基本上只能以 9 种不同方式旋转中心像素周围的像素,这些方式不能代表所有可能的角度。

导出的透明图片:

对于灰度图像:

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

导出的透明彩色图像:

对于彩色图像:

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

使用 MATLAB R2019b 运行

【讨论】:

  • 感谢您的工作,太棒了。我想详细了解一些东西。填充图像对我来说是新事物,那部分代码在做什么你能总结一下吗?
  • @AbdulkadirArslan 是的,当然,在旋转图像时填充图像很重要,因为如果您将图像旋转 45 度,那么角落将被切断。在旋转之前用一堆黑色像素填充图像会给我们一个边距,允许图像在不剪裁任何角/边缘的情况下旋转。
  • 如果您想更深入地了解使用imshow() 绘制填充图像可能会提供更多视角。
  • 您也可以尝试在没有填充的情况下旋转图像,以了解可能会发生剪切的情况。
  • 你好,迈克尔,我正在回顾你写的代码。我发现我没有清楚地理解最重要的部分。 for 循环中的 6 行。所以,如果你能为我详细说明这部分,我会很高兴... X_Displacement = Row - X_Midpoint; Y_Displacement = 列 - Y_Midpoint; X_Prime = X_Displacementcosd(Angle) + Y_Displacementsind(Angle); Y_Prime = -X_Displacementsind(Angle) + Y_Displacementcosd(Angle); X_Prime = 圆形(X_Prime + X_Midpoint); Y_Prime = round(Y_Prime + Y_Midpoint);
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-22
  • 1970-01-01
  • 2012-07-02
  • 1970-01-01
  • 2021-04-12
相关资源
最近更新 更多