原文:
http://blog.csdn.NET/chenyusiyuan/article/details/5970799
在获取到视差数据后,利用 OpenCV 的 reProjectImageTo3D 函数结合 Bouquet 校正方法得到的 Q 矩阵就可以得到环境的三维坐标数据,然后利用
OpenGL 来实现三维重构。 OpenCV 与 OpenGL 的编程范例,我在 学习笔记( 15 )中有详细的讨论,这里就不重复了,下面补充一些细节问题:
.
.
1. reProjectImageTo3D 是怎样计算出三维坐标数据的?
图 22
.
相信看过 OpenCV 第 12 章的朋友对上图中的 Q 矩阵不会陌生,根据以上变换公式,按理说 OpenCV 应该也是通过矩阵运算的方式来计算出三维坐标数据的,但实际上仔细查看源代码,会发现 cvReprojectImageTo3D 用了比较奇怪的方法来实现,主要代码如下:
02737 for( y = 0; y
02738 {
02739 const float* sptr = (const float*)(src->data.ptr + src->step*y); // 视差矩阵指针
02740 float* dptr0 = (float*)(dst->data.ptr + dst->step*y), *dptr = dptr0; // 三维坐标矩阵指针
// 每一行运算开始时,用 当前行号y 乘以Q阵第2列、再加上Q阵第4列,作为初始值
// 记 qq=[qx, qy, qz, qw]’
02741 double qx = q[0][1]*y + q[0][3], qy = q[1][1]*y + q[1][3];
02742 double qz = q[2][1]*y + q[2][3], qw = q[3][1]*y + q[3][3];
…
// 每算完一个像素的三维坐标,向量qq 累加一次q阵第1列
// 即:qq = qq + q(:,1)
02769 for( x = 0; x
02770 {
02771 double d = sptr[x];
// 计算当前像素三维坐标
// 将向量qq 加上 Q阵第3列与当前像素视差d的乘积,用所得结果的第4元素除前三位元素即可
// [X,Y,Z,W]’ = qq + q(:,3) * d; iW = 1/W; X=X*iW; Y=Y*iW; Z=Z*iW;
02772 double iW = 1./(qw + q[3][2]*d);
02773 double X = (qx + q[0][2]*d)*iW;
02774 double Y = (qy + q[1][2]*d)*iW;
02775 double Z = (qz + q[2][2]*d)*iW;
02776 if( fabs(d-minDisparity) <= FLT_EPSILON