我使用带有kniect的OpenCV 3.2.1运行VS2010。
我正在使用here
中的教程int main( int argc, char* argv[] ){
VideoCapture capture(CV_CAP_OPENNI); // or CV_CAP_OPENNI
for(;;)
{
Mat depthMap;
Mat bgrImage;
capture.grab();
capture.retrieve( depthMap, CV_CAP_OPENNI_DEPTH_MAP ); // Depth values in mm (CV_16UC1)
capture.retrieve( bgrImage, CV_CAP_OPENNI_BGR_IMAGE );
cout << "rows: " << depthMap.rows << " cols: " << depthMap.cols << endl;
cout << "depth: " << depthMap.at<int>(0,0) << endl;
imshow("RGB image", bgrImage);
if( waitKey( 30 ) >= 0 )
break;
}h
return 0;
运行代码后,我得到以下结果:
靠近一米远的墙壁:
rows: 480 cols: 640
depth: 1157
rows: 480 cols: 640
depth: 1157
rows: 480 cols: 640
depth: 1157
rows: 480 cols: 640
depth: 1157
(Kinect面向墙壁,距离一米多远)
rows: 480 cols: 640
depth: 83690629
rows: 480 cols: 640
depth: 83690629
rows: 480 cols: 640
depth: 83690629
rows: 480 cols: 640
depth: 83690629
rows: 480 cols: 640
depth: 83690629
我被告知这些值实际上是两个像素?我真的不明白。
所以到目前为止我的理解是这样的:
我抓住了一个深度框并将其存储在一个名为depthMap的矩阵中。矩阵的大小现在是640 * 480。我正在使用代码depthMap.at(0,0)从第0行第0列获取第一个深度值。但不是以毫米为单位返回结果,而是返回83690629!这是我想要的最大值10000的方式
如何将这些值转换为毫米,以便我可以使用它们?谢谢
答案 0 :(得分:1)
深度图数据是单通道无符号16Bit。
尝试将int
替换为CV_16UC1
答案 1 :(得分:1)
我目前正在使用kinect(+ OpenNi + OpenCv),我不知道你是否还在处理你的问题。
我尝试使用完全相同的代码,但使用depthMap.at<unsigned short>(i,j)
并且效果非常好,给我的值为mm(当我距离kinect 50厘米时为502)
问题是:我不知道深度值是如何传递的,我在互联网上看到了很多矛盾的信息。为什么它是2像素?为什么要转换为Hex?
我敢肯定,我不会在这里努力理解基本原则。那么,有人在kinect深度上有一些可靠的文档吗?
(我读过有关stephane Magnenat / Nicolas Burrus的公式:11位上的kinect原始数据,添加了一些几何等等......但是OpenNi是否已经处理了这个并且提供了深度原样?)
随意发表评论。 欢呼声。
答案 2 :(得分:1)
深度值以11位存储,封装在16位变量中。
因此,当您访问矩阵时,您必须提供正确的元素数据类型。
如前所述,您可以使用depthMap.at<unsigned short>(i,j)
,但必须确保unsigned short
在所有编译器中都是16位长。
我更喜欢使用uint16_t
数据类型。
此外,根据您选择的openni PIXEL_FORMAT,存储在矩阵内的深度值可以是:
您可以使用void openni::VideoMode::setPixelFormat(PixelFormat)
函数设置pixel_format
http://www.openni.ru/wp-content/doxygen/html/classopenni_1_1_video_mode.html#af7fd37bba526fced9c7dbbbf1ab419ea
如果你想要更精确的数据(PIXEL_FORMAT_DEPTH_100_UM
)以毫米为单位,你可以将其转换为浮动并将其除以10:
uint16_t redValue = depthMap.at<uint16_t>(i,j);
float myVal = ( (float) redValue ) / 10.0f;
答案 3 :(得分:0)
检查正确的数据类型,调试模式,然后检查具有矩阵的断点,然后检查文件数据类型