数图(春季授课)作业一——几何变换

任务:

选择典型图像(football.jpg)为研究对象
1.显示原图像
2.将图像旋转45°并进行显示(不调用自带函数,利用矩阵变换)
数图(春季授课)作业一——几何变换_第1张图片

原理:

(原文链接:https://blog.csdn.net/Bryan_Q...

以坐标原点为中心旋转的原理

点p0绕坐标原点逆时针方向旋转Θ角度得到点p1
数图(春季授课)作业一——几何变换_第2张图片

$$ \begin{bmatrix} cos(θ) & -sinθ & 0\\ sinθ & cos(θ) & 0 \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x_0\\ y_0\\ 1 \end{bmatrix} = \begin{bmatrix} x_1\\ y_1\\ 1 \end{bmatrix} $$

以任意图形中心点为坐标原点旋转原理

(这符合MATLAB的系统空间坐标设置,绕中心旋转可以统一化几何变换问题,原点旋转处理具有个体化)
数图(春季授课)作业一——几何变换_第3张图片

从上图可知,以任意图形中心为坐标原点旋转需要三步:

(1)将坐标系I变成坐标系II
注:坐标系I符合MATLAB的系统空间坐标设置,坐标系II中,图形中心是坐标原点。

$$ \begin{bmatrix} 1 & 0 & -0.5w\\ 0 & -1 & 0.5h \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} XI\\ YI\\ 1 \end{bmatrix} = \begin{bmatrix} XII\\ YII\\ 1 \end{bmatrix} $$

(2)将坐标系II旋转θ角

$$ \begin{bmatrix} cos(θ) & -sinθ & 0\\ sinθ & cos(θ) & 0 \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x_0\\ y_0\\ 1 \end{bmatrix} = \begin{bmatrix} x_1\\ y_1\\ 1 \end{bmatrix} $$

(3)将坐标系II变成坐标系I
注:MATLAB中只能以坐标系I的形式呈现图像,只能显示其x>0,y>0的部分。

$$ \begin{bmatrix} 1 & 0 & 0.5nW\\ 0 & -1 & 0.5nH \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} XII\\ YII\\ 1 \end{bmatrix} = \begin{bmatrix} XI\\ YI\\ 1 \end{bmatrix} $$

从而将三步结合起来,可以得到以任意图像中心为坐标原地旋转,最后呈现完整图像的变换矩阵:

前向映射

$$ \begin{bmatrix} 1 & 0 & 0.5nW\\ 0 & -1 & 0.5nH \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} cos(θ) & -sinθ & 0\\ sinθ & cos(θ) & 0 \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} 1 & 0 & -0.5w\\ 0 & -1 & 0.5h \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x_0\\ y_0\\ 1 \end{bmatrix} = \begin{bmatrix} x_1\\ y_1\\ 1 \end{bmatrix} $$

它的逆变换为:
后向映射

$$ \begin{bmatrix} x_0\\ y_0\\ 1 \end{bmatrix} = \begin{bmatrix} 1 & 0 & -0.5nW\\ 0 & -1 & 0.5nH \\ 0& 0 & 1 \end{bmatrix} \begin{bmatrix} cos(θ) & sin(θ) & 0\\ -sin(θ) & cos(θ) & 0 \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} 1 & 0 & 0.5w \\ 0 & -1 & 0.5h\\ 0& 0 & 1 \end{bmatrix} \begin{bmatrix} x_1\\ y_1\\ 1 \end{bmatrix} $$

向前映射和向后映射的区别

参考博客:[(4条消息) 图像变换——向前映射和向后映射_薇洛的打火机-CSDN博客](https://blog.csdn.net/glorydr...

总结:
数图(春季授课)作业一——几何变换_第4张图片
数图(春季授课)作业一——几何变换_第5张图片

MATLAB编程实现

(1)MATLAB自带函数实现图像任意角度旋转
旋转函数介绍:

B = imrotate(A,angle,method,bbox)
angle:旋转角度,单位为度,逆正顺负。
method:指定插值方法,邻点插值、双线性插值、双三次插值,(默认邻点插值)
bbox:定义输出图像大小的边界框

I=imread('football.jpg');
I1=imrotate(I,-45);                  %旋转45°
I2=imrotate(I,-45,'crop');           %旋转45°,并剪切图像,使得到的图像和原图像大小一致
I3=imrotate(I,-45,'bilinear','crop');%双线性插值法旋转45°,并剪切图像,使得到的图像和原图像大小一致
figure,subplot(2,2,1),imshow(I);
title('srcImage');
subplot(2,2,2),imshow(I1);
title('I1');
subplot(2,2,3),imshow(I2);
title('I2');
subplot(2,2,4),imshow(I3);
title('I3');
(2)自编myimrotate()函数实现图像任意角度旋转
function [ A ] = new_myimrotate(B,degree)                             %定义旋转函数,degree要旋转的角度
[h,w,d]=size(B);                                                      %获取输入图像B的行(高)h、列(宽)w和通道数d,为了旋转彩色图像所以有必要得到通道数d
nH=round(h*abs(cosd(degree))+w*abs(sind(degree)));                    %旋转图像后得到的新高度,“round()函数四舍五入“,“abs()函绝对值和复数的模”,“cosd()以度为单位的参数的余弦”
nW=round(w*abs(cosd(degree))+h*abs(sind(degree)));                    %旋转图像后得到的新宽度
A=zeros(nH,nW,d);                                                     %定义生成目标图像的行列以及通道数
M1=[1 0 -0.5*nW;0 -1 0.5*nH;0 0 1 ];                                   %坐标系变换矩阵M1
M2=[cosd(degree) sind(degree) 0;-sind(degree) cosd(degree) 0;0 0 1];  %角度旋转变换矩阵M2,我用的是顺时针方向
M3=[1 0 0.5*w;0 -1 0.5*h;0 0 1];                                      %坐标系变换矩阵M3
    for i=1:nW
        for j=1:nH
            temp=M1*M2*M3*[i;j;1];                                    %得到旋转前的矩阵temp
            y=temp(2,1);                                              %y取矩阵temp的第一行第二列,y对应j,为高度
            x=temp(1,1);                                              %x取矩阵temp的第一行第一列,x对应i,为宽度
            y=round(y);                                               %y四舍五入取整,邻近插值法
            x=round(x);                                               %x四舍五入取整,邻近插值法
           if(x>=1&&x<=w)&&(y>=1&&y<=h)                               %判断的得到的(x,y)点是否在原图像上
               A(j,i,:)=B(y,x,:);                                     %将原图像的像素点赋值给对应的旋转后图像上的点
           end                                                        %(”会疑惑为啥不是A(i,j,:)=B(x,y,:);因为i,x对应的是列,即宽,而j,y对应的是行,即高“)
        end                                                           %要弄清楚元素坐标与元素在矩阵中位置的转换关系
    end
end
主程序
I=imread('football.jpg');
I1=myimrotate(I,45);                %调用myimrotate()函数旋转45° 
I2=myimrotate(I,-45);               %调用myimrotate()函数旋转-45°
figure,subplot(1,3,1),imshow(I);
title('srcImage');
subplot(1,3,2),imshow(uint8(I1));   %matlab中读入图像的数据类型是uint8,而在图像矩阵运算的时候,使用的数据类型却是double类型
title('旋转45°:I1');
subplot(1,3,3),imshow(uint8(I2));
title('旋转-45°:I2');

程序运行结果:
数图(春季授课)作业一——几何变换_第6张图片

你可能感兴趣的:(图像处理)