使用Kinect和OpenGL进行投影映射

Projection Mapping with Kinect and OpenGL

本文关键字:投影 映射 OpenGL Kinect 使用      更新时间:2023-10-16

我目前使用名为procacalibJavaCV软件来校准Kinect投影仪设置,该设置以Kinect RGB相机为原点。该设置仅包括一台Kinect RGB相机(我目前大致使用Kinect作为普通相机(和一台投影仪。此校准软件使用LibFreeconnect(OpenKinect(作为Kinect驱动程序。

一旦软件完成其过程,它将向我提供相机和投影仪的内部和外部参数,这些参数被扔到OpenGL软件上以验证校准,这也是一些问题开始的地方。一旦正确设置了投影和模型视图,我应该能够将Kinect看到的内容与正在投影的内容相匹配,但为了实现这一点,我必须在所有3个轴上进行手动翻译,而最后一部分对我来说毫无意义!你们能帮我整理一下吗?用于检索Kinect数据的SDK是OpenNI(不是最新的2.x版本,应该是1.5.x(

我将准确地解释我正在做什么来重现这个错误。校准参数如下所示:

投影矩阵设置为(基于http://sightations.wordpress.com/2010/08/03/simulating-calibrated-cameras-in-opengl/(:

r = width/2.0f;         l = -width/2.0f;
t = height/2.0f;        b = -height/2.0f;
alpha = fx;      beta = fy;
xo    = cx;      yo   = cy;
X = kinectCalibration.c_near + kinectCalibration.c_far;
Y = kinectCalibration.c_near*kinectCalibration.c_far;
d = kinectCalibration.c_near - kinectCalibration.c_far;

float* glOrthoMatrix = (float*)malloc(16*sizeof(float));
glOrthoMatrix[0] = 2/(r-l); glOrthoMatrix[4] = 0.0f;        glOrthoMatrix[8] = 0.0f;        glOrthoMatrix[12] = (r+l)/(l-r);
glOrthoMatrix[1] = 0.0f;    glOrthoMatrix[5] = 2/(t-b);     glOrthoMatrix[9] = 0.0f;        glOrthoMatrix[13] = (t+b)/(b-t);
glOrthoMatrix[2] = 0.0f;    glOrthoMatrix[6] = 0.0f;        glOrthoMatrix[10] = 2/d;        glOrthoMatrix[14] = X/d;
glOrthoMatrix[3] = 0.0f;    glOrthoMatrix[7] = 0.0f;        glOrthoMatrix[11] = 0.0f;       glOrthoMatrix[15] = 1;
printM( glOrthoMatrix, 4, 4, true, "glOrthoMatrix" );

float* glCameraMatrix = (float*)malloc(16*sizeof(float));
glCameraMatrix[0] = alpha;  glCameraMatrix[4] = skew;   glCameraMatrix[8] = -xo;    glCameraMatrix[12] = 0.0f;
glCameraMatrix[1] = 0.0f;   glCameraMatrix[5] = beta;   glCameraMatrix[9] = -yo;    glCameraMatrix[13] = 0.0f;
glCameraMatrix[2] = 0.0f;   glCameraMatrix[6] = 0.0f;   glCameraMatrix[10] = X;     glCameraMatrix[14] = Y;
glCameraMatrix[3] = 0.0f;   glCameraMatrix[7] = 0.0f;   glCameraMatrix[11] = -1;    glCameraMatrix[15] = 0.0f;
float* glProjectionMatrix = algMult( glOrthoMatrix, glCameraMatrix );

模型视图矩阵设置为:

proj_loc = new Vec3f(   proj_RT[12], proj_RT[13], proj_RT[14] );    
proj_fwd = new Vec3f(   proj_RT[8],  proj_RT[9],  proj_RT[10] );
proj_up  = new Vec3f(   proj_RT[4],  proj_RT[5],  proj_RT[6]  );
proj_trg = new Vec3f(   proj_RT[12] + proj_RT[8], 
                        proj_RT[13] + proj_RT[9], 
                        proj_RT[14] + proj_RT[10] );
gluLookAt( proj_loc[0], proj_loc[1], proj_loc[2],
           proj_trg[0], proj_trg[1], proj_trg[2],
           proj_up[0],  proj_up[1],  proj_up[2] );

最后,相机显示并移动:

glPushMatrix();
glTranslatef(translateX, translateY, translateZ); 
drawRGBCamera();
glPopMatrix();

其中使用键盘手动调整平移值,直到我有视觉匹配(我在校准板上投影Kinect rgb相机看到的内容,所以我手动调整opengl相机,直到投影的图案与打印的图案匹配(。

我的问题是为什么我必须进行手动调整?模型视图和投影设置应该注意这一点。

由于OpenKinect用于校准,OpenNI用于验证,所以我也在犹豫在切换这样的驱动程序时是否有任何问题。这是在研究另一种流行的校准工具RGBDemo时想到的,该工具称,如果使用LibFreenect后端,则需要Kinect校准。

那么,如果用驱动程序进行校准并用另一个驱动程序显示,校准会出错吗

有人认为如果用OpenCV而不是OpenGL来实现成功会更容易吗

JavaCV参考:https://code.google.com/p/javacv/
Procamcalb"短纸":http://www.ok.ctrl.titech.ac.jp/~saudet/research/procacalib/
Procamcalb源代码:https://code.google.com/p/javacv/source/browse?repo=procamcalib
RGB模式校准参考:http://labs.manctl.com/rgbdemo/index.php/Documentation/Calibration

如果需要的话,我可以上传更多的东西,只需让我知道你们需要什么来帮助我:(

我是您链接到的文章的作者,我认为我可以提供帮助。

问题在于如何设置模型视图矩阵。调用gluLookAt((时,使用proj_RT的第三列作为摄影机的位置,但这不是摄影机的位置。它是摄影机坐标中世界原点的位置。我为我的新博客写了一篇文章,可能有助于澄清这一点。它描述了解释外在矩阵的三种不同(等效(方法,每种方法都有WebGL演示:

http://ksimek.github.io/2012/08/22/extrinsic/

如果您必须使用gluLookAt,本文将向您展示如何使用,但只调用glLoadMatrix(proj_RT)要简单得多。

tl;dr:用glLoadMatrix(proj_RT) 替换gluLookAt()

对于Kinect校准,请查看RGBDemo的最新0.7版本http://labs.manctl.com/rgbdemo以及相应的Freenect校准源。

来自v0.7.0 ChangeLogs:

v0.6.1之后的新功能:

  • 使用标记获取对象模型的新演示
  • rgbd multikinect的简单校准模式
  • rgbd multikinect抓取速度更快
  • 保存到磁盘时添加时间戳和相机序列
  • 与PCL 1.4的兼容性各种错误修复

一本很好的书是Jason McKesson的《学习现代3D图形编程》。你也可以阅读Kinect的ROS页面和Nicolas的Kinect校准页面