热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

matlab之原始处理图像几何变换

(一)图像几何变换理论知识(1)图像的平移与比例图像的平移很简单,平移前后的坐标分别为(x,y)和(x’,y’),则满足的关系式为x

(一)图像几何变换理论知识

(1)图像的平移与比例

         图像的平移很简单,平移前后的坐标分别为(x,y)和(x’,y’),则满足的关系式为

              x’= x +Tx;

       y’= y +Ty;

其中Tx与Ty分别为对应的偏移量。 

图像的比例也很简单,可以描述为:x’=S_x * x;  y’=S_y * y;

那么上述的关系怎么用一个矩阵来表示呢?一个很重要的矩阵来了,那就是变换矩阵T,并且对于二维坐标下的点,一般转化为笛卡尔坐标系下进行计算,用一个三维点表示二维的,只不过把最后一项值置为1,这样一个二维坐标(x,y)就变为 (x,y,1)了。在把上述的平移等式关系转化为矩阵形式为:

 

比例等式关系为:


(2)关于旋转变换

对于某个点,在坐标系中的变换为(旋转角度为θ,并且逆时针旋转为正):

 

那么可以看出,这个时候对应的旋转矩阵为T就如图上所示。

(3)关于对称变换

对称变换比较简单,还是以点的变换为例,比如变换前的点P(x,y)和变换后的点P’=(x’,y’),那么对称变换包括点关于x轴、y轴、原点、y=x、y=-x等等,点的变换可以自己推导下,这样也就可以得到对应的变换矩阵T了。

比如,关于x对称的话,T=[1,0,0;0,-1,0;0,0,1],关于原点对称的话,T=[-1,0,0;0,-1,0;0,0,1];关于y=x对称的话,T=[0,1,0;1,0,0;0,0,1];等等。

(4)复合变换

下面再重点介绍下复合变换,因为有的变换不是简单的初等变换,但是有一点需要明确的是任何复合变换都可以用初等变换一步步变换而来。比如前面的旋转变换,旋转点选取的是原点,这样才有的那个公式,那要是旋转点不是原点怎么办?比如任一点s(X_f,Y_f),那么点P绕着点s旋转一定的角度θ该怎么表示呢?这里就要把这个复合变换化成为3个简单的初等变换,具体步骤为:首先把s点平移操作至原点(这个过程中,相当于所有的点都按照一定的方向平移了),然后相当于在原点对平移后的P点进行旋转变换,变换完后再把这个店反平移回去,这样是不是就相当于完成了那个复合变换。此时的变换矩阵为T,则T可以看出是两次平移矩阵T1、T2和一次旋转矩阵T3相乘的组合,即T=T1*T3*T2,注意方向不能反,因为是矩阵相乘,反的话相乘的结果不一定相同。

那么这个时候总的变换矩阵T就是:


这个在编程实现原点移动位置时至关重要。

几何变换的基础知识就说到这,具体的可以再找相关文章了解。

(二)matlab编程实现变换

(1)对图像的理解

        Matlab表示一副图像的方法很简单,对于灰度图像来说,就是一个二维矩阵,行与列存的就是像素点的位置,而矩阵值就是该像素点的灰度值。这里以有名的一副图lenna图为例,那么直接image=imread(‘lenna.jpg’)就可以加载带matlab工作框中,显示的话imshow(image)就可以了,显示如下:

 

(2)比例变换

了解了变换的基本原理,要知道其中最重要的就是关于坐标的变换。如果以上图中的行和列都为1的点作为原点的话,变换的程序为:

%-------------函数说明----------------
% 比例变换
% 输入变量:img 灰白图像(彩色不行)
% s_x x方向上的比例系数
% s_y y方向上的比例系数
%-------------------------------------
function bili(img,s_x,s_y)
[m,n] = size(img);
new_matrix = ones(m,n);
T1 = [s_x,0,0;0,s_y,0;0,0,1]; %对应的比例系数矩阵
for i=1:m
for j=1:n
p = floor([i,j,1]*T1^-1);%由P_new = P_old*T 可得:P_old = P_new*(T^-1)
if (p(1)<=m)&&(p(1)>0)&&(p(2)<=n)&&(p(2)>0) %限制范围
new_matrix(i,j) = img(p(1),p(2)); %坐标变换关系
else
new_matrix(i,j) = 0; %没有的点赋值为0
end
end
end
figure;imshow(new_matrix,[]);

这样运行对应程序:

bili(image,2,2):

 

bili(image,0.5,0.5):

 

可以看到,分别对图像扩大和缩小的时候,都是以行和列为1为原点来操作的。如果还是以这个点来进行旋转操作的话,就会非常不协调不好看。况且如果了解matlab本身自带这些旋转、比例操作函数的话会发现,这些函数操作原点是图像的正中心,这样操作起来后才很好看。那么现在的问题就是如何把图像的中心作为我们在坐标系下认为的原点呢?那就是上面讲到的三步走了,首先平移中心点至原点,再变换,再平移至中心点就好了。我们需要做的就是确定平移的行与列的长度(平移的长度应该是图像行与列总长度的一半吧,如果是把中心点当做原点的话)。基于此修改上述的程序如下:

function bili(img,s_x,s_y)
[m,n] = size(img);
new_matrix = ones(m,n);
T2 = [1,0,0;0,1,0;-m/2,-n/2,1]; %x、y轴平移值原点
T3 = [1,0,0;0,1,0;m/2,n/2,1]; %x、y轴反平移

T1 = [s_x,0,0;0,s_y,0;0,0,1]; %对应的比例系数矩阵
T = T2*T1*T3; %P_new = P_old*T2*T1*T3 顺序不能错了
for i=1:m
for j=1:n
p = floor([i,j,1]*T1^-1);%由P_new = P_old*T 可得:P_old = P_new*(T^-1)
if (p(1)<=m)&&(p(1)>0)&&(p(2)<=n)&&(p(2)>0) %限制范围
new_matrix(i,j) = img(p(1),p(2)); %坐标变换关系
else
new_matrix(i,j) = 0; %没有的点赋值为0
end
end
end
% figure;imshow(img,[]);
figure;imshow(new_matrix,[]);

从程序可以看出,只是多了那么两个矩阵而已就可以实现原点的转移了。

运行相应程序,bili(image,2,2):

 

bili(image,0.5,0.5):

 

可以看出,这样操作以后是不是协调多了,基本上和matlab自带的函数有相同的功能了。

(3)对称变换

   对称变换和上述变换差不多,无非修改相应的变换矩阵,程序如下:

%-------------函数说明----------------
% 对称变换
% 输入变量:img 灰白图像(彩色不行)
% num 对称类型
% 0:原点对称,1:x轴对称,2:y轴对称
% 3:y=x轴对称 4:y=-x轴对称 其他。。
%-------------------------------------
function duichen(img,num)
[m,n] = size(img);
new_matrix = ones(m,n);
T2 = [1,0,0;0,1,0;-m/2,-n/2,1]; %x、y轴平移值原点
T3 = [1,0,0;0,1,0;m/2,n/2,1]; %x、y轴反平移

T_x = [1,0,0;0,-1,0;0,0,1]; %x轴对称矩阵
T_y = [-1,0,0;0,1,0;0,0,1]; %y轴对称矩阵
T_o = [-1,0,0;0,-1,0;0,0,1]; %原点对称矩阵
T_yx = [0,1,0;1,0,0;0,0,1]; %y=x对称的矩阵
T_xy = [0,-1,0;-1,0,0;0,0,1]; %y=-x对称的矩阵
switch num %选择某一种对称方式
case 0
T = T2*T_o*T3 ;
case 1
T = T2*T_x*T3 ;
case 2
T = T2*T_y*T3 ;
case 3
T = T2*T_yx*T3 ;
case 4
T = T2*T_xy*T3 ;
end
for i=1:m %对于每一个像素点
for j=1:n
p = floor([i,j,1]*T^-1);%由P_new = P_old*T 可得:P_old = P_new*(T^-1)
if (p(1)<=m)&&(p(1)>0)&&(p(2)<=n)&&(p(2)>0) %限制范围
new_matrix(i,j) = img(p(1),p(2)); %坐标变换关系
else
new_matrix(i,j) = 0; %没有的点赋值为0
end
end
end
% figure;imshow(img,[]);
figure;imshow(new_matrix,[]);

运行相应程序:

>> duichen(image,0)

 

>> duichen(image,2)

 

(4)旋转变换

 %-------------函数说明----------------
% 旋转变换
% 输入变量:img 灰白图像(彩色不行)
% theat 变化的角度,逆时针旋转为正
%---------------------------------------
function xuanzhuan(img,theat)
[m,n] = size(img);
new_matrix = ones(m,n);
T2 = [1,0,0;0,1,0;-m/2,-n/2,1]; %x、y轴平移值原点
T3 = [1,0,0;0,1,0;m/2,n/2,1]; %x、y轴反平移

T1 = [cos(theat),sin(theat),0;-sin(theat),cos(theat),0;0,0,1];%旋转变换
T = T2*T1*T3; %P_new = P_old*T2*T1*T3 顺序不能错了
for i=1:m
for j=1:n
p = floor([i,j,1]*T^-1);%由P_new = P_old*T 可得:P_old = P_new*(T^-1)
if (p(1)<=m)&&(p(1)>0)&&(p(2)<=n)&&(p(2)>0) %限制范围
new_matrix(i,j) = img(p(1),p(2)); %坐标变换关系
else
new_matrix(i,j) = 0; %没有的点赋值为0
end
end
end
% figure;imshow(img,[]);
figure;imshow(new_matrix,[]);

运行相应程序:

>> xuanzhuan(image,pi/4)

 

>> xuanzhuan(image,-pi/3)

 

至此,一些基本的几何变换操作就完成了,其他的变换就在次基础上发挥了。

有一个问题是上述的变换在旋转的时候,原图的部分图像会被切割掉,这个是没有考虑到的,因为部分像素点在变换以后必然超出范围,对比matlab自带的旋转函数可以发现自带的函数是可以对出界的部分进行压缩到范围内。当然这一点我们也可以编程处理,不过稍微要麻烦点,必须对每个像素点再进行压缩处理,这个有待研究。

        二维图像的几何变换大致如此了。那么引申一下,对于三维图像的几何变换怎么处理了?其实归结到底还是有一个变换矩阵T,而这个矩阵不再是3*3的了,这个时候增加了一维,那么对应的矩阵也得增加一维变成4*4的了,维数的增加必然带来处理上的更加复杂了,不过理解了二维变换的原理,再来处理三维的话还是很好处理的,弄清楚对应关系就可以了。

 


推荐阅读
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 一、Hadoop来历Hadoop的思想来源于Google在做搜索引擎的时候出现一个很大的问题就是这么多网页我如何才能以最快的速度来搜索到,由于这个问题Google发明 ... [详细]
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 本文介绍了游戏开发中的人工智能技术,包括定性行为和非定性行为的分类。定性行为是指特定且可预测的行为,而非定性行为则具有一定程度的不确定性。其中,追逐算法是定性行为的具体实例。 ... [详细]
  • vue使用
    关键词: ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • Metasploit攻击渗透实践
    本文介绍了Metasploit攻击渗透实践的内容和要求,包括主动攻击、针对浏览器和客户端的攻击,以及成功应用辅助模块的实践过程。其中涉及使用Hydra在不知道密码的情况下攻击metsploit2靶机获取密码,以及攻击浏览器中的tomcat服务的具体步骤。同时还讲解了爆破密码的方法和设置攻击目标主机的相关参数。 ... [详细]
  • 如何基于ggplot2构建相关系数矩阵热图以及一个友情故事
    本文介绍了如何在rstudio中安装ggplot2,并使用ggplot2构建相关系数矩阵热图。同时,通过一个友情故事,讲述了真爱难觅的故事背后的数据量化和皮尔逊相关系数的概念。故事中的小伙伴们在本科时参加各种考试,其中有些沉迷网络游戏,有些热爱体育,通过他们的故事,展示了不同兴趣和特长对学习和成绩的影响。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 本文详细介绍了MysqlDump和mysqldump进行全库备份的相关知识,包括备份命令的使用方法、my.cnf配置文件的设置、binlog日志的位置指定、增量恢复的方式以及适用于innodb引擎和myisam引擎的备份方法。对于需要进行数据库备份的用户来说,本文提供了一些有价值的参考内容。 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
author-avatar
竹叶清2012
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有