将Kinect的深度转换为RGB

5

我正在使用OpenNI和OpenCV(但没有最新的支持openni的代码)。如果我只把深度通道发送到屏幕上,它会看起来很暗,很难理解。所以我想展示一个带有颜色的深度通道给用户,但是找不到在不失精度的情况下如何实现。现在我的实现方式是这样的:

xn::DepthMetaData xDepthMap;
depthGen.GetMetaData(xDepthMap);
XnDepthPixel* depthData = const_cast<XnDepthPixel*>(xDepthMap.Data());
cv::Mat depth(frame_height, frame_width, CV_16U, reinterpret_cast<void*>(depthData));

cv::Mat depthMat8UC1;
depth.convertTo(depthMat8UC1, CV_8UC1);

cv::Mat falseColorsMap;
cv::applyColorMap(depthMat8UC1, falseColorsMap, cv::COLORMAP_AUTUMN);
depthWriter << falseColorsMap;

但是在这种情况下,我得到的输出比如 Kinect for Windows 软件显示给我的更差(失去了细节)。因此,我正在寻找 OpenNI 或 OpenCV 中具有更好转换功能的函数。

2个回答

2

以下是直方图均衡化的代码链接:https://github.com/OpenNI/OpenNI2/blob/master/Samples/Common/OniSampleUtilities.h。

简单来说,直方图均衡化使得每个级别的概率相等,并优化了10000个级别和255个级别之间的映射。这就是为什么Kinect黄色地图看起来比天真的I=255*z/z_range更好。

注意:不要使用颜色进行可视化,因为人眼对亮度变化比颜色变化更敏感。因此,使用255个亮度级别可以获得比使用255*255*255个颜色级别更好的对比度。如果您仍然决定沿着颜色映射的道路前进,请使用HSV颜色空间,其中可以操纵Hue 0..360度,Value 1..0,最好将饱和度设置为最大值。将深度映射到色调和值上,转换为RGB并显示。然后返回到直方图均衡化 ;)


最后,将此规范化添加到代码中:https://github.com/KirillLykov/oni2avi/blob/master/oni2avi.cpp - Kirill Lykov

1

试试这个:

const float scaleFactor = 0.05f;
depth.convertTo(depthMat8UC1, CV_8UC1, scaleFactor);
imshow("depth gray",depthMat8UC1);

调整数值以获得您满意的结果


应该将scaleFactor设为255/max(depth)吗? - Kirill Lykov
255.0/4096.0 = 0.062255859375,你可以尝试一下。但在实际应用中,并非所有的4096个值都可用(由于精度呈指数级下降)。如果你只是想为可视化应用不同的映射,可以添加一个滑块来调整比例因子,进行微调以获得所需的缩放/范围。 - George Profenza

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接