我目前正在使用名为 procamcalib 的 JavaCV 软件来校准Kinect-Projector设置,该设置以Kinect RGB相机为原点。此设置仅包含Kinect RGB相机(我现在大致使用Kinect作为普通相机)和一台投影仪。该校准软件使用 LibFreenect (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 );
Modelview矩阵设置为:
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-camera直到投影图案匹配印刷图案)。
我的问题是为什么我必须进行此手动调整?模型视图和投影设置应该处理它。
如果在切换这样的驱动程序时出现任何问题,我也会徘徊,因为OpenKinect用于校准,OpenNI用于验证。在研究另一种名为RGBDemo的流行校准工具时会想到这一点,它说如果使用LibFreenect后端,则需要进行Kinect校准。
那么,如果使用驱动程序进行校准并与其他人一起显示,校准是否会出错?
有人认为如果使用OpenCV而不是OpenGL来取得成功会更容易吗?
JavaCV参考:https://code.google.com/p/javacv/
Procamcalib“短文”:http://www.ok.ctrl.titech.ac.jp/~saudet/research/procamcalib/
Procamcalib源代码:https://code.google.com/p/javacv/source/browse?repo=procamcalib
RGBDemo校准参考:http://labs.manctl.com/rgbdemo/index.php/Documentation/Calibration
如果有必要,我可以上传更多内容,让我知道你们需要什么来帮助我:)
答案 0 :(得分:3)
我是您链接的文章的作者,我想我可以提供帮助。
问题在于如何设置模型视图矩阵。当你调用gluLookAt()时,你使用proj_RT的第三列作为相机的位置,但它不是相机的位置,它是相机坐标中世界原点的位置。我为我的新博客撰写了一篇文章,可能有助于澄清这一点。它描述了解释外在矩阵的三种不同(等效)方法,每种方法都有WebGL演示:
http://ksimek.github.io/2012/08/22/extrinsic/
如果您必须使用gluLookAt,本文将向您展示如何,但只需调用glLoadMatrix(proj_RT)
就更简单了。
tl; dr:将gluLookAt()
替换为glLoadMatrix(proj_RT)
答案 1 :(得分:0)
对于Kinect校准,请查看最新的0.7版RGBDemo http://labs.manctl.com/rgbdemo和相应的Freenect calibration source。
来自v0.7.0 ChangeLogs:
自v0.6.1以来的新功能:
- 使用标记获取对象模型的新演示
- rgbd-multikinect的简单校准模式
- 快速抓住rgbd-multikinect
- 保存到磁盘时添加时间戳和相机序列号
- 与PCL 1.4的兼容性各种错误修复
一本非常好的书是Jason McKesson的Learning Modern 3D Graphics Programming你也可以阅读Kinect's ROS page和Nicolas'Kinect Calibration Page