乐趣区

关于图像处理:数图春季授课作业一几何变换

工作:

抉择典型图像(football.jpg)为钻研对象
1. 显示原图像
2. 将图像旋转 45°并进行显示(不调用自带函数,利用矩阵变换)

原理:

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

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

点 p 0绕坐标原点逆时针方向旋转 Θ 角度失去点 p 1

$$
\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 的零碎空间坐标设置,绕核心旋转能够统一化几何变换问题,原点旋转解决具备个体化)

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

(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…

总结:

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

程序运行后果:

退出移动版