如何构建Halcon中的仿射变换矩阵?
摘要:构建仿射变换矩阵 vector_angle_to_rigid 作用:获取刚性变换的变换矩阵 算子签名:vector_angle_to_rigid( Row1, Column1, Angle1, Row2, Column2, Angle2 :
构建仿射变换矩阵
vector_angle_to_rigid
作用:获取刚性变换的变换矩阵
算子签名:vector_angle_to_rigid( Row1, Column1, Angle1, Row2, Column2, Angle2 : HomMat2D)
输入参数:
Row1, Column1(输入控制):旋转中心坐标(图像坐标系)
Angle1 (输入控制) : 初始角度(弧度制)
Row2, Column2(输入控制):目标位置 的参考点(通常与旋转中心相同)
Angle2 (输入控制) : 目标旋转角度(弧度制)
输出参数:
HomMat2D(输出对象):生成的刚性变换矩阵(3×3)
// 将图像绕中心(256,256)旋转30度(无平移)
HTuple centerRow = 256, centerCol = 256;
HTuple angle1 = 0, angle2 = rad(30); // rad()将角度转弧度
HhomMat2D homMat;
vector_angle_to_rigid(centerRow, centerCol, angle1,
centerRow, centerCol, angle2,
&homMat);
刚性变换矩阵由旋转和平移构成,矩阵形式为:
\[HomMat2D =
\begin{bmatrix}
\cos(\theta) & -\sin(\theta) & T_x \\
\sin(\theta) & \cos(\theta) & T_y \\
0 & 0 & 1
\end{bmatrix}
\]
vector_to_similarity
作用:获取包含旋转、平移和各向同性缩放的相似变换矩阵
算子签名:vector_to_similarity(Px, Py, Qx, Qy, HomMat2D)
输入参数:
Px, Py(输入参数):源点坐标(元组)
Qx, Qy (输入参数) : 目标点坐标(元组)
输出参数:
HomMat2D(输出对象):生成的相似变换矩阵(3×3)
最少点对:
相似变换:2对点(4自由度)
// 将图像绕中心(256,256)旋转30度,再缩放2倍
HTuple centerRow = 256, centerCol = 256;
HTuple angle1 = 0, angle2 = rad(30); // rad()将角度转弧度
HTuple scale = 2; // 缩放因子
HTuple Px = centerRow, Py = centerCol; // 原点坐标
HTuple Qx = centerRow + 256*scale, Qy = centerCol + 256*scale; // 目标点坐标
HhomMat2D homMat;
vector_to_similarity(Px, Py, Qx, Qy, &homMat);
相似变换矩阵形式:
\[HomMat2D =
\begin{bmatrix}
s & 0 & 1 \\
0 & s & 1 \\
0 & 0 & 1
\end{bmatrix}
\begin{bmatrix}
1 & 0 & T_x \\
0 & 1 & T_y \\
0 & 0 & 1
\end{bmatrix}
\begin{bmatrix}
\cos(\theta) & -\sin(\theta) & 0 \\
\sin(\theta) & \cos(\theta) & 0 \\
0 & 0 & 1
\end{bmatrix}
=
\begin{bmatrix}
s\cos(\theta) & -s\sin(\theta) & T_x \\
s\sin(\theta) & s\cos(\theta) & T_y \\
0 & 0 & 1
\end{bmatrix}
\]
// 源点:P1(100,100), P2(200,100)
HTuple Px, Py, Qx, Qy;
Px.Append(100); Px.Append(200); // Px = [100, 200]
Py.Append(100); Py.Append(100); // Py = [100, 100]
// 目标点:Q1(300,300), Q2(500,300)
Qx.Append(300); Qx.Append(500); // Qx = [300, 500]
Qy.Append(300); Qy.Append(300); // Qy = [300, 300]
// 计算变换矩阵
HTuple homMat;
vector_to_similarity(Px, Py, Qx, Qy, &homMat);
// 应用变换
affine_trans_image(Image, &ImageTransformed, homMat, "constant");
hom_vector_to_proj_hom_mat2d
作用:计算投影变换(单应性变换) 的3×3齐次变换矩阵,支持透视变换、仿射变换等更复杂的几何变换
算子签名:hom_vector_to_proj_hom_mat2d(Px, Py, Pw, Qx, Qy, Qw, Method : HomMat2D)
输入参数:
Px, Py(输入参数):源点坐标(元组)
Qx, Qy (输入参数) : 目标点坐标(元组)
Pw, Qw (输入参数) : 权重(元组)
Method(输入控制):计算方法 'dlt' 或 'normalized_dlt'
输出参数:
HomMat2D(输出对象):生成的投影变换矩阵(3×3)
最少点对:
仿射变换:3对点(6自由度)
投影变换:4对点(8自由度)
权重的作用:权重越大的点对,在矩阵计算中的影响力越强。
输入规则
参数组合
行为
省略Pw和Qw
所有点权重=1.0
仅提供 Pw
目标权重 Qw 自动设为 Pw
Pw 和 Qw 不同
使用各自独立权重
// 高精度点赋予更大权重
HTuple Pw = {1.0, 1.0, 2.0, 2.0}; // 后两个点更可靠
HTuple Qw = {1.0, 1.0, 3.0, 1.0}; // 第三个目标点优先级最高
HhomMat2D homMat;
hom_vector_to_proj_hom_mat2d(Px, Py, Pw, Qx, Qy, Qw, "dlt", &homMat);
HTuple Px = {100, 400, 400, 100}; // 源四边形
HTuple Py = {100, 100, 300, 300};
HTuple Qx = {80, 420, 380, 120}; // 目标四边形
HTuple Qy = {80, 120, 320, 280};
// 无权重,使用默认权重
HTuple homMat;
hom_vector_to_proj_hom_mat2d(Px, Py, HTuple(), Qx, Qy, HTuple(),
"normalized_dlt", &homMat);
Method 参数:
方法
说明
'dlt'
标准直接线性变换算法
'normalized_dlt'
推荐:归一化的直接线性变换,数值稳定性更好
总结
算子
vector_angle_to_rigid
vector_to_similarity
hom_vector_to_proj_hom_mat2d
变换类型
刚性变换(旋转+平移)
相似变换(旋转+平移+各向同性缩放)
投影变换(旋转+平移+缩放+透视变形)
最小点数
1(旋转中心)
2(点对)
4(点对)
输入参数
旋转中心 + 角度
两个对应点对
四个及以上对应点对(可带权重)
输出矩阵形式
[cosθ -sinθ Tx; sinθ cosθ Ty; 0 0 1]
[s*cosθ -s*sinθ Tx; s*sinθ s*cosθ Ty; 0 0 1]
[h11 h12 h13; h21 h22 h23; h31 h32 h33]
自由度
3(θ, Tx, Ty)
4(θ, s, Tx, Ty)
8(所有hᵢⱼ,比例固定)
保持的几何属性
长度、角度
角度、比例
直线性(平行性可能丢失)
优势
- 计算速度快
- 单点控制旋转
- 支持缩放
- 两点确定变换
- 处理透视变形
- 可加权优化
不足
- 不支持缩放
- 灵活性低
- 不支持各向异性缩放
- 无法处理透视
- 需要更多点
- 计算复杂度高
典型应用场景
- 图像旋转校正
- 机械臂定位
- 物体尺寸匹配
- 标定板对齐
- 文档透视校正
- 3D场景投影
数值稳定性
极高
高
需用'normalized_dlt'避免不稳定
特殊要求
需明确旋转中心
两点需非重合
任意三点不共线
