【数字图像处理】(三)图像的几何变换

图像的几何变换

1 图像平移

图像平移就是将图像中所有的点按照指定的平移量水平或者垂直移动。

1.1 图像平移的变换公式

( x 0 , y 0 ) (x_0,y_0) (x0,y0)为原图像上的一点,图像水平平移量为 T x T_x Tx,垂直平移量为 T y T_y Ty,如下图所示:
在这里插入图片描述

则平移之后的点坐标 ( x 1 , y 1 ) (x_1,y_1) (x1,y1)变为:
在这里插入图片描述
在这里插入图片描述
这样,平移后的目标图像中的每一点都可以在原图像中找到对应的点。例如:对于新图中的 ( i , j ) (i, j) (i,j)像素,代入上面的方程组,可以求出对应原图中的像素 ( i − T x , j − T y ) (i-T_x, j-T_y) iTx,jTy。而此时如果 T x T_x Tx大于 i i i T y T_y Ty大于 j j j,则点 ( i − T x , j − T y ) (i-T_x, j-T_y) iTx,jTy超出了原图的范围,可以直接将它的像素值统一设置为0或者255。

对于原图中被移出图像显示区域的点通常也有两种处理方法,可以直接丢弃,也可以通过适当增加目标图像尺寸(将新生成的图像宽度增加 T x T_x Tx,高度增加 T y T_y Ty)的方法使得新图像中能够包含这些点。

1.2 MATLAB实现

MATLAB没有直接用于图像平移的函数,这里给出了一个基于灰度形态学的图像平移实现

A=imread('pout.tif');
% strel用来创建形态学结构元素
% translate(SE,[y,x]) 在原结构元素SE上进行y和x方向的偏移
%参数[80,50]可以修改,修改后平移距离对应改变
se=translate(strel(1),[80,50]);
% imdilate 形态学膨胀
B=imdilate(A,se);
figure
subplot(1,2,1),subimage(A);
title('原图像')
subplot(1,2,2),subimage(B);
title('图像平移')

结果:
在这里插入图片描述

平移后原图像之外的点算法直接采用黑色(0)填充,并丢弃了变换后目标图像中被移出图像显示区域的像素。

2 图像镜像

镜像变换又分为水平镜像和竖直镜像。水平镜像即将图像左半部分和右半部分以图像竖直中轴线为中心轴进行对换;而竖直镜像则是将图像上半部分和下半部分以图像水平中轴线为中心轴进行对换,如图4.4所示。
在这里插入图片描述

2.1 图像镜像的变换公式

水平镜像的变换关系为:
在这里插入图片描述

扫描二维码关注公众号,回复: 11932590 查看本文章

竖直镜像的变换关系可形式化地描述如下:
在这里插入图片描述

2.2 MATLAB编程实现

Imtransform()函数用于完成一般的二维空间变换,形式如下
在这里插入图片描述

  • 参数A为要进行几何变换的图像
  • 空间变换结构TFORM指定了具体的变换类型
  • 可选参数method允许为imtransform()函数选择的插值方法,其合法值如表4.1所示。

在这里插入图片描述
认时为双线性插值——’bilinear’。

函数输出B为经imtransform()变换后的目标图像。
可以通过两种方法来创建TFORM结构,即使用maketform()函数和cp2tform()函数。cp2tform是一个数据拟合函数,它需要原图像与目标图像之间的对应点对儿作为输入,用于确定基于控制点对儿的几何变换关系,下文的图像配准中将对它进行介绍;这里仅给出使用maketform()函数获得TFORM结构的方法。
在这里插入图片描述

  • 参数transformtype指定了变换的类型,如常见的’affine’为二维或多维仿射变换,包括平移、旋转、比例、拉伸和错切等。
  • Matrix为相应的仿射变换矩阵。

镜像变换程序的代码如下

A=imread('pout.tif');
[height,width,dim]=size(A);
tform=maketform('affine',[-1,0,0;0,1,0;width,0,1]);
% 定义水平镜像变换矩阵
B=imtransform(A,tform,'nearest');
tform2=maketform('affine',[1,0,0;0,-1,0;0,height,1]);
% 定义竖直镜像变换矩阵
C=imtransform(A,tform2,'nearest');
subplot(1,3,1),imshow(A);
title('原图像')
subplot(1,3,2),imshow(B);
title('水平镜像')
subplot(1,3,3),imshow(C);
title('竖直镜像')

结果:
在这里插入图片描述

3 图像转置

图像转置是将图像像素的x坐标和y坐标互换,如图4.6所示。图像的大小会随之改变——高度和宽度将互换。
在这里插入图片描述

3.1 图像转置的变换公式

转置变换的公式如下:
在这里插入图片描述

3.2 MATLAB编程实现

转置变换的实现程序如下

A=imread('pout.tif');
tform=maketform('affine',[0,1,0;1,0,0;0,0,1]);
% 定义转置变换矩阵
B=imtransform(A,tform,'nearest');
subplot(1,2,1),imshow(A);
title('原图像')
subplot(1,2,2),imshow(B);
title('图像转置')

结果:
在这里插入图片描述

4 图像缩放

图像缩放是指图像大小按照指定的比率放大或者缩小,如图所示:
在这里插入图片描述

4.1 图像缩放的变换公式

假设图像 x x x轴方向的缩放比率 S x , y S_x, y Sx,y轴方向的缩放比率 S y S_y Sy,相应的变换表达式为:
在这里插入图片描述
其逆运算如下:
在这里插入图片描述

直接根据缩放公式计算得到的目标图像中,某些映射原坐标可能不是整数,从而找不到对应的像素位置。例如:当 S x = S y = 2 S_x=S_y=2 Sx=Sy=2时,图像放大2倍,放大图像中的像素(0,1)对应于原图中的像素(0,0.5),这不是整数坐标位置,自然也就无法提取其灰度值。因此操作者必须进行某种近似处理,一种简单的策略是直接将它最邻近的整数坐标位置(0,0)或者(0,1)处的像素灰度值赋给它,这就是所谓的最近邻插值。

4.2 MATLAB编程实现

MATLAB提供了专门的图像缩放函数imresize(),具体调用形式如下。
在这里插入图片描述

  • 参数A为要进行缩放的原始图像。
  • Scale为统一的缩放比例
  • 可选参数method用于为imresize()函数指定的插值方法,其合法取值同imtransform()函数,但默认为最近邻插值。

输出B为缩放后的图像。

下面给出图像等比例缩放的MATLAB编程实现的代码

A=imread('pout.tif');
B=imresize(A,1.2,'nearest');
% 图像扩大1.2倍
figure
imshow(A);
title('原图像')
figure
imshow(B);
title('图像缩放')

结果:
在这里插入图片描述
如果希望在 x x x y y y方向上以不同比例进行缩放,可使用如下方式调用imresize()函数。
在这里插入图片描述
向量参数[mrows ncols]指明了变换后目标图像B的具体行数(高)和列数(宽),其余均与等比例缩放时的调用相同,这里不再赘述。

5 图像旋转

图像旋转一般是指将图像围绕某一指定点旋转一定的角度。旋转通常也会改变图像的大小。和图像平移的处理一样,可以把转出显示区域的图像截去,也可以改变输出图像的大小以扩展显示范围。

5.1 以原点为中心的图像旋转

如图所示,点 P 0 ( x 0 , y 0 ) P_0(x_0, y_0) P0(x0,y0)绕原点逆时针旋转角度 θ θ θ到点 P 1 ( x 1 , y 1 ) P_1(x_1,y_1) P1(x1,y1)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5.2 以任意点为中心的图像旋转

围绕任意的指定点来旋转,只需将平移和旋转操作相结合即可,即先进行坐标系平移,再以新的坐标原点为中心旋转,之后将新原点平移回原坐标系的原点。这一过程可归纳为以下3个步骤。
(1)将坐标系I变成II
(2)将该点顺时针旋转 θ θ θ
(3)将坐标系II变回I

以围绕图像中心的旋转为例,具体说明上述的变换过程。如图4.11所示,坐标系I以图像左上角点为原点,向右为x轴正方向,向下为y轴正方向;而坐标系II是以图像的中心为原点,向右为x轴正方向,向上为y轴正方向。
在这里插入图片描述
那么坐标系I与坐标系II之间的转换关系如何呢?
设图像的宽为 w w w,高为 h h h,则容易得到:
在这里插入图片描述
相应的逆变换为:
在这里插入图片描述
至此,操作者已经实现了上述3个步骤中的第1步和第3步,再加上第2步的旋转变换就得到了围绕图像中心点旋转的最终变换矩阵,该矩阵实际上是3个变换步骤中分别用到的3个变换矩阵的级联。
在这里插入图片描述
其中,Wold、Hold、Wnew、Hnew分别表示原图像和新图像的宽和高

上式的逆变换为:
在这里插入图片描述
这样就可以根据上面的逆变换公式,按照算法5.1中的描述来实现围绕图像中心的旋转变换。类似地,可以进一步得出以任意点为中心的旋转变换。

5.3 MATLAB编程实现

MATLAB提供了围绕图像中心的旋转变换函数imrotate()
在这里插入图片描述

  • A是要旋转的图像
  • angle为旋转角度,单位为度,如为其指定一个正值,则imrotate()函数按逆时针方向旋转图像。
  • 可选参数methodimrotate()函数指定的插值方法。
  • 'crop’选项会裁剪旋转后增大的图像,使得到的图像和原图大小一致。

下面给出图像旋转的MATLAB编码实现

A=imread('pout.tif');
% 最近邻插值法逆旋转30度,并剪切图像
B=imrotate(A,30,'nearest','crop');
subplot(1,2,1),imshow(A);
title('原图像')
subplot(1,2,2),imshow(B)
title('逆时针旋转30度')

在这里插入图片描述

6 插值算法

实现几何运算时,有两种方法。第一种称为向前映射法,其原理是将输入图像的灰度一个像素一个像素地转移到输出图像中,即从原图像坐标计算出目标图像坐标 g ( x 1 , y 1 ) = f ( a ( x 0 , y 0 ) , b ( x 0 , y 0 ) ) g(x_1,y_1)=f ( a(x_0,y_0), b(x_0,y_0) ) g(x1,y1)=f(a(x0,y0),b(x0,y0))。前面的平移、镜像等操作就可以采用这种方法

另外一种称为向后映射法,它是向前映射变换的逆,即输出像素一个一个地映射回输入图像中。如果一个输出像素映射到的不是输入图像的采样栅格的整数坐标处的像素点,则其灰度值就需要基于整数坐标的灰度值进行推断,这就是插值。由于向后映射法是逐个像素产生输出图像,不会产生计算浪费问题,所以在缩放、旋转等操作中多采用这种方法,书中采用的也全部为向后映射法。

6.1 最近邻插值

这是一种最简单的插值算法,输出像素的值为输入图像中与其最邻近的采样点的像素值。例如,图4.13中的点 P 0 P_0 P0在几何变换中被映射至点 P 1 ′ P_1' P1,但由于点 P 1 ’ P_1’ P1处于非整数的坐标位置,无法提取其像素灰度值。所以可以用与 P 1 ’ P_1’ P1最邻近的采样点P1的灰度值近似作为 P 1 ’ P_1’ P1的灰度值。
在这里插入图片描述
最近邻插值可表示如下
在这里插入图片描述

6.2 双线性插值

双线性插值又称为一阶插值,是线性插值扩展到二维的一种应用。它可以通过一系列的一阶线性插值得到。

注:线性(linear),指量与量之间按比例、成直线的关系,在数学上可以理解为一阶导数为常数的函数;线性插值则是指根据两个点的值线性地确定位于这两个点连线上的某一点的值。

输出像素的值为输入图像中距离它最近的2×2邻域内采样点像素灰度值的加权平均。

设已知单位正方形的顶点坐标分别为 f ( 0 , 0 ) 、 f ( 1 , 0 ) 、 f ( 0 , 1 ) 、 f ( 1 , 1 ) f(0,0)、f(1,0)、f(0,1)、f(1,1) f(0,0)f(1,0)f(0,1)f(1,1),如图4.14所示,本节要通过双线性插值得到正方形内任意点 f ( x , y ) f(x,y) f(x,y)的值。
在这里插入图片描述

首先对上端的两个点进行线性插值得到:
在这里插入图片描述
再对下端的两个顶点进行线性插值得到:
在这里插入图片描述
最后,对垂直方向进行线性插值得到:
在这里插入图片描述

整理得出:
在这里插入图片描述

6.3 高阶插值

在几何运算的一些情况中,双线性插值的平滑作用会使图像的细节退化,而其斜率的不连续性则会导致变换产生不希望的结果。这些都可以通过高阶插值得到弥补,高阶插值常用卷积来实现。输出像素的值为输入图像中距离它最近的4×4领域内采样点像素值的加权平均值。

下面以三次插值为例,它使用了如下的三次多项式来逼近理论上的最佳插值函数sin(x)/x,如图4.15所示。
在这里插入图片描述

在这里插入图片描述

上式中 ∣ x ∣ |x| x是周围像素沿 x x x方向与原点的距离。待求像素 ( x , y ) (x, y) (x,y)的灰度值由其周围16个点的灰度值加权插值得到。计算公式如下:
在这里插入图片描述

三次插值方法通常应用在光栅显示中,它在允许任意比例的缩放操作的同时,较好地保持了图像细节。

6.4 MATLAB实现

A=ones(80,40);
B=imrotate(A,30,'nearest');
C=imrotate(A,30,'bilinear');
D=imrotate(A,30,'bicubic');
% 图像旋转30度的插值方法比较
subplot(2,2,1),imshow(A);
title('原图像')
subplot(2,2,2),imshow(B);
title('最近邻插值')
subplot(2,2,3),imshow(C);
title('双线性插值')
subplot(2,2,4),imshow(D);
title('三次插值')

结果:

在这里插入图片描述
从图中可以看出最近邻的插值方法得到的结果还是可以接受的。但当图像中包含的像素之间灰度级有明显变化时,从结果图像的锯齿形边可以看出三种插值方法的效果依次递减,最近邻插值的效果明显不如另外两个好,锯齿比较多,而三次插值得出的图像较好地保持了图像的细节。这是因为参与计算输出点的像素值的拟合点个数不同,个数越多效果越精确,当然参与计算的像素个数会影响计算的复杂度。实验结果也清楚地表明:三次插值法花费的时间比另外两种的要长一些。最近邻和线性插值的速度在此次图像处理中几乎分不出来。所以,在计算时间与质量之间有一个折中问题。

内容来源
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_44378835/article/details/108954245