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;
}
相关推荐
多恩Stone5 天前
【C++入门扫盲1】C++ 与 Python:类型、编译器/解释器与 CPU 的关系
开发语言·c++·人工智能·python·算法·3d·aigc
多恩Stone5 天前
【3D-AICG 系列-15】Trellis 2 的 O-voxel Shape: Flexible Dual Grid 代码与论文对应
人工智能·python·算法·3d·aigc
sali-tec5 天前
C# 基于OpenCv的视觉工作流-章27-图像分割
图像处理·人工智能·opencv·算法·计算机视觉
saoys5 天前
Opencv 学习笔记:腐蚀操作 + 轮廓标记 + 分水岭分割
笔记·opencv·学习
saoys5 天前
Opencv 学习笔记:距离变换(DIST_L1 算法实战 + 归一化)
笔记·opencv·学习
在下胡三汉5 天前
为什么“资产土地”标准化主资产的 glTF、glb格式模型,为什么非常流行
3d
2401_863801465 天前
3DTiles(.b3dm,i3dm,cmpt) 数据转换fbx转obj转max转su,cesium格式模型转换
3d
3Dmax效果图渲染研习社5 天前
2026年3ds Max云渲染平台哪个好?
3d
guygg885 天前
图像匹配技术:相关匹配、Hausdorff距离匹配与基于距离变换的Hausdorff距离匹配
图像处理·opencv·计算机视觉