OpenCV相机标定与3D重建(25)计算两个三维点集之间的最优仿射变换矩阵(3x4)函数estimateAffine3D()的使用

  • 操作系统:ubuntu22.04
  • OpenCV版本:OpenCV4.9
  • IDE:Visual Studio Code
  • 编程语言:C++11

算法描述

计算两个3D点集之间的最优仿射变换。

它计算 [ x y z ] = [ a 11 a 12 a 13 a 21 a 22 a 23 a 31 a 32 a 33 ] [ X Y Z ] + [ b 1 b 2 b 3 ] \begin{bmatrix} x\\ y\\ z\\ \end{bmatrix} = \begin{bmatrix} a_{11} & a_{12} & a_{13}\\ a_{21} & a_{22} & a_{23}\\ a_{31} & a_{32} & a_{33}\\ \end{bmatrix} \begin{bmatrix} X\\ Y\\ Z\\ \end{bmatrix} + \begin{bmatrix} b_1\\ b_2\\ b_3\\ \end{bmatrix} xyz = a11a21a31a12a22a32a13a23a33 XYZ + b1b2b3

cv::estimateAffine3D 是 OpenCV 库中的一个函数,用于计算两个三维点集之间的最优仿射变换矩阵(3x4)。此函数通常用于3D图像配准、物体识别和追踪等领域。它通过最小化源点集与目标点集之间的几何误差来估计变换,并且可以选择使用鲁棒方法(如RANSAC)来处理异常值(outliers)。

函数原型

cpp 复制代码
int cv::estimateAffine3D
(
	InputArray 	src,
	InputArray 	dst,
	OutputArray 	out,
	OutputArray 	inliers,
	double 	ransacThreshold = 3,
	double 	confidence = 0.99 
)		

参数

src 第一个输入的3D点集,包含 (X,Y,Z) 坐标。

dst 第二个输入的3D点集,包含 (x,y,z) 坐标。

out 输出的3D仿射变换矩阵 3×4,形式如下:

a 11 a 12 a 13 b 1 a 21 a 22 a 23 b 2 a 31 a 32 a 33 b 3 \] \\begin{bmatrix} a_{11} \& a_{12} \& a_{13} \& b_1\\\\ a_{21} \& a_{22} \& a_{23} \& b_2\\\\ a_{31} \& a_{32} \& a_{33} \& b_3\\\\ \\end{bmatrix} a11a21a31a12a22a32a13a23a33b1b2b3 inliers 输出向量,指示哪些点是内点(1-内点,0-外点)。 ransacThreshold 在RANSAC算法中,考虑一个点为内点的最大重投影误差。 confidence 对估计变换的置信水平,在0和1之间。通常0.95到0.99之间的值就足够了。过于接近1的值可能会显著减慢估计过程。低于0.8-0.9的值可能导致变换估计不准确。 该函数使用RANSAC算法估计两个3D点集之间的最优3D仿射变换。 ### 代码示例 ```cpp #include #include #include using namespace cv; using namespace std; int main() { // 定义两组对应的3D点 (X, Y, Z) - 源点集和目标点集 vector< Point3f > src = { Point3f( 0, 0, 0 ), Point3f( 1, 0, 0 ), Point3f( 0, 1, 0 ), Point3f( 0, 0, 1 ) }; vector< Point3f > dst = { Point3f( 1, 1, 1 ), Point3f( 2, 1, 1 ), Point3f( 1, 2, 1 ), Point3f( 1, 1, 2 ) }; // 定义一个 Mat 来接收输出的仿射变换矩阵 Mat affineMatrix; // 定义一个 Mat 来接收内点信息 vector< uchar > inliers; // 调用 estimateAffine3D 函数 int inlierCount = estimateAffine3D( src, dst, affineMatrix, inliers ); if ( !affineMatrix.empty() ) { cout << "Estimated Affine Matrix:\n" << affineMatrix << endl; cout << "Number of inliers: " << inlierCount << endl; // 打印哪些点被认为是内点 for ( size_t i = 0; i < inliers.size(); ++i ) { if ( inliers[ i ] ) { cout << "Point pair (" << src[ i ] << ", " << dst[ i ] << ") is an inlier.\n"; } else { cout << "Point pair (" << src[ i ] << ", " << dst[ i ] << ") is an outlier.\n"; } } } else { cout << "Failed to estimate affine transformation." << endl; } return 0; } ``` ### 运行结果 ```bash Estimated Affine Matrix: [0.9999999999999998, 3.483324739761429e-15, -1.838806884535416e-15, 0.9999999999999998; -4.649058915617843e-16, 1.000000000000004, -1.595945597898663e-15, 1; -4.371503159461554e-16, 3.337607967779377e-15, 0.9999999999999983, 0.9999999999999994] Number of inliers: 1 Point pair ([0, 0, 0], [1, 1, 1]) is an inlier. Point pair ([1, 0, 0], [2, 1, 1]) is an inlier. Point pair ([0, 1, 0], [1, 2, 1]) is an inlier. Point pair ([0, 0, 1], [1, 1, 2]) is an inlier. ```

相关推荐
测试人社区-小明4 分钟前
智能测试误报问题的深度解析与应对策略
人工智能·opencv·线性代数·微服务·矩阵·架构·数据挖掘
雍凉明月夜2 小时前
视觉opencv学习笔记Ⅴ-数据增强(1)
人工智能·python·opencv·计算机视觉
Mangguo52082 小时前
解锁复杂制造的自由: SLS 3D打印技术如何重塑工业生产的边界
3d·性能优化·制造
深蓝学院4 小时前
让一张照片“变立体”:Meta 发布 SAM 3D,实现真正的单图 3D 重建
3d
刘一说5 小时前
WebGIS开发核心库深度解析:从2D到3D的全栈选择
3d·openlayers·webgis
啊阿狸不会拉杆5 小时前
《数字图像处理 》 第 1 章-绪论
图像处理·python·opencv·算法·数字图像处理
测试人社区-小明6 小时前
未来测试岗位的AI需求分析
人工智能·opencv·测试工具·算法·金融·机器人·需求分析
未来之窗软件服务7 小时前
幽冥大陆(五十)屏幕录像手机教程3D透镜主题——东方仙盟炼气期
3d·仙盟创梦ide·东方仙盟·屏幕录像大师
Microvision维视智造7 小时前
告别漏检与低效 ,维视智造用 2D+3D 视觉攻克 3C 连接器质检难题
3d·视觉检测