《Mastering OpenCV》--3.Markless AR.无标识式AR (2)

第三讲 无标识AR

3.3 模式姿态估计

3.3.1 引理

在三维空间中,可以通过标记角点的精确位置来估计摄像机与标记之间的转换。这个过程叫做二维到三维的姿态估计。这个估计会在物体与摄像机之间找到一个欧氏变换的空间。

è¿éåå¾çæè¿°

如上图所示,C代表相机中心,大写的P1-P4是现实三维世界中的点,p1-p4是物体在相机图像二维平面上投影的点。姿态估计的目标就是找到p1-p4到P1-P4之间的转换关系。回顾slam十四讲,我们可以知道,空间点P首先通过坐标转换,从世界坐标系下转换到相机坐标系下的点(是同一点,但是不同坐标系下的坐标不同,这属于相机外参),再通过针孔相机模型,投影到成像面上(服从相似三角形关系,焦距,像原点之类都有关于相机内参);

\left\{\begin{matrix} P_{uv} = \pmb K P_{c} \\ \widetilde{ P_{c } } = (\pmb T P_{w})_{1:3} \end{matrix}\right.    即        

现在p1-p4是已知的,就是在图像平面求到的pattern的二维坐标点。

那么P1-P4怎么求呢,就需要我们检测到图像上的pattern并发现其四个角点,这里可以通过有标识的AR中的标识去类比理解。

è¿éåå¾çæè¿°

然后借助opencv的solvePnP函数获取欧氏转换[R|T]。 

这个函数求得的变换是相机相对于3维空间中的标记的位置,因此我们必须反转矩阵得到的变换,求出标记在相机坐标系统中的变换,有利于进行三维渲染。 


这里所做的姿态估计和有标识的姿态估计有类似的地方,通常需要2D-3D的对应关系来估计相机的外参。分配四个三维点作为单位矩形的角点,这个矩形位于XY平面,沿着Z轴投影。二维点对应的是图像的位图的角点。

3.3.2 构建pattern对象

在PatternDetector.cpp中,使用buildPatternFromImage函数来创建pattern对象。

角点的设置很有用,因为这个pattern的坐标系将会被直接放在pattern 的中心并处于XY平面内,Z的方向刚好是摄像机的方向。


3.3.3相机内参获取

相机内参可以用OpenCV的示例程序camera_calibration.exe来计算。

用下面的命令行方式执行标定:

imagelist_creator imagelist.yaml *.png
calibration -w 9 -h 6 -o camera_intrinsic.yaml imagelist.yaml

第一条命令将创建 YAML 格式的一个图像列表,标定工具想用当前目录的 PNG 文件作为输入。当然,也可以使用具体的文件名字:例如:img1.png,img2.png 和 img2.png。产生的文件imagelist.yaml 将传递给标定应用程序。同样的,标定工具也可以从摄像机获取图像。


第二条命令是指定标定模式和输入以及标定数据的输出文件的规模。

完成后,会得到一个yaml文件,下面为一个例子

%YAML:1.0
calibration_time: "06/12/12 11:17:56"
image_width: 640
image_height: 480
board_width: 9
[ 110 ]Chapter 3
board_height: 6
square_size: 1.
flags: 0
camera_matrix: !!opencv-matrix
rows: 3
cols: 3
dt: d
data: [ 5.2658037684199849e+002, 0., 3.1841744018680112e+002, 0.,
5.2465577209994706e+002, 2.0296659047014398e+002, 0., 0., 1. ]
distortion_coefficients: !!opencv-matrix
rows: 5
cols: 1
dt: d
data: [ 7.3253671786835686e-002, -8.6143199924308911e-002,
-2.0800255026966759e-002, -6.8004894417795971e-004,
-1.7750733073535208e-001 ]
avg_reprojection_error: 3.6539552933501085e-001

主要关注camera_matrix,一个3x3的矩阵。也就是相机内参

\pmb K =\begin {bmatrix} f_{x}& 0 &c_{x} \\ 0& f_{y}& c_{y} \\ 0 & 0 & 1 \end {bmatrix}

为了估计模型的位置,我们使用 OpenCV 的 cv::solvePnp 函数来解决 PnP 问题。我们需要当前图像上的pattern角点的坐标
和它的 3D reference 坐标(之前已经在pattern里定义了)。


***cv::solvePnP 函数可以在多于四个点下计算。同样的,如果你想创建一个 带有复杂pattern的 AR,它也是关键的函数。思想是一样的,你仅需要定义你的pattern的 3D 结构和相应的二维。 


我们从训练的pattern对象中获取 reference3D 点,并且从 PatternTrackingInfo 结构中获取他们在 2维上的相应的投影。相机标定信息存储在 PatternDetector 私有变量里。



 

你可能感兴趣的:(Mastering,OpenCV)