我正在开展一个项目,我需要使用Kinect One,我对那种传感器没有那么多的经验(既不是新的也不是旧的kinect) . 因此我开始玩它,我成功地使用Kinect SDK v2.0和opencv获取图像 . 现在我想做的是从rgb传感器和红外/深度传感器覆盖两个视图,以创建一个rgb-d图像 . Kinect SDK为此提供了一个类,名为CoordinateMapper,但没有提供足够的结果(速度和质量),而且我面临@ api55描述here的问题 . 因此,我想尝试手动执行此操作,以及学习原因 . 彩色摄像机具有全高清分辨率(1920x1080像素),深度/红外图像分别为512x424像素 . 此外,两个传感器具有不同的纵横比 . 搜索我发现正确的方法是首先校准两个传感器,然后在两个视图之间应用任何映射 .

我将使用opencv进行校准和映射程序 . 对于校准,我注意到这里的人们一般都建议如果我首先使用 calibrate() 函数单独校准两个传感器,然后将提取的cameraMatrix /内部和失真系数/ distCoeffs值用于 stereoCalibrate() 函数,以便更好获得旋转(R)和平移(T)矩阵以及其他一些矩阵,例如R1,R2,P1,P2,Q等......稍后需要进行映射 . 使用非对称圆网格图案我设法分别校准每个传感器的初始分辨率和纵横比,分别获得rgb和ir传感器的重投影误差rms为0.3和0.1 . 将提取的值传递给带有 CV_CALIB_USE_INTRINSIC_GUESSCV_CALIB_FIX_INTRINSICstereoCalibrate() 我设法获得具有重投影误差的R和T矩阵,rms = ~0.4看起来也是好的 .


Question 1

然而,在我继续之前,这里我有一个问题 stereoCalibrate() 有一个关于图像大小的参数,我使用了红外相机的大小,因为后来我想使用这个分辨率来映射两个视图 . 另一方面,我在某处读到它没有任何作用,因为它只对内部摄像机校准中的初始化有用(根据openCV文档),如果使用参数 CALIB_FIX_INTRINSIC 调用 stereoCalibrate() 是正确的话,则不使用它?此外,你认为我应该将高分辨率相机的大小调整到较小的相机的大小,因为我将在后面使用后者进行映射 . 我想我需要应用一些裁剪,因为不同的方面比例,对吧?或者没有必要 .


在没有调整大小和裁剪的情况下继续进行,我设法从 stereoRectify() 函数获得了非失真和纠正所需的所有必要信息 . 所以,我已经成功获得了cameraMatrix,distCoeffs,R,T,R1,R2,P1,P2,Q矩阵 . 现在尝试不扩地/纠正并重新映射两个视图的初始大小我得到了以下结果:

enter image description here

enter image description here

这看起来相当不错,除了第一张图片周围的戒指,我不知道它是什么,如果有人能解释我,我会很感激 . 我的猜测很可能是校准错误的结果?此外,在 initUndistortRectifyMap() 我使用大分辨率传感器的大小,否则我得到一些完全错误的东西,我不明白,如果有人可以解释 .

现在,如果我在任何校准(未应用裁剪)之前调整大分辨率图像的大小,我会得到更好的结果:

enter image description here

enter image description here

当然,正如你所看到的,由于纵横比,图像是完全不同的 .


Question 2

所以再次从问题1继续,正确的方法是什么,我可以使用他们的初始大小的图像,或者我应该调整它们的大小,我是否应该也应用裁剪?我在程序中做错了什么?



Question 3

考虑到我将在校准/失真/校正之后设法获得两个视图我如何覆盖它们?我有两个传感器和R,T,R1,R2,P1,P2,Q矩阵的rgb和深度图像,cameraMatric和distCoeffs . 我读到我可以使用cv :: projectPoints但我找不到一个例子 . 如果有人给我一些提示,我将不胜感激 .

提前致谢 .

附:我可以提供一些代码是必要的,暂时有点乱,但如果它对我没有任何问题 .