OpenCV相机标定与3D重修(25)计算两个三维点集之间的最优仿射变更矩阵(3x4 ...

打印 上一主题 下一主题

主题 829|帖子 829|积分 2489


  • 操纵系统: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​               ​=               ​a11​a21​a31​​a12​a22​a32​​a13​a23​a33​​               ​               ​XYZ​               ​+               ​b1​b2​b3​​               ​
cv::estimateAffine3D 是 OpenCV 库中的一个函数,用于计算两个三维点集之间的最优仿射变更矩阵(3x4)。此函数通常用于3D图像配准、物体识别和追踪等领域。它通过最小化源点集与目的点集之间的几何毛病来估计变更,而且可以选择利用鲁棒方法(如RANSAC)来处理异常值(outliers)。
函数原型

  1. int cv::estimateAffine3D
  2. (
  3.         InputArray         src,
  4.         InputArray         dst,
  5.         OutputArray         out,
  6.         OutputArray         inliers,
  7.         double         ransacThreshold = 3,
  8.         double         confidence = 0.99
  9. )               
复制代码
参数

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}                                    ​a11​a21​a31​​a12​a22​a32​​a13​a23​a33​​b1​b2​b3​​               ​
inliers 输出向量,指示哪些点是内点(1-内点,0-外点)。
ransacThreshold 在RANSAC算法中,考虑一个点为内点的最大重投影毛病。
confidence 对估计变更的置信程度,在0和1之间。通常0.95到0.99之间的值就足够了。过于靠近1的值可能会显著减慢估计过程。低于0.8-0.9的值可能导致变更估计不准确。
该函数利用RANSAC算法估计两个3D点集之间的最优3D仿射变更。
代码示例

  1. #include <iostream>
  2. #include <opencv2/opencv.hpp>
  3. #include <vector>
  4. using namespace cv;
  5. using namespace std;
  6. int main()
  7. {
  8.     // 定义两组对应的3D点 (X, Y, Z) - 源点集和目标点集
  9.     vector< Point3f > src = { Point3f( 0, 0, 0 ), Point3f( 1, 0, 0 ), Point3f( 0, 1, 0 ), Point3f( 0, 0, 1 ) };
  10.     vector< Point3f > dst = { Point3f( 1, 1, 1 ), Point3f( 2, 1, 1 ), Point3f( 1, 2, 1 ), Point3f( 1, 1, 2 ) };
  11.     // 定义一个 Mat 来接收输出的仿射变换矩阵
  12.     Mat affineMatrix;
  13.     // 定义一个 Mat 来接收内点信息
  14.     vector< uchar > inliers;
  15.     // 调用 estimateAffine3D 函数
  16.     int inlierCount = estimateAffine3D( src, dst, affineMatrix, inliers );
  17.     if ( !affineMatrix.empty() )
  18.     {
  19.         cout << "Estimated Affine Matrix:\n" << affineMatrix << endl;
  20.         cout << "Number of inliers: " << inlierCount << endl;
  21.         // 打印哪些点被认为是内点
  22.         for ( size_t i = 0; i < inliers.size(); ++i )
  23.         {
  24.             if ( inliers[ i ] )
  25.             {
  26.                 cout << "Point pair (" << src[ i ] << ", " << dst[ i ] << ") is an inlier.\n";
  27.             }
  28.             else
  29.             {
  30.                 cout << "Point pair (" << src[ i ] << ", " << dst[ i ] << ") is an outlier.\n";
  31.             }
  32.         }
  33.     }
  34.     else
  35.     {
  36.         cout << "Failed to estimate affine transformation." << endl;
  37.     }
  38.     return 0;
  39. }
复制代码
运行效果

  1. Estimated Affine Matrix:
  2. [0.9999999999999998, 3.483324739761429e-15, -1.838806884535416e-15, 0.9999999999999998;
  3. -4.649058915617843e-16, 1.000000000000004, -1.595945597898663e-15, 1;
  4. -4.371503159461554e-16, 3.337607967779377e-15, 0.9999999999999983, 0.9999999999999994]
  5. Number of inliers: 1
  6. Point pair ([0, 0, 0], [1, 1, 1]) is an inlier.
  7. Point pair ([1, 0, 0], [2, 1, 1]) is an inlier.
  8. Point pair ([0, 1, 0], [1, 2, 1]) is an inlier.
  9. Point pair ([0, 0, 1], [1, 1, 2]) is an inlier.
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

刘俊凯

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表