我正在使用OpenCV处理给定的数据集,而我没有任何Kinect。我想将给定的深度数据映射到RGB对应物(这样我就可以得到实际的颜色和深度)
由于我使用的是OpenCV和C ++,并且没有Kinect,遗憾的是我无法使用官方Kinect API中的MapDepthFrameToColorFrame方法。
根据给定的相机的内在函数和失真系数,我可以根据提供的算法将深度映射到世界坐标,然后回到RGB here
Vec3f depthToW( int x, int y, float depth ){
Vec3f result;
result[0] = (float) (x - depthCX) * depth / depthFX;
result[1] = (float) (y - depthCY) * depth / depthFY;
result[2] = (float) depth;
return result;
}
Vec2i wToRGB( const Vec3f & point ) {
Mat p3d( point );
p3d = extRotation * p3d + extTranslation;
float x = p3d.at<float>(0, 0);
float y = p3d.at<float>(1, 0);
float z = p3d.at<float>(2, 0);
Vec2i result;
result[0] = (int) round( (x * rgbFX / z) + rgbCX );
result[1] = (int) round( (y * rgbFY / z) + rgbCY );
return result;
}
void map( Mat& rgb, Mat& depth ) {
/* intrinsics are focal points and centers of camera */
undistort( rgb, rgb, rgbIntrinsic, rgbDistortion );
undistort( depth, depth, depthIntrinsic, depthDistortion );
Mat color = Mat( depth.size(), CV_8UC3, Scalar(0) );
ushort * raw_image_ptr;
for( int y = 0; y < depth.rows; y++ ) {
raw_image_ptr = depth.ptr<ushort>( y );
for( int x = 0; x < depth.cols; x++ ) {
if( raw_image_ptr[x] >= 2047 || raw_image_ptr[x] <= 0 )
continue;
float depth_value = depthMeters[ raw_image_ptr[x] ];
Vec3f depth_coord = depthToW( y, x, depth_value );
Vec2i rgb_coord = wToRGB( depth_coord );
color.at<Vec3b>(y, x) = rgb.at<Vec3b>(rgb_coord[0], rgb_coord[1]);
}
}
但结果似乎是错位的。我无法手动设置翻译,因为数据集是从3个不同的Kinects获得的,并且每个Kinect都在不同的方向上未对齐。您可以在下方看到其中一个(左:未失真的RGB,中间:未失真的深度,右:将RGB映射到深度)
我的问题是,此时我该怎么办?在尝试将世界或世界的深度投射回RGB时,我是否错过了一步?任何有立体相机经验的人都可以指出我的错误吗?
答案 0 :(得分:1)
我假设您需要使用RGB数据校准深度传感器,就像校准立体相机一样。 OpenCV有一些你可以利用的功能(和教程)。
其他一些可能有用的东西
答案 1 :(得分:0)
OpenCV没有将深度流与彩色视频流对齐的功能。但我知道“Kinect for Windows SDK”中有special function名为MapDepthFrameToColorFrame
。
我没有代码,但希望这是开始的好点。
UPD: Here is使用带有OpenCV接口的KinectSDK(不是我的代码)将彩色图像映射到深度的相同示例。
答案 2 :(得分:0)
看起来你没有在你的解决方案中考虑两个相机之间的外在性。
答案 3 :(得分:0)
是的,你没有考虑RGB和深度之间的转换。 但是你可以使用cvStereoCalibrate()方法计算这个矩阵,该方法只传递RGB和深度的图像序列以及棋盘角。 您可以在OpecvCV文档中找到详细信息: http://docs.opencv.org/2.4/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html#double stereoCalibrate(InputArrayOfArrays objectPoints,InputArrayOfArrays imagePoints1,InputOutrayArrays cameraMaints2,InputOutputArray distCoeffs1,InputOutputArray cameraMatrix2,InputOutputArray distCoeffs2,Size imageSize,OutputArray R,OutputArray T,OutputArray E,OutputArray F,TermCriteria criteria,int flags)< / p>
这背后的整个方法理念是:
color uv&lt; - color normalize&lt; - color space&lt; - DtoC transformation&lt; - depth space&lt; - depth normalize&lt; - depth uv (uc,vc)&lt; - &lt; - ExtrCol *(pc)&lt; - 立体校准MAT&lt; - ExtrDep ^ -1 *(pd)&lt; - &lt;(ud - cx)* d / fx,(vd -cy)* d / fy,d&gt; &lt; - (ud,vd)
如果要为RGB添加失真,只需按照以下步骤操作即可: http://docs.opencv.org/2.4/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html