使用Kinect和OpenGL进行投影映射
Projection Mapping with Kinect and OpenGL
我目前使用名为procacalib的JavaCV软件来校准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校准页面
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 将函数类成员映射到类本身内部
- 如何在 C# 中映射双 C 结构指针?
- 如何在C++中使用结构生成映射
- 使用std::函数映射对象方法
- 如何加载(或映射)文件部分的最大大小,但适合在Windows上的RAM
- C++映射分割错误(核心转储)
- 内联映射初始化的动态atexit析构函数崩溃
- 使用"std::unordereded_map"映射到"std::list"对象
- 如何从多映射中删除特定的重复项
- 在未初始化映射的情况下,将值插入到映射的映射中
- QT通过C++添加映射QML项目
- 在c++中访问int到类对象的映射时出错
- 在C++中搜索嵌套多映射值
- 错误处理.将系统错误代码映射到泛型
- OpenGL 透视投影裁剪多边形与顶点在视锥体之外 = 错误的纹理映射?
- 在C++中的OpenGL中将坐标从三维透视投影映射到二维正投影
- OpenGL透视投影来映射屏幕像素
- 使用Kinect和OpenGL进行投影映射