本节我们总结一下数字图像的几何变换,区别于前面几种操作(白平衡,灰度变换,空间滤波)针对于像素强度,几何变换主要针对像素的位置。
对空间的操作主要包括仿射(线性)变换(平移,旋转,伸缩,剪切)和投影变换。每种变换方法的具体细节不展开阐述,就是把对像素(变量)的操作提取出来作为变换矩阵(其实也就是线性代数中的线性变换,推荐B站从空间几何的角度理解线性代数:https://b23.tv/BV1ys411472E/p1)。每个矩阵对应一种变换空间,如果进行多种叠加操作就是对应矩阵不断左乘,多个线性空间不断作用的结果。
仿射变换
平移,旋转,伸缩是严格的2D线性变换,是刚体变换(本身的形态不发生变换),剪切可以保证图中的平行线不变。2D线性变换中的变量有6个,也就是自由度DOF=6。
2D线性变换通项如下:
具体来说:
(图中的旋转对应逆时针旋转)
投影变换
(投影变换中不保证平行线仍然平行)投影变换对应原来的线性变换再除以一个线性变换,投影变换矩阵中前两行对应线性变换中的参数,这样可以用该3 X 3的矩阵统一线性变换及投影变换,当最后一行为[0 0 1]时就是线性变换。
图像插值
由图像几何变换带来一个问题就是变换之后的像素值可能不是一个整数,而我们所使用的像素值一般是整数,所以需要近似来解决。插值的关键思想就是保证变换后的像素点和最近的邻居最相似,最远的邻居最不相似,考虑的邻居越多,图像越光滑。一般插值方法有以下几种:
下面解释一下双线性插值的思路:
由上图知双线性插值使用了4个相邻的点,假设为a, b, c, d,经过变换后x落入abcd区间内,用经过x的横纵线将该区间分块,分别得到1,2,3,4四个点。
1点处的像素值由a, b两点决定,并且应该和b最相近,所以给b的权值应该更大,x1=(1-α)a+αb,类似的,我们可以得到x2=(1-β)a+βc,x3=(1-β)b+βb,x4=(1-α)c+αd。
相似地,x的像素值可以由23决定也可以由14决定,得到的结果是一样的。
x=(1-β)x1+βx4=(1-α)x2+αx3
应用及例子
本节内容最直接的例子就是图像的配准。
再举个几何变换的具体栗子:将图像顺时针旋转35度,x方向伸缩变换比例为0.6,平移50,y方向伸缩变换比例为0.8,平移15。
作出结果如下(左图是原图,右图是变换后的图)
参考代码(虽然代码比较简单,但是里面有很多容易犯错的地方,主要是matlab的定义方式略有不同)另:默认的插值方法是线性插值
addpath('E:\Digital_img_processing\Lecture_7_dicussion_geometry'); fig=imread('zombie.jpg'); rotate=[cosd(-35) sind(-35) 0; -sind(-35) cosd(-35) 0; 0 0 1]; % 围绕原点逆时针旋转-35度 scale=[0.6 0 0; 0 0.8 0; 0 0 1]; shift=[1 0 50; 0 1 15; 0 0 1]; tf=affine2d((shift*scale*rotate)'); % 需要转置 output=imwarp(fig,tf); figure;imshowpair(fig,output,'montage'); axis on; xlabel x; ylabel y;
总结(易出错的地方)
① matlab中几何变换矩阵是我们定义的变换矩阵的转置,这与其具体实现有关,所以记得转置
(affine2d函数官方文档)
② matlab中图像坐标系统与图像的坐标相反,如一般数字图像原点在左上角,x轴向下,y轴向右,而matlab中y轴向下,x轴向右。这导致我们需要使用定义的顺时针操作来实现逆时针,如栗子中的rotate变换定义。
③ 还有一个没提到的问题就是根据变换矩阵推出进行了哪些变换操作(也就是上述操作的逆过程):
以一个matlab中的变换矩阵为例:
该矩阵是变换矩阵的转置,平移很好看出来就是(-87.5517, 301.3816),而伸缩和旋转是叠加的,利用变换前后的不变性sin2θ+cos2θ=1或者tanθ得到。θ=arctan(-0.7969/0.4853 = -58.6596°)
④ 弧度制问题,matlab中角度制函数后面比弧度制通常多一个d (degree), 如弧度制:cos() 角度制:cosd()。弧度->角度:rad2deg() 角度->弧度:deg2rad()。
ref:
matlab中的图像坐标系统: https://blog.csdn.net/Enjolras_fuu/article/details/66530196
来源:https://www.cnblogs.com/pear-linzhu/p/12557368.html