首页 > 其他分享 >OpenCV相机标定与3D重建(57)精细化优化由 cv::solvePnP 或 cv::solvePnPRansac 等函数得到的初始估计值的函数solvePnPRefineLM()的使用

OpenCV相机标定与3D重建(57)精细化优化由 cv::solvePnP 或 cv::solvePnPRansac 等函数得到的初始估计值的函数solvePnPRefineLM()的使用

时间:2025-01-15 13:28:02浏览次数:3  
标签:平移 solvePnPRansac 函数 0.0 Point2f 向量 cv Point3f

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

算法描述

从3D-2D点对应关系出发,并基于一个初始解,精细化姿态(将物体坐标系中的3D点变换到相机坐标系的旋转和平移。
cv::solvePnPRefineLM 是 OpenCV 中用于精细化优化由 cv::solvePnP 或 cv::solvePnPRansac 等函数得到的初始估计值的函数。它使用 Levenberg-Marquardt (LM) 算法来最小化重投影误差,从而获得更精确的姿态估计(旋转和平移向量)。

函数原型

void cv::solvePnPRefineLM
(
	InputArray 	objectPoints,
	InputArray 	imagePoints,
	InputArray 	cameraMatrix,
	InputArray 	distCoeffs,
	InputOutputArray 	rvec,
	InputOutputArray 	tvec,
	TermCriteria 	criteria = TermCriteria(TermCriteria::EPS+TermCriteria::COUNT, 20, FLT_EPSILON) 
)		

参数

  • 参数objectPoints 物体坐标空间中的物体点数组,格式为Nx3的单通道或1xN/Nx1的三通道,其中N是点的数量。也可以传递 vector 类型的数据。
  • 参数imagePoints 对应的图像点数组,格式为Nx2的单通道或1xN/Nx1的双通道,其中N是点的数量。也可以传递 vector 类型的数据。
  • 参数cameraMatrix输入的相机内参矩阵 A = [ f x 0 c x 0 f y c y 0 0 1 ] A =\begin{bmatrix}f_x & 0 & c_x \\0 & f_y & c_y \\0 & 0 & 1\end{bmatrix} A= ​fx​00​0fy​0​cx​cy​1​
  • 参数distCoeffs 输入的畸变系数向量 (k1, k2, p1, p2 [,k3 [,k4, k5, k6 [,s1, s2, s3, s4 [,τx, τy]]]]),包含4、5、8、12或14个元素。如果该向量为空,则假设畸变为零。
  • 参数rvec 输入/输出旋转向量(见 Rodrigues),与 tvec 一起将模型坐标系中的点变换到相机坐标系中。输入值用作初始解。
  • 参数tvec 输入/输出平移向量。输入值用作初始解。
  • 参数criteria 确定何时停止Levenberg-Marquardt迭代算法的标准。

该函数从至少3个物体点及其对应的图像投影出发,给定旋转和平移向量的初始解以及相机内参矩阵和畸变系数,精细化物体的姿态。根据Levenberg-Marquardt迭代最小化过程,该函数最小化了关于旋转和平移向量的投影误差。

代码示例


#include <iostream>
#include <opencv2/opencv.hpp>
#include <vector>

using namespace cv;
using namespace std;

int main()
{
    // 假设我们有以下数据
    vector< Point3f > objectPoints = { Point3f( 0.0f, 0.0f, 0.0f ), Point3f( 1.0f, 0.0f, 0.0f ), Point3f( 0.0f, 1.0f, 0.0f ), Point3f( 1.0f, 1.0f, 0.0f ) };

    vector< Point2f > imagePoints = { Point2f( 300.0f, 300.0f ), Point2f( 400.0f, 300.0f ), Point2f( 300.0f, 400.0f ), Point2f( 400.0f, 400.0f ) };

    // 相机内参矩阵
    Mat cameraMatrix = ( Mat_< double >( 3, 3 ) << 520.9, 0, 325.1, 0, 521.0, 249.7, 0, 0, 1 );

    // 畸变系数
    Mat distCoeffs = ( Mat_< double >( 5, 1 ) << 0.2624, -0.9531, -0.0054, 0.0026, 1.1633 );

    // 初始的旋转向量和平移向量
    Vec3d rvec_initial = Vec3d( 0.0, 0.0, 0.0 );     // 初始猜测值
    Vec3d tvec_initial = Vec3d( 0.0, 0.0, 1000.0 );  // 初始猜测值

    // 使用 solvePnP 获取初始估计
    bool success = solvePnP( objectPoints, imagePoints, cameraMatrix, distCoeffs, rvec_initial, tvec_initial );
    if ( !success )
    {
        cerr << "solvePnP failed." << endl;
        return -1;
    }

    // 使用 solvePnPRefineLM 进行精细化优化
    TermCriteria criteria( TermCriteria::EPS + TermCriteria::COUNT, 100, 1e-5 );
    solvePnPRefineLM( objectPoints, imagePoints, cameraMatrix, distCoeffs, rvec_initial, tvec_initial, criteria );

    cout << "精化后的旋转向量: " << rvec_initial << endl;
    cout << "精化后的平移向量: " << tvec_initial << endl;

    // 可选:将旋转向量转换为旋转矩阵
    Mat R;
    Rodrigues( rvec_initial, R );
    cout << "精化后的旋转矩阵: " << endl << R << endl;

    return 0;
}

运行结果

精化后的旋转向量: [0.0404742, -0.0162112, 0.000554714]
精化后的平移向量: [-0.251495, 0.504091, 5.228]
精化后的旋转矩阵: 
[0.9998684653639389, -0.0008825542291305424, -0.01619484698273995;
 0.0002265223551939896, 0.9991808950794823, -0.04046588187334291;
 0.01621729503907217, 0.04045689071341727, 0.9990496681023513]

标签:平移,solvePnPRansac,函数,0.0,Point2f,向量,cv,Point3f
From: https://blog.csdn.net/jndingxin/article/details/145136489

相关文章

  • vue.js辅助函数-mapMutations
    在Vue.js中,使用辅助函数可以更方便地使用Vuex的mutation。而mapMutations就是Vuex提供的一个辅助函数,它可以将mutation映射到组件的methods中,使得我们可以在组件中直接调用mutation,而不需要手动进行commit。mapMutations函数接收一个字符串数组或对象作为参数,数组中的字符串即......
  • 【西南石油大学电气信息学院主办,EI检索稳定 | SPIE (ISSN: 0277-786X)出版】2025年计
    2025年计算机视觉研究进展与应用国际学术会议(ACVRA2025)2025InternationalConferenceonAdvancesinComputerVisionResearchandApplications2025年2月28-3月2日广州会议官网:www.acvra.org【更多详情】EI检索稳定| 西南石油大学电气信息学院主讲嘉宾:孟......
  • 6、原来可以这样理解C语言_函数(4/8)形参和实参
    目录 四、形参和实参四、(1)、实参 四、(2)、形参四、(3)、实参和形参的关系 四、形参和实参        在函数使⽤的过程中,把函数的参数分为,实参和形参。#include<stdio.h>intAdd(intx,inty){intz=0;z=x+y;returnz;}intmain(......
  • 2025.1.14初学欧拉函数记
    显然,本文的一切都是关于它——\(\varphi\)。前提互质若有正整数\(a,b\)且满足\(\gcd(a,b)=1\),则称\(a,b\)互质。对于多种数的情况,我们把\(\gcd(a,b,c)=1\)的情况称为\(a,b,c\)互质。把\(\gcd(a,b)=\gcd(a,c)=\gcd(b,c)=1\)称为\(a,b,c\)两两互质。后者明显是一个......
  • cv::Vec3f什么意思
    cv::Vec3f是OpenCV中用于表示三维向量或三通道颜色的类。具体来说,cv::Vec3f是一个包含三个float类型元素的向量,通常用于以下几种情况:颜色表示:在图像处理中,Vec3f常用于表示颜色值,尤其是在浮点图像中。例如,一个RGB颜色可以用cv::Vec3f表示,其中每个分量(红色、绿色、蓝......
  • 智能合约中的多个函数重入攻击(Reentrancy Attack)详解
    简介在区块链智能合约开发中,重入攻击(ReentrancyAttack)是一种非常危险的漏洞类型。攻击者通过利用合约内函数之间的调用漏洞,可能会重复调用某个函数或多个函数,从而导致不正常的行为,甚至损失资金。通常,重入攻击依赖于合约执行过程中状态更新与外部合约交互的顺序错误。在这篇......
  • 【学习笔记】函数复合:[PKUSC 2024] 排队
    函数复合是这样的一类问题:有一个函数序列\(f_1,f_2,f_3,...,f_n\)。离线询问,给定参数\(x\),\(f_r(f_{r-1}(...f_l(x)))\)的值。有点抽象对吧。看道题就懂了。[PKUSC2024]排队QOJ题目链接:#8672.排队。(反正我在其他OJ上没找到)前置知识:平衡树题面上有简化题意,但......
  • JavaScript详解 ——函数
    1、函数的概念在JS里面,可能会定义非常多的相同代码或者功能相似的代码,这些代码需要大量重复使用函数:就是封装一段可被重复调用执行的代码块。通过代码块可以实现在需要的的重复使用,使用typeof检查一个函数对象时,会返回function函数的封装是把一个或者多个功能通过函数的方式......
  • MySQL基础函数使用
    DQL中的函数#官方函数链接https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_date-format4.1 单行函数函数都是数据库提前给我们准备好的,所以我们可以直接调用,使用函数可以让指定的列计算出我们需要的数据单行函数:指的是操作一行数据返......
  • My CVPR Learning-Feedback
    2024视觉-语言 EfficientVision-LanguagePre-trainingbyClusterMasking图像包含大量冗余信息,这使得从图像中高效学习表示变得具有挑战性,提出了一种在视觉-语言对比学习过程中对图像块进行聚类掩蔽的策略论文方法:随机聚类掩蔽:在训练过程中,随机选择图像块作为聚类中......