- 📢博客主页:https://loewen.blog.csdn.net
- 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!
- 📢本文由 丶布布原创,首发于 CSDN,转载注明出处🙉
- 📢现在的付出,都会是一种沉淀,只为让你成为更好的人✨
文章预览:
一. 基本几何变换
基本几何变换是指对图形的几何信息经过平移、缩放、旋转等操作后产生的新图形。这些变换通常包括相似变换、仿射变换和投影变换(畸变校正):
- 相似变换: 在平面或空间中,相似变换保持两个图形之间的每一对对应点之间的距离比不变。简单来说,就是将一个图形按照比例因子进行缩放、旋转和平移后,得到的新图形与原图形相似。这种变换常用于地图缩放等场合。。
- 仿射变换: 仿射变换也是在平面或空间中进行的线性变换,它保持两个图形之间的每一对对应点之间的距离比和直线上点之间的距离比不变。这意味着,除了平移、旋转和缩放外,仿射变换还包括剪切操作。这种变换(二维仿射变换)对于图像处理、计算机视觉等领域中的图像校正、图像配准等任务非常重要。
- 投影变换: 投影变换,也称为透射变换或投影映射,是将图像从一个视平面投影到另一个新的视平面的过程。这种变换不仅仅是二维坐标到二维坐标的变换,有时也涉及二维到三维的变换,尤其是在处理透视畸变时。透射变换是仿射变换的扩展,它允许图像在变换后形状发生较大改变,如边不再平行或发生透视畸变。这时,投影变换可以用于校正这些畸变,使其恢复原状或适应新的视角。这种变换在图像畸变校正等场合尤为重要。
二. 二维仿射变换
HALCON中常用几何变换是仿射和投影变换,下面重点介绍二维仿射变换:
1、维度: 发生在二维平面上,涉及x和y两个坐标轴。它主要用于处理二维图像或图形的变换,如平移、旋转、缩放和错切等。
2、矩阵形式
在数学上,仿射变换可以通过一个变换矩阵来表示。由于仿射变换包括线性变换(缩放,错切,旋转)和平移两部分 —— y = kx(线性变换) + b(平移),因此变换矩阵需要能够同时表示这两部分。
T
2
∗
3
=
[
a
b
p
c
d
q
]
(4)
T_{2*3} = \tag{4} \left [ \begin{matrix} a & b &p \\ c & d &q\\ \end{matrix}\right ]
T2∗3=[acbdpq](4)
T
1
=
[
a
b
c
d
]
;
T
2
=
[
p
q
]
;
(5)
T_1 = \tag{5} \left [ \begin{matrix} a & b\\ c & d\\ \end{matrix}\right ]; T_2 = \ \left [ \begin{matrix} p & q\\ \end{matrix}\right ];
T1=[acbd];T2= [pq];(5)
其中:
- T1:表示对图形进行缩放、旋转、剪切、对称等变换;
- T2:对图形进行平移变换;
在二维仿射变换中,我们通常使用2*3的矩阵来表示这种变换。这个矩阵的前两列T1(或前两行,取决于是左乘(2×3)还是右乘(3×2)矩阵)表示线性变换部分,而最后一列T2(或最后一行)则表示平移部分。
3、不同坐标系之间的点坐标变换
首先,我们需要明确一点:在线性变换中,矩阵与向量的乘法表示的是对向量进行线性变换。当我们说“从坐标系A到坐标系B的转换矩阵 MAB”时,我们实际上是在说,如果有一个在坐标系A中表示为向量 vA的点,那么它在坐标系B中的表示 vB可以通过:
v
B
=
M
A
B
×
v
A
v_B = M_{AB} × v_A
vB=MAB×vA
具体来说,对于一个二维点(x, y),经过仿射变换后的新坐标(x’, y’)可以通过以下矩阵乘法得到:
[ x ’ y ’ 1 ] = [ 1 0 a 0 1 b 0 0 1 ] [ x y 1 ] (7) \tag{7} \left [ \begin{matrix} x’ \\ y’ \\ 1 \end{matrix} \right ]= \left [ \begin{matrix} 1 & 0&a \\ 0 & 1&b \\ 0 & 0&1 \end{matrix}\right ] \left [ \begin{matrix} x \\ y \\ 1 \end{matrix} \right ] x’y’1 = 100010ab1 xy1 (7)
注意,这里我们使用了齐次坐标表示法,即在二维坐标的基础上增加了一个维度(通常为1),以便能够用矩阵乘法来表示平移。然而,在实际应用中,由于仿射变换矩阵的最后一行总是[0, 0, 1],因此在实际编写代码或进行计算时,通常只关注矩阵的前两行(或前两列)和平移部分,即2*3的矩阵形式。
4、组合变换
已知从坐标系A到B的矩阵变换MAB,坐标系B到C的矩阵变换MBC,可求坐标系A到C的矩阵变换:
M
A
C
=
M
B
C
×
M
A
B
M_{AC} = M_{BC} × M_{AB}
MAC=MBC×MAB
注意矩阵乘法的顺序,即“从右到左”地应用变换。这是因为,当我们说“从A到B再到C”时,实际上是先应用MAB将A中的向量转换到B中,然后再应用MBC将B中的向量转换到C中。在数学上,这对应于矩阵的连续乘法,其中右侧的矩阵先与向量相乘。
解释:“从右到左”地应用变换?
- 变换矩阵:
当我们谈论几何变换时,每个变换(如旋转、缩放、平移等)都可以用一个特定的矩阵来表示。例如,一个二维旋转矩阵可以围绕原点旋转一个角度θ,而一个缩放矩阵可以沿着x轴和y轴分别缩放物体。 - 矩阵乘法与变换顺序:
当你想要对一个对象应用多个变换时,你需要将这些变换的矩阵相乘。但是,这里的关键是理解矩阵乘法的顺序决定了变换的顺序。具体来说,当你计算 C=A×B 并用这个结果矩阵 C 去变换一个向量或点时,这个变换实际上是先应用 B 变换,然后应用 A 变换。 - “从右到左”的理解:
由于矩阵乘法是从左到右进行的(即先计算 A×B),但变换效果却是先B后A,因此我们可以说变换是“从右到左”地应用的。换句话说,当你写下一个变换序列的矩阵乘法时,最右边的矩阵会首先应用于对象,然后依次向左进行。
示例: 假设你有一个二维图形,你想要先将其绕原点旋转45度,然后沿x轴缩放2倍。
- 旋转45度的矩阵为R;
- 沿x轴缩放2倍的矩阵为S;
为了应用这两个变换,你需要计算 S×R 并用这个结果矩阵去变换图形。尽管在计算时你首先写的是 S 然后是 R(从左到右),但变换效果却是先旋转(R)后缩放(S),即“从右到左”地应用变换。
三. 投影变换
投影变换(如透视变换)与仿射变换不同,它涉及到三维空间到二维平面的投影过程,或者将二维图像投影到另一个视角的二维平面上。这种变换不再是线性的,因此不能用简单的2×3矩阵来表示。相反,透视变换通常使用3×3的矩阵来表示,该矩阵能够描述更复杂的变换关系,包括深度信息的改变和视角的变换。
T 3 ∗ 3 = [ a b p c d q m n s ] T_{3*3} = \left [ \begin{matrix} a & b &p \\ c & d &q\\ m & n& s \end{matrix}\right ] T3∗3= acmbdnpqs
T
1
=
[
a
b
c
d
]
;
T
2
=
[
m
n
]
;
T
3
=
[
p
q
]
;
T
4
=
[
s
]
;
(5)
T_1 = \tag{5} \left [ \begin{matrix} a & b\\ c & d\\ \end{matrix}\right ]; T_2 = \ \left [ \begin{matrix} m & n\\ \end{matrix}\right ]; T_3 = \ \left [ \begin{matrix} p & q\\ \end{matrix}\right ]; T_4 = \ \left [ \begin{matrix} s\\ \end{matrix}\right ];
T1=[acbd];T2= [mn];T3= [pq];T4= [s];(5)
其中:
- T1:表示对图形进行缩放、旋转、剪切、对称等变换;
- T2:对图形进行投影变换;
- T3:对图形进行平移变换;T4:对图形做整体比例变换;
四. 齐次坐标与齐次变换矩阵
4.1 齐次坐标 :点的坐标进行转置,然后扩1维 增加一个1
「齐次坐标」就是将一个原本是n
维的向量用一个n+1
维向量来表示。
- 二维坐标齐次化:二维点(x, y)变为(x, y, w)就成了齐次坐标;
- 三维坐标齐次化:三维点p(x, y, z)àp(x, y, z, w)也成了齐次坐标
w
作为通用比例因子,它可取任意正值,但一般在几何变换中,总是取w=1
,如果把一个「齐次坐标」转换成普通坐标,把前面坐标同时除以最后一个坐标,然后去掉最后一个分量。
4.1.1 为什么引入齐次坐标概念
使用齐次坐标与矩阵相乘的原因主要在于其能够更方便地表示和计算仿射变换(包括平移、旋转和缩放),而普通坐标则无法实现坐标的平移变换,只能通过矩阵乘法实现缩放和旋转,因为平移不是线性变换。
为了能够在矩阵乘法的框架下统一表示平移、旋转和缩放等变换,引入了齐次坐标的概念。通过引入齐次坐标,平移变换可以表示为一个3x3的变换矩阵与齐次坐标向量的乘法。
4.2 齐次变换矩阵
4.2.1 平移变换
以点p(x,y)
为例,如果想把它平移至p(x+a,y+b)
,是不可能用矩阵计算完成的,现在换成齐次坐标(x,y,1)
,通过矩阵相乘(左侧公式) ,很方便得到平移后的坐标(x+a,y+b)
。
写成矩阵的形式:
[ x y 1 ] [ 1 0 0 1 a b ] = [ x + a y + b ] (6) \left [ \begin{matrix} x & y & 1 \end{matrix} \right ] \left [ \begin{matrix} 1 & 0 \\ 0 & 1 \\ a & b \end{matrix}\right ] = \tag{6} \left [ \begin{matrix} x+a & y+b\\ \end{matrix} \right ] [xy1] 10a01b =[x+ay+b](6)
但通常不是上面的写法,而是把变换矩阵写到左侧,即左乘(实现矩阵行变换):
[
1
0
a
0
1
b
0
0
1
]
[
x
y
1
]
=
[
x
+
a
y
+
b
1
]
(7)
\left [ \begin{matrix} 1 & 0&a \\ 0 & 1&b \\ 0 & 0&1 \end{matrix}\right ] \left [ \begin{matrix} x \\ y \\ 1 \end{matrix} \right ] = \tag{7} \left [ \begin{matrix} x+a &y+b&1\\ \end{matrix} \right ]
100010ab1
xy1
=[x+ay+b1](7)
4.2.2 缩放变换
以点𝑝(𝑥,𝑦)
为例,如果想把它的x
和y
缩小10倍,现在换成齐次坐标(x,y,1
)T,缩放后的坐标(x/10, y/10
)
通过矩阵相乘(左侧公式),写成矩阵相乘的形式:
[
0.1
0
1
0
0.1
1
0
0
1
]
[
x
y
1
]
=
[
0.1
x
0.1
y
1
]
(8)
\left [ \begin{matrix} 0.1 & 0&1 \\ 0 & 0.1&1 \\ 0 & 0&1 \end{matrix}\right ] \left [ \begin{matrix} x \\ y \\ 1 \end{matrix} \right ] = \tag{8} \left [ \begin{matrix} 0.1x &0.1y&1\\ \end{matrix} \right ]
0.10000.10111
xy1
=[0.1x0.1y1](8)
4.2.3 旋转变换
旋转变换是线性变换的一种,通过旋转矩阵来实现。假设我们想对点𝑝(𝑥,𝑦)
进行逆时针旋转𝜃度,得到的新坐标,可以用如下的旋转矩阵来表示:
[
c
o
s
(
θ
)
−
s
i
n
(
θ
)
1
s
i
n
(
θ
)
c
o
s
(
θ
)
1
0
0
1
]
[
x
y
1
]
=
[
x
c
o
s
(
θ
)
−
y
s
i
n
(
θ
)
x
s
i
n
(
θ
)
+
y
c
o
s
(
θ
)
1
]
(9)
\left [ \begin{matrix} cos(\theta) & -sin(\theta)&1 \\ sin(\theta) & cos(\theta)&1 \\ 0 & 0&1 \end{matrix}\right ] \left [ \begin{matrix} x \\ y \\ 1 \end{matrix} \right ] = \tag{9} \left [ \begin{matrix} xcos(θ)−ysin(θ) &xsin(θ)+ycos(θ) &1\\ \end{matrix} \right ]
cos(θ)sin(θ)0−sin(θ)cos(θ)0111
xy1
=[xcos(θ)−ysin(θ)xsin(θ)+ycos(θ)1](9)
4.2.4 剪切变换
在二维空间中,剪切变换可以描述为通过沿着一个坐标轴(通常是 x 或 y 轴)移动所有点的过程。主要的二维剪切变换有:
1、水平剪切(Horizontal Shear):
可以用矩阵表示为:
[
1
s
h
x
1
0
1
1
0
0
1
]
[
x
y
1
]
=
[
x
+
s
h
x
∗
y
y
1
]
(10)
\left [ \begin{matrix} 1 & shx&1 \\ 0 & 1&1 \\ 0 & 0&1 \end{matrix}\right ] \left [ \begin{matrix} x \\ y \\ 1 \end{matrix} \right ] = \tag{10} \left [ \begin{matrix} x + shx * y &y&1\\ \end{matrix} \right ]
100shx10111
xy1
=[x+shx∗yy1](10)
这里 shx 是水平剪切因子,决定了沿 y 轴的移动量
2、垂直剪切(Vertical Shear):
[
1
0
1
s
h
y
1
1
0
0
1
]
[
x
y
1
]
=
[
x
s
h
y
∗
x
+
y
1
]
(11)
\left [ \begin{matrix} 1 & 0&1 \\ shy & 1&1 \\ 0 & 0&1 \end{matrix}\right ] \left [ \begin{matrix} x \\ y \\ 1 \end{matrix} \right ] = \tag{11} \left [ \begin{matrix} x ­ * x+ y&1\\ \end{matrix} \right ]
1shy0010111
xy1
=[xshy∗x+y1](11)
这里 shy 是垂直剪切因子,决定了沿 x 轴的移动量。
五. Halcon中的矩阵变换
5.1 平移、缩放和旋转变换
将放射变换矩阵,拆解为多个基础变换矩阵(旋转,缩放和剪切)
[[cos, -sin] * [[sx, 0] * [[1, sr] = [[sx*cos, a*sx*cos - sy*sin] = [[m11, m12]
[ sin, cos]] [0, sy]] [0, 1]] = [sx*sin, a*sx*sin + sy*cos]] = [m21, m22]]
将一个空矩阵经过旋转、平移和缩放之后,其内的数值变化如下:
1、生成一个[1.0, 0.0, 0.0, 0.0, 1.0, 0.0]
的空矩阵
hom_mat2d_identity (HomMat2DIdentity)
2、将该矩阵逆时针旋转80°,[cos80°, -sin80°, 0.0, sin80°, cos80°, 0.0]
*即[0.173648, -0.984808, 0.0, 0.984808, 0.173648, 0.0]
hom_mat2d_rotate (HomMat2DIdentity, rad(80), 0, 0, HomMat2DRotate)
3、再将该矩阵沿着XY方向分别平移600,400
*[0.173648, -0.984808, 600.0, 0.984808, 0.173648, 400.0]
hom_mat2d_translate (HomMat2DRotate, 600, 400, HomMat2DTranslate)
4、最终将该矩阵沿着XY方向缩放0.5倍
*[0.0868241, -0.492404, 300.0, 0.492404, 0.0868241, 200.0]
hom_mat2d_scale (HomMat2DTranslate, 0.5, 0.5, 0, 0, HomMat2DScale)
注意:这里不仅仅是第一三参数变为原来的0.5倍,而是所有系数全变为原来的0.5倍。
这也为我们从一个包含缩放和旋转效果的变换矩阵中提取出纯粹的旋转部分,然后计算旋转角度提供思路。
5.2 生成仿射变换矩阵(常用)
1、仿射变换算子
vector_to_hom_mat2d ( : : Px, Py, Qx, Qy : HomMat2D) — 用来生成像素坐标与机械坐标之间的转换矩阵
描述:
参数:
Px(in):原始点的X坐标。
Py(in):原始点的Y坐标。
Qx(in):变换点的X坐标。
Qy (in):变换点的Y坐标。
HomMat2D(out) :输出转换矩阵。
2、实际使用
根据实际标定得到的像素坐标和机械位置生成图像坐标系和机械坐标系之间的仿射矩阵
vector_to_hom_mat2d ([0,100,200,0,100,200,0,100,200] ,[0,0,0,100,100,100,200,200,200],[0,10,20,0,10,20,0,10,20],[0,0,0,10,10,10,20,20,20], HomMat2D)
* 查看qx,qy的值 是否和标定的数据差异太大
affine_trans_point_2d (HomMat2D, 1863, 1934, Qx, Qy)
如图:可以输出的转换矩阵含有6个值
实际参与左乘计算的齐次转换矩阵如下所示:
由于该像素当量的标定仅仅只有缩放变换,所以可以看出,只有转换矩阵中的HomMat2D[0]和HomMat2D[4]元素参与计算,分别代表X
和Y
方向的缩放系数。
具体来说,矩阵的生成顺序为:
首先进行旋转变换。
然后进行缩放变换。
最后进行平移变换(如果指定了平移向量)
下雨天,最惬意的事莫过于躺在床上静静听雨,雨中入眠,连梦里也长出青苔。 |