图像处理入门2-图像与几何变换

图像变换

图像处理过程中经常存在着大小,位置,角度不同的图像,如果想统一的用一个标准处理,就需要图像变换将其变到需要的状态。常用的图像变换有平移、旋转、缩放、透视等。本章节主要讨论的就是这几种常用的变换方法。

一、基本变换

1.平移

平移意思是将物体从A点沿某个方向移动至B点,不改变物体的大小形状。如果在坐标系下,可以表示为沿着 x , y x,y x,y方向分别移动 △ x , △ y \triangle x,\triangle y x,y。用一个公式可以表示为:
x ′ = x + △ x y ′ = y + △ y x'=x+\triangle x \\ y'=y+\triangle y x=x+xy=y+y
其中 x ′ , y ′ x',y' x,y表示移动后位置, x , y x,y x,y表示移动前位置, △ x , △ y \triangle x,\triangle y x,y表示移动距离。

2.旋转

旋转是物体绕着某个中心点旋转某个角度的变换,如果用直角坐标系表示。旋转变换可以表示为:
x ′ = x ∗ c o s ( θ ) − y ∗ s i n ( θ ) y ′ = x ∗ s i n ( θ ) + y ∗ c o s ( θ ) x'=x*cos(\theta)-y*sin(\theta) \\ y'=x*sin(\theta)+y*cos(\theta) x=xcos(θ)ysin(θ)y=xsin(θ)+ycos(θ)
其中 x ′ , y ′ x',y' x,y表示旋转后位置, x , y x,y x,y表示旋转前位置, θ \theta θ表示旋转角度。

3.缩放

假设某点位置坐标在二维图像上沿 x x x轴放大 S x S_x Sx倍,沿 y y y轴放大 S y S_y Sy倍,那么变换后该店位置坐标为:
x ′ = S x ∗ x y ′ = S y ∗ y x'=S_x*x \\ y'=S_y*y x=Sxxy=Syy
其中 x ′ , y ′ x',y' x,y表示放大后位置, x , y x,y x,y表示放大前位置, S x , S y S_x,S_y Sx,Sy分别表示 x x x方向和 y y y方向放大系数。

二、认识提升

如果将上述几种变换做一些比较和扩展,那么变换的规律可以更深入的了解,对于熟练掌握和应用有很大好处。
首先前两个变换平移和旋转都不改变物体本身大小,改变的仅仅是位置,这类变换也被称为刚体变换,含义就是被变换的物体像刚体一样没有形变。从数学角度看,就是变换前后两点间的距离依旧保持不变。该变换是个线性变换,设刚体变换为 M M M,则变换可以表示为:
[ x ′ y ′ ] = M ∗ [ x y ] + [ △ x △ y ] \begin {bmatrix} x' \\ y'\end {bmatrix}=M*\begin {bmatrix} x \\ y\end {bmatrix}+\begin {bmatrix} \triangle x \\ \triangle y\end {bmatrix} [xy]=M[xy]+[xy]
那么变换前后保持距离不变,对于二维变换就是 d e t ( M ) = ∣ M ∣ = ± 1 det(M)=|M|=\pm1 det(M)=M=±1(思考一下为什么?),对于2维变换来说:
M = [ a b c d ] (1) M= \begin{bmatrix} a&b\\ c&d \end{bmatrix} \tag{1} M=[acbd](1)
det ⁡ ( M ) = ∣ a b c d ∣ = ± 1 (2) \det(M)= \begin{vmatrix} a&b\\ c&d \end{vmatrix}=\pm1 \tag{2} det(M)=acbd=±1(2)
我们先取 d e t ( M ) = 1 det(M)=1 det(M)=1这个分支看看,都是什么组成的,首先变换前后距离不变,假设点的位置向量是 P ⃗ = ( x , y ) \vec{P}=(x,y) P =(x,y),那么按照距离的内积表示:
变换前: d = < P ⃗ , P ⃗ > = ( x , y ) ( x , y ) T d=<\vec{P},\vec{P}>=(x,y) (x,y)^{T} d=<P ,P >=(x,y)(x,y)T
变换后: d ′ = < P ′ ⃗ , P ′ ⃗ > = ( x ′ , y ′ ) ( x ′ , y ′ ) T d'=<\vec{P'},\vec{P'}>=(x',y') (x',y')^{T} d=<P ,P >=(x,y)(x,y)T
这样就是: d = d ′ ⟹ ( x ′ , y ′ ) ( x ′ , y ′ ) T = ( x , y ) ( x , y ) T d=d'\Longrightarrow(x',y') (x',y')^{T}=(x,y) (x,y)^{T} d=d(x,y)(x,y)T=(x,y)(x,y)T
( M ∗ ( x , y ) T ) T ∗ ( M ∗ ( x , y ) T ) = ( x , y ) M T M ( x , y ) T = ( x , y ) ∗ ( x , y ) T (M*(x,y)^T)^T*(M*(x,y)^T)=(x,y)M^TM(x,y)^T=(x,y)*(x,y)^T (M(x,y)T)T(M(x,y)T)=(x,y)MTM(x,y)T=(x,y)(x,y)T,所以 M T M = I M^TM=I MTM=I
矩阵展开得到三个方程组成的方程组:

{ a 2 + c 2 = 1 a b + c d = 0 b 2 + d 2 = 1 \begin{cases} a^2+c^2=1\\ ab+cd=0\\ b^2+d^2=1\\ \end{cases} a2+c2=1ab+cd=0b2+d2=1

同时加入 det ⁡ ( M ) = 1 \det(M)=1 det(M)=1这个条件,具体将行列式展开就有: ( a ∗ d − b ∗ c ) = 1 (a*d-b*c)=1 (adbc)=1,我们得到4个参数,4个方程,但解不唯一,取一组常用解就是:
a = c o s ( θ ) , b = − s i n ( θ ) , c = s i n ( θ ) , d = c o s ( θ ) a=cos(\theta),b=-sin(\theta),c=sin(\theta),d=cos(\theta) a=cos(θ),b=sin(θ),c=sin(θ),d=cos(θ)
这是一个旋转矩阵 M = [ c o s ( θ ) − s i n ( θ ) s i n ( θ ) c o s ( θ ) ] M=\begin{bmatrix} cos(\theta)&-sin(\theta)\\ sin(\theta)&cos(\theta) \end{bmatrix} M=[cos(θ)sin(θ)sin(θ)cos(θ)]
θ = 0 \theta=0 θ=0时, M = [ 1 0 0 1 ] M=\begin{bmatrix} 1&0\\ 0&1 \end{bmatrix} M=[1001]是一个恒等变换。
如果时 det ⁡ ( M ) = − 1 \det(M)=-1 det(M)=1,这些方程的解组成的矩阵就是一个镜像旋转变换。这里篇幅所限,以后单独讨论。
所有这些都是正交变换。
在任意正交变换下不变的几何性质有:距离(长度)、角度、面积、对称性。
缩放变换不属于正交变换,它归类为仿射变换的一种,包括正交变换也属于仿射变换。仿射变换的性质:共线、平行、相交、线上点的顺序、中心对称等。回到缩放变换来,缩放变换的变换矩阵可以表示成:
[ x ′ y ′ ] = [ S x 0 0 S y ] [ x y ] \begin {bmatrix} x' \\ y'\end {bmatrix}=\begin{bmatrix} S_x&0\\ 0&S_y \end{bmatrix}\begin {bmatrix} x \\ y\end {bmatrix} [xy]=[Sx00Sy][xy]

上述平移、旋转、缩放等变换矩阵不满足齐次性,运算起来不方便,为此将欧式空间映射到仿射空间中变换,使得变换矩阵构成群元,这样具有封闭性,这个思维转变比较重要。

这样上述变换对应成
平移变换:
T = [ 1 0 △ x 0 1 △ y 0 0 1 ] T=\begin{bmatrix} 1&0&\triangle x\\0&1&\triangle y\\0&0&1\end{bmatrix} T=100010xy1
旋转变换:
T = [ c o s ( θ ) − s i n ( θ ) 0 s i n ( θ ) c o s ( θ ) 0 0 0 1 ] T=\begin{bmatrix} cos(\theta)&-sin(\theta)& 0\\sin(\theta)&cos(\theta)&0\\0&0&1\end{bmatrix} T=cos(θ)sin(θ)0sin(θ)cos(θ)0001
缩放变换:
T = [ S x 0 0 0 S y 0 0 0 1 ] T=\begin{bmatrix} S_x&0& 0\\0&S_y&0\\0&0&1\end{bmatrix} T=Sx000Sy0001
有了这种形式:平移、旋转、缩放矩阵乘法可以连乘,可以混合乘,很方便。
举例:平移变换: T 1 , T 2 T_1,T_2 T1,T2分别为: T 1 = [ 1 0 △ x 1 0 1 △ y 1 0 0 1 ] T_1=\begin{bmatrix} 1&0&\triangle x_1\\0&1&\triangle y_1\\0&0&1\end{bmatrix} T1=100010x1y11, T 2 = [ 1 0 △ x 2 0 1 △ y 2 0 0 1 ] T_2=\begin{bmatrix} 1&0&\triangle x_2\\0&1&\triangle y_2\\0&0&1\end{bmatrix} T2=100010x2y21
合成后还是一个平移变换(没有变坏掉 ^_^): T = T 1 ∗ T 2 = [ 1 0 △ x 1 + △ x 2 0 1 △ y 1 + △ y 2 0 0 1 ] T=T_1*T_2=\begin{bmatrix} 1&0&\triangle x_1+\triangle x_2\\0&1&\triangle y_1+\triangle y_2\\0&0&1\end{bmatrix} T=T1T2=100010x1+x2y1+y21
旋转矩阵 T 1 , T 2 T_1,T_2 T1,T2分别为: T 1 = [ c o s ( θ 1 ) − s i n ( θ 1 ) 0 s i n ( θ 1 ) c o s ( θ 1 ) 0 0 0 1 ] T_1=\begin{bmatrix} cos(\theta_1)&-sin(\theta_1)&0\\sin(\theta_1)&cos(\theta_1)&0\\0&0&1\end{bmatrix} T1=cos(θ1)sin(θ1)0sin(θ1)cos(θ1)0001, T 2 = [ c o s ( θ 2 ) − s i n ( θ 2 ) 0 s i n ( θ 2 ) c o s ( θ 2 ) 0 0 0 1 ] T_2=\begin{bmatrix} cos(\theta_2)&-sin(\theta_2)&0\\sin(\theta_2)&cos(\theta_2)&0\\0&0&1\end{bmatrix} T2=cos(θ2)sin(θ2)0sin(θ2)cos(θ2)0001
合成后还是旋转矩阵:
T = T 1 ∗ T 2 = [ c o s ( θ 1 + θ 2 ) − s i n ( θ 1 + θ 2 ) 0 s i n ( θ 1 + θ 2 ) c o s ( θ 1 + θ 2 ) 0 0 0 1 ] T=T_1*T_2=\begin{bmatrix} cos(\theta_1+\theta_2)&-sin(\theta_1+\theta_2)&0\\sin(\theta_1+\theta_2)&cos(\theta_1+\theta_2)&0\\0&0&1\end{bmatrix} T=T1T2=cos(θ1+θ2)sin(θ1+θ2)0sin(θ1+θ2)cos(θ1+θ2)0001
缩放矩阵也是类似的,这里就不写了。
思考一下旋转和平移合成是什么结果?大家可以试试!

我们整理再扩展一下变换:
正交变换包含平移、旋转、镜像等变换;
相似变换=位似变换与正交变换的合成;
缩放变换包含相似变换、伸缩变换;
由伸缩变换延伸出错切变换;
相似变换、位似变换、伸缩变换、错切变换的共同性质是把共线三点映射成共线三点,且都为可逆变换,这个共同性质抽象出了仿射变换。
所以仿射变换包含正交变换、斜切变换、缩放变换、压缩、错切等变换。

而射影变换是更一般的线性变换,是射影平面到自身的映射,也就是射影平面上共线三点映射到射影平面共线三点的映射。(注意和仿射变换区别)

射影变换也叫透视变换、投影变换
变换矩阵表示为 M = [ A t c t 1 ] M=\begin{bmatrix} A&t\\ c^t&1 \end{bmatrix} M=[Actt1],可以看出射影变换的自由度为 n 2 − 1 n^2-1 n21
上述变换统一到变换群的框架中,从群的角度分类几何变换可以更清晰的理解其中的意义。
射影变换经常用于视觉校正中,方便观察和处理。这里过多不介绍了,以后再专门讲解。

三、应用

有了上述理论,将它用于实际中,更有意义,下面使用的是halcon软件演示的效果,不了解halcon的可以自行百度一下,halcon使用起来比较方便,容易上手。以后补充Opencv版的变换。


halcon中算子使用方法

  • 创建一个空的仿射变换矩阵
    hom_mat2d_identity (HomMat2DIdentity)
  • 设置平移矩阵
    hom_mat2d_translate (HomMat2DIdentity, T x T_x Tx, T y T_y Ty,HomMat2DTranslate)
  • 设置旋转矩阵 以 ( P x , P y ) (P_x,P_y) (Px,Py)为参考点进行旋转
    hom_mat2d_rotate (HomMat2DTranslate, θ \theta θ, P x P_x Px, P y P_y Py, HomMat2DRotate)
  • 设置缩放矩阵 以 ( P x , P y ) (P_x,P_y) (Px,Py)为参考点进行缩放
    hom_mat2d_scale (HomMat2DRotate, S x S_x Sx, S y S_y Sy, P x P_x Px, P y P_y Py, HomMat2DScale)
  • 求出投影变换算子
    hom_vector_to_proj_hom_mat2d( Px, Py, Pw, Qx, Qy, Qw, Method,HomMat2DScale)
  • 投影变换
    projective_trans_image (Image_display, Image_rectified, HomMat2D, ‘bilinear’, ‘false’, ‘false’)

1.平移变换

*读取图像
read_image (Image, 'C:/Users/DELL/Desktop/1.jpg')
*创建单元矩阵
hom_mat2d_identity (HomMat2DIdentity)
*创建平移矩阵移动150,200
hom_mat2d_translate (HomMat2DIdentity, 150, 200, HomMat2DTranslate)
*对图像做平移变换
affine_trans_image (Image, ImageRotate, HomMat2DTranslate, 'constant', 'false')

效果如下:

原始位置                              变换位置


2.旋转变换

*读取图像
read_image (Image, '2.jpg')
*创建单元矩阵
hom_mat2d_identity (HomMat2DIdentity)
*在单元矩阵上修改成旋转矩阵
hom_mat2d_rotate (HomMat2DIdentity, rad(30), 360, 500, HomMat2DRotate)
*应用矩阵做旋转变换
affine_trans_image (Image, ImageRotate, HomMat2DRotate, 'constant', 'false')

效果如下:

 
原图                              变换后



3.射影变换:

*关闭当前显示窗口,清空屏幕
dev_close_window ()
*读取图像
read_image (Image, 'image.jpg')
*将图像转为灰度图像,单通道
rgb1_to_gray (Image, GrayImage)
*获取图像的尺寸---宽imageWidth和高imageHeight
get_image_size(Image,imageWidth, imageHeight)
*新建窗口,适应图像尺寸,方便显示
dev_open_window (0, 0, imageWidth, imageHeight, 'black', WindowHandle1)
*显示图像,用于观察
dev_display (GrayImage)
*初始化角点坐标,相当于初始化数组,存放变换的角点
XCoordCorners := []
YCoordCorners := []
***************下面时图像处理,提取出变换的点*******************
*阈值处理,提取较暗的区域
threshold(GrayImage,DarkRegion,0, 80)
*分离不相连的区域
connection (DarkRegion, ConnectedRegions)
*选择面积最大的暗色区域,即屏幕区域
select_shape_std (ConnectedRegions, displayRegion, 'max_area', 70)
*裁剪屏幕区域
reduce_domain (GrayImage, displayRegion, displayImage)
*创建边缘轮廓
gen_contour_region_xld (displayRegion, Contours, 'border')
*将轮廓分割为边
segment_contours_xld (Contours, ContoursSplit, 'lines', 5, 4, 2)
*获取边的数量
count_obj (ContoursSplit, Number)
*存储每条边的起点位置
for index:=1 to Number by 1
   select_obj(ContoursSplit, ObjectCurrent, index)
   *拟合每条边
   fit_line_contour_xld (ObjectCurrent, 'tukey', -1, 0, 5, 2, RowBegin, ColBegin, RowEnd, ColEnd, Nr, Nc, Dist)
   *存储每条边的顶点x坐标
   tuple_concat (XCoordCorners, RowBegin, XCoordCorners)
   *存储每条边的顶点y坐标
   tuple_concat (YCoordCorners, ColBegin, YCoordCorners)
endfor
**************************************************************************
*****现在XCoordCorners和YCoordCorners是提取出的角点,分别保存x和y坐标,共四个点。
*****建立要变换到的目标的坐标
XOff:= 100
YOff:= 100*imageHeight/imageWidth

*****用提取的4个点和创建目标点构建仿射变换矩阵
hom_vector_to_proj_hom_mat2d (XCoordCorners, YCoordCorners, [1,1,1,1], [YOff,YOff,imageHeight-YOff,imageHeight-YOff], [XOff,imageWidth-XOff,imageWidth-XOff,XOff], [1,1,1,1], 'normalized_dlt', HomMat2D)
*对图像做投影变换
projective_trans_image (Image, Image_rectified, HomMat2D, 'bilinear', 'false', 'false')
* 显示校正结果
dev_display (Image_rectified)

效果如下:

 
原图                              变换后
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值