OpenCV (相机姿态还原)
在已知物体三维结构的情况下,如何计算出相机的姿态。
三维姿态
solvePnP
官方解释:
http://docs.opencv.org/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html#solvepnp
1 | bool solvePnP(InputArray objectPoints, InputArray imagePoints, InputArray cameraMatrix, InputArray distCoeffs, OutputArray rvec, OutputArray tvec,bool useExtrinsicGuess=false, int flags=ITERATIVE ) |
注意,OpenCV 中还提供了 SolvePnPRansac
函数。它使用 RANSAC
算法求解 PnP
问题。这个函数能识别出错误的物体点/图像点对,并将其标记为异常数据。
RANSAC(随机抽样一致性)
用于匹配图像的算法
https://zhuanlan.zhihu.com/p/45532306
https://blog.csdn.net/weixin_42990464/article/details/119254747
cvPOSIT
官方解释:
1 | void cvPOSIT( CvPOSITObject* posit_object, CvPoint2D32f* image_points, double focal_length, CvTermCriteria criteria, CvMatr32f rotation_matrix, CvVect32f translation_vector ) |
两种函数的同与异
同:
- 输入都是
3D
点集和对应的2D
点集,其中cvPOSIT
的3D
点包含在posit_object
结构中 - 输出包括旋转矩阵和位移向量
异:
solvePnP
调用的是cvFindExtrinsicCameraParams2
通过已知的内参进行未知外参求解,是一个精确解;而cvPOSIT
是用仿射投影模型近似透视投影模型下,不断迭代计算出来的估计值(在物体深度变化相对于物体到摄像机的距离比较大的时候,这种算法可能不收敛)solvePnP
输出的rvec
是旋转向量,可以通过Rodrigues
转换成旋转矩阵,有需要可以再转到欧拉角
实现
公园里的长椅
用标定的相机进行拍照 并 标注8个点
测量长椅的物理尺寸
椅座:242.5cm53.5cm\9cm
靠背:242.5cm24cm\9cm
两者相距 12cm
推导八个点的三维坐标
设椅座与靠背的交叉线的左侧顶点作为坐标系原点
1 | vector<Point3f> objectPoints; |
在二维成像平面中,写出这些点的坐标
1 | vector<Point2f> imagePoints; |
调用 solvePnP
函数,计算拍照时相机与这些点之间的相对位置
此函数实际上是通过旋转和平移,把物体坐标转换到以相机为中心的坐标系上(焦点为坐标原点)
注意,该函数得到的旋转量是一个三维容器。表示物体绕着一个单位向量(旋转轴)转了某个角度。(轴 + 角度,罗德里格旋转公式 )。在 OpenCV 中,旋转角度对应着输出的旋转向量的值,该向量与旋转轴一致,所以,投影公式中使用 Rodrigues
函数来获取旋转三维矩阵。
1 | Mat rvec, tvec; |
检验
使用 cv::viz
模块可以显示三维信 息
cv::viz:: ...
使用样例
1 | cv::viz::Viz3d visualizer("Viz window"); // 创建窗口 |
相机姿态更新
https://blog.csdn.net/aptx704610875/article/details/48915149
- Post title:OpenCV (相机姿态还原)
- Post author:Eva.Q
- Create time:2021-08-02 10:48:21
- Post link:https://qyy/2021/08/02/OPENCV/OPENCV1-4/
- Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.