OpenCV相机标定与3D重建(46)将三维空间中的点投影到二维图像平面上函数projectPoints()的使用

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

算法描述

将3D点投影到图像平面上。

cv::projectPoints 是 OpenCV 库中的一个函数,用于将三维空间中的点投影到二维图像平面上。这个过程涉及到相机的内参矩阵、外参(旋转和平移向量)以及畸变系数。该函数可以用来模拟或校正从3D世界坐标到2D图像坐标的转换。

函数原型

cpp 复制代码
void cv::projectPoints	
(
	InputArray 	objectPoints,
	InputArray 	rvec,
	InputArray 	tvec,
	InputArray 	cameraMatrix,
	InputArray 	distCoeffs,
	OutputArray 	imagePoints,
	OutputArray 	jacobian = noArray(),
	double 	aspectRatio = 0 
)		

参数

  • 参数objectPoints:相对于世界坐标系表达的对象点数组。可以是3xN/Nx3的单通道矩阵或1xN/Nx1的三通道矩阵(或 vector),其中N是视图中的点数。
  • 参数rvec:旋转向量(Rodrigues形式),与 tvec 一起,执行从世界坐标系到相机坐标系的基变换,详见 calibrateCamera 的说明。
  • 参数tvec:平移向量,参见上述参数描述。
  • 参数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= fx000fy0cxcy1 . 。
  • 参数distCoeffs:输入的畸变系数向量 ( k 1 , k 2 , p 1 , p 2 [ , k 3 [ , k 4 , k 5 , k 6 [ , s 1 , s 2 , s 3 , s 4 [ , τ x , τ y ] ] ] ] ) (k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6[, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]]) (k1,k2,p1,p2[,k3[,k4,k5,k6[,s1,s2,s3,s4[,τx,τy]]]]),包含4、5、8、12或14个元素。如果向量为空,则假设畸变为零。
  • 参数imagePoints:输出的图像点数组,可以是1xN/Nx1的双通道矩阵,或 vector。
  • 参数jacobian:可选输出的 2N×(10+) 雅可比矩阵,表示图像点坐标对旋转向量、平移向量、焦距、主点坐标和畸变系数各分量的偏导数。在旧接口中,雅可比矩阵的不同部分通过不同的输出参数返回。
  • 参数aspectRatio:可选的"固定纵横比"参数。如果该参数不为0,函数假定纵横比 ( f x / f y ) (f_x / f_y) (fx/fy)是固定的,并相应地调整雅可比矩阵。

函数描述:

该函数根据给定的相机内部和外部参数计算3D点到图像平面的2D投影。可选地,函数还可以计算雅可比矩阵------即图像点坐标(作为所有输入参数的函数)对特定参数(内部或外部)的偏导数矩阵。这些雅可比矩阵用于 calibrateCamera、solvePnP 和 stereoCalibrate 中的全局优化过程。该函数本身也可以用来计算重投影误差,给定当前的内部和外部参数。

注意:

通过设置 rvec = tvec = [0,0,0],或将 cameraMatrix 设置为3x3的单位矩阵,或传递零畸变系数,可以获得函数的各种有用的部分情况。这意味着,可以在理想零畸变设置下计算稀疏点集的畸变坐标或应用透视变换(并计算导数)。

代码示例

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

using namespace cv;
using namespace std;

int main()
{
    // 定义3D点
    vector< Point3f > objectPoints = { Point3f( 0, 0, 0 ), Point3f( 1, 0, 0 ), Point3f( 0, 1, 0 ) };

    // 相机姿态(旋转和平移)
    Mat rvec = ( Mat_< double >( 3, 1 ) << 0, 0, 0 );  // 无旋转
    Mat tvec = ( Mat_< double >( 3, 1 ) << 0, 0, 0 );  // 无平移

    // 相机内参矩阵
    Mat cameraMatrix = ( Mat_< double >( 3, 3 ) << 1000, 0, 320, 0, 1000, 240, 0, 0, 1 );

    // 畸变系数(假设无畸变)
    Mat distCoeffs = Mat::zeros( 5, 1, CV_64F );

    // 定义输出变量
    vector< Point2f > imagePoints;

    // 执行投影
    projectPoints( objectPoints, rvec, tvec, cameraMatrix, distCoeffs, imagePoints );

    // 打印结果
    cout << "Projected Image Points:" << endl;
    for ( size_t i = 0; i < imagePoints.size(); ++i )
    {
        cout << "(" << imagePoints[ i ].x << ", " << imagePoints[ i ].y << ")" << endl;
    }

    return 0;
}

运行结果

bash 复制代码
Projected Image Points:
(320, 240)
(1320, 240)
(320, 1240)
相关推荐
子夜江寒1 小时前
基于 OpenCV 的图像形态学与边缘检测
python·opencv·计算机视觉
saoys1 小时前
Opencv 学习笔记:创建与原图等尺寸的空白图像
笔记·opencv·学习
智驱力人工智能9 小时前
守护流动的规则 基于视觉分析的穿越导流线区检测技术工程实践 交通路口导流区穿越实时预警技术 智慧交通部署指南
人工智能·opencv·安全·目标检测·计算机视觉·cnn·边缘计算
@areok@10 小时前
C++opencv图片(mat)传入C#bitmap图片
开发语言·c++·opencv
柠檬071115 小时前
fillPoly 函数
opencv
dazzle17 小时前
计算机视觉处理(OpenCV基础教学(十九):图像轮廓特征查找技术详解)
人工智能·opencv·计算机视觉
AI浩21 小时前
LabelAny3D: Label Any Object 3D in the Wild
3d
柳鲲鹏21 小时前
OpenCV视频实时跟踪目标,多种算法,python版
opencv·算法·音视频
学無芷境1 天前
vesselFM: A Foundation Model for Universal 3D Blood Vessel Segmentation
3d
sali-tec1 天前
C# 基于OpenCv的视觉工作流-章7-膨胀
图像处理·人工智能·opencv·算法·计算机视觉