OpenCV相机标定与3D重建(47)从两幅图像中的一组匹配点恢复相机的姿态(旋转和平移)函数recoverPose()的使用

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

算法描述

从两幅不同相机拍摄的图像中对应的点恢复相对相机旋转和平移,使用手性检查。返回通过该检查的内点数量。

cv::recoverPose 是 OpenCV 库中的一个函数,用于从两幅图像中的一组匹配点恢复相机的姿态(旋转和平移)。它还可以计算本质矩阵(Essential Matrix)或基础矩阵(Fundamental Matrix),具体取决于提供的相机内参矩阵。

函数原型

cpp 复制代码
int cv::recoverPose	
(
	InputArray 	points1,
	InputArray 	points2,
	InputArray 	cameraMatrix1,
	InputArray 	distCoeffs1,
	InputArray 	cameraMatrix2,
	InputArray 	distCoeffs2,
	OutputArray 	E,
	OutputArray 	R,
	OutputArray 	t,
	int 	method = cv::RANSAC,
	double 	prob = 0.999,
	double 	threshold = 1.0,
	InputOutputArray 	mask = noArray() 
)		

参数

  • 参数points1:来自第一幅图像的N个2D点数组。点坐标应该是浮点数(单精度或双精度)。
  • 参数points2:与 points1 大小和格式相同的第二幅图像的点数组。
  • 参数cameraMatrix1:第一相机的输入/输出相机矩阵,同 calibrateCamera 中的定义。此外,对于立体情况,可以使用额外的标志位,详见下文。
  • 参数distCoeffs1:第一相机的输入/输出畸变系数向量,同 calibrateCamera 中的定义。
  • 参数cameraMatrix2:第二相机的输入/输出相机矩阵,同 calibrateCamera 中的定义。此外,对于立体情况,可以使用额外的标志位,详见下文。
  • 参数distCoeffs2:第二相机的输入/输出畸变系数向量,同 calibrateCamera 中的定义。
  • 参数E:输出的本质矩阵。
  • 参数R:输出的旋转矩阵。与平移向量一起,该矩阵组成一个从第一个相机坐标系到第二个相机坐标系的基变换元组。注意,通常情况下,t 不能直接用于此元组,详见下面描述的参数。
  • 参数t:输出的平移向量。这个向量是通过 decomposeEssentialMat 得到的,因此只知道其方向且具有单位长度。
  • 参数method:计算本质矩阵的方法。
    • RANSAC:用于RANSAC算法。
    • LMEDS:用于LMedS算法。
  • 参数prob:仅用于RANSAC或LMedS方法的参数。它指定了估计矩阵正确的期望置信水平(概率)。
  • 参数threshold:仅用于RANSAC的参数。它是点到极线的最大距离(以像素为单位),超过此距离的点被视为离群点,并不用于计算最终的基本矩阵。可以根据点定位的准确性、图像分辨率和图像噪声设置为大约1-3。
  • 参数mask:points1 和 points2 中内点的输入/输出掩码。如果它不是空的,则它标记了给定本质矩阵 E 下 points1 和 points2 的内点。只有这些内点将被用来恢复姿态。在输出掩码中,只有通过手性检查的内点会被保留。

函数描述

此函数使用 decomposeEssentialMat 分解本质矩阵,然后通过手性检查验证可能的姿态假设。手性检查意味着三角化的3D点应具有正深度。一些细节可以在文献 [204] 中找到。

此函数可用于处理 findEssentialMat 输出的 E 和 mask。在这种情况下,points1 和 points2 是 findEssentialMat 的相同输入。

cpp 复制代码
// Example. Estimation of fundamental matrix using the RANSAC algorithm
int point_count = 100;
vector<Point2f> points1(point_count);
vector<Point2f> points2(point_count);
// initialize the points here ...
for( int i = 0; i < point_count; i++ )
{
    points1[i] = ...;
    points2[i] = ...;
}
// Input: camera calibration of both cameras, for example using intrinsic chessboard calibration.
Mat cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2;
// Output: Essential matrix, relative rotation and relative translation.
Mat E, R, t, mask;
recoverPose(points1, points2, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2, E, R, t, mask);

返回值

该函数返回内点的数量,即符合估计模型的点对数目。

注意事项

如果 cameraMatrix2 和 distCoeffs2 没有提供,则假设它们与 cameraMatrix1 和 distCoeffs1 相同。

当提供了有效的 mask 参数时,函数将更新这个掩码以反映最终确定的内点。

代码示例

cpp 复制代码
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main()
{
    // 定义两组2D点 (这里仅作为示例,实际应用中这些点应该来自图像特征匹配)
    vector<Point2f> points1 = { /* ... */ };
    vector<Point2f> points2 = { /* ... */ };

    // 相机内参矩阵和畸变系数 (假设已知)
    Mat cameraMatrix1 = (Mat_<double>(3, 3) << fx, 0, cx, 0, fy, cy, 0, 0, 1);
    Mat distCoeffs1 = Mat::zeros(5, 1, CV_64F);

    // 输出变量
    Mat E, R, t;
    Mat mask; // 内点掩码

    // 执行姿态恢复
    int inliers = recoverPose(points1, points2, cameraMatrix1, distCoeffs1,
                              cameraMatrix1, distCoeffs1, E, R, t, mask);

    // 打印结果
    cout << "Number of inliers: " << inliers << endl;
    cout << "Rotation matrix:\n" << R << endl;
    cout << "Translation vector:\n" << t << endl;

    return 0;
}
相关推荐
denghai邓海2 小时前
用OpenCV实现UVC视频分屏
人工智能·opencv·音视频
jndingxin2 小时前
OpenCV相机标定与3D重建(49)将视差图(disparity map)重投影到三维空间中函数reprojectImageTo3D()的使用
3d
布兰妮甜2 小时前
Three.js - 打开Web 3D世界的大门
前端·javascript·3d·动画·three.js
mm_exploration2 小时前
halcon三维点云数据处理(七)find_shape_model_3d_recompute_score
图像处理·3d·halcon·点云处理
光场视觉2 小时前
3D机器视觉的类型、应用和未来趋势
3d
深色風信子2 小时前
Kotlin OpenCV 画画
opencv·kotlin
知识鱼丸2 小时前
【杂记】机器视觉 #opencv #numpy #matplotlib
人工智能·opencv·计算机视觉
jndingxin3 小时前
OpenCV相机标定与3D重建(48)对三台相机进行极线校正(rectification)函数rectify3Collinear()的使用
opencv·3d
创小董5 小时前
3D立体无人机夜间表演技术详解
3d·无人机
xm一点不soso13 小时前
ROS2+OpenCV综合应用--11. AprilTag标签码跟随
人工智能·opencv·计算机视觉