opencv和C++使用Halcon标定的相机内参和外参,将图像坐标转为世界坐标

本文详细介绍了坐标变换在计算机视觉中的应用,包括世界坐标系、相机坐标系、图像坐标系和像素坐标系的关系。重点讲解了如何通过相机内参数矩阵和外参数矩阵进行坐标转换,以及如何使用OpenCV库中的solvePnP函数进行标定和坐标计算,最后提到了Halcon格式的内参参数转换方法。
摘要由CSDN通过智能技术生成

坐标变换详解

提示:这里可以添加技术概要

1.1 坐标关系

在这里插入图片描述
相机中有四个坐标系,分别为world,camera,image,pixel

  • world为世界坐标系,可以任意指定 x w x_{w} xw轴和 y w y_w yw轴,为上图P点所在坐标系。
  • camera为相机坐标系,原点位于小孔,z轴与光轴重合,轴和轴平行投影面,为上图坐标系 X c Y c Z c X_{c}Y_{c}Z_{c} XcYcZc
  • image为图像坐标系,原点位于光轴和投影面的交点,轴和轴平行投影面,为上图坐标系xy。
  • pixel为像素坐标系,从小孔向投影面方向看,投影面的左上角为原点,uv轴和投影面两边重合,该坐标系与图像坐标系处在同一平面,但原点不同。

1.2 坐标转换

下式为像素坐标pixel与世界坐标world的转换公式,右侧第一个矩阵为相机内参数矩阵,第二个矩阵为相机外参数矩阵。假设图像坐标已知,同时相机内参数矩阵通过标定已获取,还需计算比例系数s和外参数矩阵。

s [ u v 1 ] = [ f x 0 c x 0 f y c y 0 0 1 ] [ r 11 r 12 r 13 t 1 r 21 r 22 r 23 t 2 r 31 r 32 r 33 t 3 ] [ x y z 1 ] s\begin{bmatrix} u\\v\\1 \end{bmatrix} =\begin{bmatrix} f_x&0&c_x\\0&f_y&c_y\\0&0&1 \end{bmatrix} \begin{bmatrix} r_{11} & r_{12}&r_{13}&t_1 \\ r_{21} & r_{22}&r_{23}&t_2 \\ r_{31} & r_{32}&r_{33}&t_3 \end{bmatrix} \begin{bmatrix} x\\y\\z\\1 \end{bmatrix} s uv1 = fx000fy0cxcy1 r11r21r31r12r22r32r13r23r33t1t2t3 xyz1
转换公式可简化为:

s [ u v 1 ] = M ( R [ X Y Z c o n s t ] + t ) s\begin{bmatrix} u\\v\\1 \end{bmatrix} =M(R\begin{bmatrix} X\\Y\\Z_{const} \end{bmatrix}+t) s uv1 =M(R XYZconst +t)

s为比例系数, M为相机内参数矩阵,R为旋转矩阵,t为平移矩阵, Z c o n s t Z_{const} Zconst为世界坐标系高度,可设置为0。

通过矩阵变换可得下式:

R − 1 M − 1 s [ u v 1 ] = [ X Y Z c o n s t ] + R − 1 t R^{-1}M^{-1}s\begin{bmatrix} u\\v\\1 \end{bmatrix} =\begin{bmatrix} X\\Y\\Z_{const} \end{bmatrix}+R^{-1}t R1M1s uv1 = XYZconst +R1t

求解出旋转矩阵和平移矩阵即可算得s。

外参矩阵

提示:这里可以添加技术整体架构

外参数矩阵

bool solvePnP(InputArray objectPoints, 
	      	  InputArray imagePoints, 
	      	  InputArray cameraMatrix, 
	      	  InputArray distCoeffs, 
              OutputArray rvec, 
              OutputArray tvec, 
              bool useExtrinsicGuess=false, 
              int flags=ITERATIVE )
  • objectPoints,输入世界坐标系中点的坐标;
  • imagePoints,输入对应图像坐标系中点的坐标;
  • cameraMatrix, 相机内参数矩阵;
  • distCoeffs, 畸变系数;
  • rvec, 旋转向量,需输入一个非空Mat,需要通过cv::Rodrigues转换为旋转矩阵;
  • tvec, 平移向量,需输入一个非空Mat;
  • useExtrinsicGuess, 默认为false,如果设置为true则输出输入的旋转矩阵和平移矩阵;
  • flags,选择采用的算法;
  • solvePnP的参数rvec和tvec应该都是double类型的

程序实现

提示:这里可以添加技术名词解释
(1)计算参数s和旋转平移矩阵,需要输入一系列的世界坐标系的点及其对应的图像坐标系的点。

//输入参数
Mat cameraMatrix = Mat(3, 3, CV_32FC1, Scalar::all(0)); /* 摄像机内参数矩阵 */
Mat distCoeffs = Mat(1, 5, CV_32FC1, Scalar::all(0)); /* 摄像机的5个畸变系数:k1,k2,p1,p2,k3 */
double zConst = 0;//实际坐标系的距离,若工作平面与相机距离固定可设置为0
	
//计算参数
double s;
Mat rotationMatrix = Mat (3, 3, DataType<double>::type);
Mat tvec = Mat (3, 1, cv::DataType<double>::type);
void calcParameters(vector<cv::Point2f> imagePoints, vector<cv::Point3f> objectPoints)
{
	//计算旋转和平移
	Mat rvec(3, 1, cv::DataType<double>::type);
	cv::solvePnP(objectPoints, imagePoints, cameraMatrix, distCoeffs, rvec, tvec);
	cv::Rodrigues(rvec, rotationMatrix);
}

(2)根据输入的图像坐标计算世界坐标。

Point3f getWorldPoints(Point2f inPoints)
{
    //获取图像坐标
    cv::Mat imagePoint = cv::Mat::ones(3, 1, cv::DataType<double>::type); //u,v,1
	imagePoint.at<double>(0, 0) = inPoints.x;
	imagePoint.at<double>(1, 0) = inPoints.y;
 
	//计算比例参数S
	cv::Mat tempMat, tempMat2;
	tempMat = rotationMatrix.inv() * cameraMatrix.inv() * imagePoint;
	tempMat2 = rotationMatrix.inv() * tvec;
	s = zConst + tempMat2.at<double>(2, 0);
	s /= tempMat.at<double>(2, 0);
 
    //计算世界坐标
	Mat wcPoint = rotationMatrix.inv() * (s * cameraMatrix.inv() * imagePoint - tvec);
	Point3f worldPoint(wcPoint.at<double>(0, 0), wcPoint.at<double>(1, 0), wcPoint.at<double>(2, 0));
	return worldPoint;
}

Opencv相机标定

提示:这里可以添加技术细节
内参矩阵:
在这里插入图片描述

在这里插入图片描述

内参矩阵参数含义:

f:焦距,单位毫米;dx:像素x方向宽度,单位毫米;1/dx:x方向1mm内有多少个像素;

f/dx:使用像素来描述x轴方向的焦距的长度

f/dy:使用像素来描述y轴方向的焦距的长度

u0,v0为主点的实际位置,单位也是毫米。

Halcon格式

Halcon格式
内参参数转换:
fx = f/sx ; fy = f/sy;u0 = cx ; v0 = cy ;

参考

提示:这里可以添加总结

  1. 图像坐标与世界坐标转换
  2. http://answers.opencv.org/question/62779/image-coordinate-to-world-coordinate-opencv/
  3. https://stackoverflow.com/questions/12299870/computing-x-y-coordinate-3d-from-image-point
  4. https://docs.opencv.org/2.4/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html
  • 19
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦上多多

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值