图像的等距变换,相似变换,仿射变换,射影变换及其matlab实现

标签: matlab


source url: http://blog.csdn.net/u014096352/article/details/53526747


图像的等距变换,相似变换,仿射变换,射影变换及其matlab实现

  第二次写CSDN文档,上一篇的排版实在太烂了,于是决定认真学习一下markdown的语法。

  好了,废话不多说,今天,我们学习一下图像(2维平面)到图像(2维平面)的四种变换,等距变换,相似变换,仿射变换,投影变换 首先介绍它的原理,最后介绍matlab的实现

1.数学基础

射影变换矩阵H属于射影群PL(n)中的一个,仿射群是由PL(3)中最后一行为(0,0,1)的矩阵组成的子群,包括仿射群欧式群,其中欧式群是仿射群的子群,其左上角的矩阵是正交的,当它的行列式为1是称为定向欧式群,距离是欧式群的不变量,但不是相似群的不变量,而夹角是这两个群的不变量。

听了这么多群,不变量的数学概念,可能有点晕,下面我用最直观的语言解释。线性空间中的线性变换可以用矩阵来描述,因此我们用矩阵来刻画这四种变换。我们以数学系的经典代数入门教材北大版的《高等代数》为例,研究这些变换是如何进行的

这里写图片描述

2. 等距变换

等距变换(isometric transform),保持欧式距离不变,当图像中的点用齐次坐标表示时,变换矩阵如下所示:

xy1=εcos(θ)εsin(θ)0εsin(θ)εcos(θ)0txty1xy1

ε=1是保向的,ε=1是逆向的,等距变换可以更简单的写成
x=HEx=(R0t1)x

其中R是旋转矩阵。t是平移矢量,有3个自由度(1旋转角θ+两个平移tx,ty),需要2组点4个方程求解,等距变换的不变量是:长度,角度,面积。用matlab实现等距变换如下:
clear;close all;clc
I=imread('book1.jpg');
figure,imshow(I);
[w,h]=size(I);
theta=pi/4;
t=[100,100];
s=0.5;
% test Eucludian transform
H_e=projective2d([cos(theta) -sin(theta) t(1);
              sin(theta)  cos(theta) t(2);
                  0           0       1]');
newimg=imwarp(I,H_e);
figure,imshow(newimg);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
这里写图片描述

可以看出,等距变换就是对图像的旋转+平移

3. 相似变换

相似变换(similarity transform):等距变换+均匀缩放,当图像中的点用齐次坐标表示时,变换矩阵如下所示:

xy1=scos(θ)ssin(θ)0ssin(θ)scos(θ)0txty1xy1

s=1是保向的,s=1是逆向的,相似变换可以更简单的写成
x=HSx=(sR0t1)x

其中R是旋转矩阵。t是平移矢量,s是缩放尺度,有4个自由度(1旋转角θ+2个平移tx,ty+1个缩放尺度),需要2组点4个方程求解,相似变换的不变量是:角度,长度的比例,面积的比例。用matlab实现相似变换如下:
clear;close all;clc
I=imread('book1.jpg');
figure,imshow(I);
[w,h]=size(I);
theta=pi/4;
t=[100,100];
s=0.5;
%% test similar transform
H_s=projective2d([s*cos(theta) -s*sin(theta) t(1);
                  s*sin(theta)  s*cos(theta) t(2);
                     0           0       1]');
newimg=imwarp(I,H_s);
figure,imshow(newimg);

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
这里写图片描述

可以看出,等距变换就是对图像的旋转+平移+缩放,这个图相对原图是变小了一些。

4. 仿射变换

仿射变换(affine transform):非奇异变换+均匀缩放,当图像中的点用齐次坐标表示时,变换矩阵如下所示:

xy1=a11a210a12a220txty1xy1

仿射变换可以更简单的写成
x=HAX=(A0t1)x

其中A是仿射矩阵。t是平移矢量,s是缩放尺度,有6个自由度(4个仿射矩阵的元素+2个平移tx,ty),需要3组点6个方程求解。这里多说一句,仿射变换的A矩阵是可以做SVD分解的,即:
A=R(θ)R(ϕ)DR(ϕ)

D=diag(λ1,λ2)仿射变换A可以看作是一个旋转ϕ+x,y方向按照比例因子λ1,λ2的缩放+回转ϕ+旋转θ的复合变换,
仿射变换的不变量是:平行线,平行线的长度的比例,面积的比例。用matlab实现仿射变换如下:
clear;close all;clc
I=imread('book1.jpg');
figure,imshow(I);
[w,h]=size(I);
theta=pi/4;
t=[100,100];
s=0.5;
%% test affine transform
H_a=projective2d([1 0.5 t(1);
                 0 0.5 t(2);
                 0 0  1]');
newimg=imwarp(I,H_a);
figure,imshow(newimg);

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
这里写图片描述

可以看出,仿射变换就是对图像的旋转+平移+缩放+切变(shear),相比前两种变换图像的形状发生了改变,但是原图中的平行线仍然保持平行。

5. 射影变换

射影变换(projection transform):当图像中的点的齐次坐标的一般非奇异线性变换。有些文献中把射影变换矩阵称为单应性矩阵变换矩阵如下所示:

xy1=h11h21h31h12h22h32h13h231xy1

仿射变换可以更简单的写成
x=HAX=(AvTtv)x

其中A是旋转矩阵。t是平移矢量,s是缩放尺度,有8个自由度(矩阵中的8个h),需要4组点8个方程求解。同样的,射影变换的A矩阵是可以做分解的,QR分解,SVD分解都有各自不同的含义。我们常说的矩阵内外参数矩阵就是QR分解中的一种(QR分解不唯一),即把单应性矩阵分解成=内参矩阵×外参矩阵 。给定世界坐标系中的二维平面,用相机对二维平面拍照,通过对应点求拍摄照片的单应性矩阵(射影矩阵)的过程就称为相机标定,直接用代数的方法求解参数会有一定的误差,在张正友的标定方法中,讲的就是如何通过迭代使得误差最小。具体可以见我写的第一篇文章张正友相机标定法。对一般的两张照片也可以求单应性矩阵,具体的应用就是把其中的一张变换到另一张上,进一步可以做图像融合。
射影变换的不变量是:长度的交比。用matlab实现射影变换如下:
clear;close all;clc
I=imread('book1.jpg');
figure,imshow(I);
[w,h]=size(I);
theta=pi/4;
t=[100,100];
s=0.5;
%% test projective transform
H_P=projective2d([0.765,-0.122,-0.0002;
                 -0.174,0.916,9.050e-05;
                  105.018,123.780,1]);
newimg=imwarp(I,H_P);
figure,imshow(newimg);

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
这里写图片描述

可以看出,射影变换就是对图像的旋转+平移+缩放+切变+射影,相比前三种变换图像的形变更为自由,原图中的平行线经过变换之后已经不在平行,而可能相交于一点,射影变换就是把理想点(平行直线在无穷远处相交)变换到图像上。

6 应用

说了这么多,下边举一个简单的小应用,就是把通过求两幅对应点的单应性矩阵(射影矩阵),把一种图片变换成另一张的形状。如图:
选择两幅图像对应的四个点
第一幅

第一幅

第二幅

这里写图片描述

变换的结果

这里写图片描述
这样就成功把第二幅图片变成第一副图片的角度
下面附上代码
%% Initial
clear;
clc;
img_num=2;  %the number of image
compress_scale=0.4;  %define image compress scale
points_p=[0 0;1 0;2 1;2 0]; %define cordinate of 2D plain in 3D space 


%% define a cell that load image

Image=cell(1,img_num);

%% read the image
Image{1,1}=imread('book1.jpg');
Image{1,2}=imread('book2.jpg');

%% image compression, transform rgb to gray, and select feature points   
feature=[];
for i=1:img_num
    Image{1,i}=imresize(Image{1,i},compress_scale);
    I{:,:,i}=Image{1,i};
    Image{1,i}=rgb2gray(Image{1,i});
    imshow(Image{1,i});
    hold on;
    for j=1:4
        [x,y]= ginput(1);        %select the corner
        x=round(x);
        y=round(y);
        plot(x,y,'ro');
        feature(j,2*i-1)=x;     %feature is a matrix containing corner cordination 
        feature(j,2*i)=y;
    end
    close all;
end       

%% calculate homegraphy matrix for each matrix
featurep1=feature(:,1:2);
featurep2=feature(:,3:4);
h = calc_homography(featurep2, featurep1);
Im=I{:,:,2};

[a,b]=size(I);
tform=projective2d(h);
J=imwarp(Im,tform);    % matlab自带的处理图像变换的函数
figure,imshow(I{:,:,1});
figure,imshow(I{:,:,2});
figure,imshow(J)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

函数calc_homegraphy的代码如下:

function T = calc_homography(points1, points2)

    xaxb = points2(:,1) .* points1(:,1);
    xayb = points2(:,1) .* points1(:,2);
    yaxb = points2(:,2) .* points1(:,1);
    yayb = points2(:,2) .* points1(:,2);

    A = zeros(size(points1, 1)*2, 9);
    A(1:2:end,3) = 1;
    A(2:2:end,6) = 1;
    A(1:2:end,1:2) = points1;
    A(2:2:end,4:5) = points1;
    A(1:2:end,7) = -xaxb;
    A(1:2:end,8) = -xayb;
    A(2:2:end,7) = -yaxb;
    A(2:2:end,8) = -yayb;
    A(1:2:end,9) = -points2(:,1);
    A(2:2:end,9) = -points2(:,2);

    [~,~,V] = svd(A);
    h = V(:,9) ./ V(9,9);
    T= reshape(h,3,3);
end

版权声明:本文为helei001原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/helei001/article/details/78041929

智能推荐

matlab、opencv、pytorch实现仿射变换

matlab opencv 需要自己平移 pytorch 和直觉相反,仿射变换矩阵应为A的逆。需要缩放平移才能显示完全...

图像仿射变换python实现

写文章不易,如果您觉得此文对您有所帮助,请帮忙点赞、评论、收藏,感谢您! 一. 仿射变换介绍:     请参考:图解图像仿射变换:https://www.cnblogs.com/wojianxin/p/12518393.html                   图像...

Docker-Compose部署nginx 和lnmp

Docker-Compose tomcat lnmp tomcat 使用Docker-Compose部署Nginx代理Tomcat集群,实现负载均衡 在这个目录下创建多个目录 切换到nginx目录修改nginx的主配置文件: [root@host1 compose]# cd nginx/ [root@host1 nginx]# vim default.conf 在末尾添加: 修改: 切换到tmca...

19-20年月度行业分析

Table of Contents 1  对各一级行业分析 2  对女装行业进行分析 对各一级行业分析 platform cid industry category themonth 销售额 访客 客群指数 行业简称 月 年 年月 0 天猫 50010368 ZIPPO/瑞士军刀/眼镜 太阳眼镜 2020-01-01 62484514.13 6663217 ...

Python数据分析入门

博客原文:https://ouduidui.cn/blog/detail?blogId=5fcddf5c61ae700fd80190db 基础知识 数据的分类 数值型数据 表示大小或多少的数据 例子:年龄、年购买量 数值型数据分析方法 最小值和最大值:查看这两个值的目的是为了能够确定一组数据的上界和下界。 **平均值:**平均值可以反映一组数据的综合水平。 **中位数:**中位数和平均数一样都是用...

猜你喜欢

1.Java基础入门 -(10)流程控制-循环嵌套结构

什么是循环嵌套? 循环嵌套就是在循环体内,包含一个完成的循环结构。(我们在if嵌套里讲过) 示例1:使用双重循环输出九九乘法表。 运行结果: 示例2:请打印直角三角形。 (这里用 . 代替 空格 方便演示) 运行结果: 示例3:请打印等腰三角形。 运行结果: 示例4:请输出1-100之间的素数。 质数又称为素数,是一个大于1的自然数,除了1和它自身外,不能被其他自然数整除的数叫做质数;否则称为合数...

AlertDialogDemo自定义使用方法

效果图如下: Dialog左边的按钮忘记支付密码写错了 已修复 图就不改了 功能需求点击重试 再次打开输入支付密码页面 点击忘记支付密码跳转密码设置页面 此Demo只为演示AlertDialog的使用方法以及资源属性设置 需要其他功能请留言说明 这是一个支付密码输入失败的弹框 自定义了基本属性 XMl布局dialog_common 圆角框的属性commen_dialog_bg Styledialo...

2020网鼎杯---Java文件上传wp

前言 一篇文章读懂Java代码审计之XXE看过我这篇博客应该不难,没看过建议在看看。 题解 下载了所有的class发现需要上传xlsx poi 开头必须是execl 新建execl -1.xlsx文件,修改后缀名execl -1.xlsx.zip解压。 修改[Content-Types].xml 重新打包成excel-1.xlsx,文件名一定不能错。 在服务器上新建一个evil.etd文件。 然后...

关于串口数据接收出错问的问题(RS232、RS422、UART)

这两天调试串口驱动,串口驱动应该是很简单的啊,但是发现数据接收的时候,总是偶尔会出现错误,经过不断的排查,终于找到了问题的关键所在。 一段串口的verilog代码如下: 如果采样上面的方式对串口数据进行接收,就会发现串口数据总是偶尔出现个别的数据接收出错。通过ila抓波形,发现有如下图一的异常情况出现,这个时候uart_rx_i已经拉低了,但是却没有检测到下降沿,就会导致数据接收出错,这是由于亚稳...

入侵别人电脑后你必须要会的Linux与window系统用命令行下载网络资源的15种方式

我花了一天时间精心整理本文,有百度的经典方案,有老师的精心传授,也有自己的实践总结,如果觉得有用就转发收藏吧️别忘点赞哦这样可以帮助到更多的人 window系统常见下载方式 FTP脚本 vbs脚本 bitsadmin命令 $client命令 Linux系统常见下载方式 wget curl lynx fetch Axel aria2 youtube-dl 双方均可用 links links2 pyt...