分享

Kinect for Windows SDK v2.0 开发笔记 (三)深度帧与红外帧获取

 quasiceo 2016-03-11

(转载请注明出处)

使用SDK: Kinect for Windows SDK v2.0 public preview

这次就说深度帧的获取与红外帧的获取


Kinect的红外激光装置能够获取空间的深度与红外图像,因为有上次的例子,这次将非常简单。得意


深度值,Kinect用一个16位无符号整数表示深度帧上一个“深素”(深度元素,由图像元素引申),单位是毫米。

目前有效距离是(500, 4500)即半米到四米半。那么怎么可视化它呢,网上有许多深度值可视化的算法,

这里,我们就想一个简单的吧:




距离0: 距离0代表深度值无效,我们给它涂上红色


距离[1, 500), 距离不可靠,我们按照距离,涂上深浅不一的绿色。

具体大致是1涂上RGB(0,129, 0),2涂上(0, 130, 0),一直涂到(0, 255, 0),然后回到起点(0, 128, 0)...反复,

伪代码大致是: 

RGB(0, (get_depth() mod 128)+128, 0)

当然,位运算理论速度快些,所以可以改成

RGB(0, (get_depth() & 0x7F)+128, 0)


距离[4500, +∞),按照上面的算法,涂上[128, 255]的蓝色,即:

RGB(0, 0, (get_depth() mod 128)+128)


距离[500, 4500),按照上面的算法,涂上[0, 255]的灰色,即:

RGB(get_depth() & 0xFF, get_depth() & 0xFF, get_depth() & 0xFF)


差不多就是这样:

  1. auto pRGBXBuffer = m_ImagaRenderer.GetBuffer();  
  2. // 处理算法  
  3. // 0着红色 (0, min)着128~255渐进绿色 大于max的着128~255蓝色 之间的着0~255灰色  
  4. // 不同深度渐进过度  
  5. for (UINT i = 0; i < nBufferSize; ++i){  
  6.     if (!pBuffer[i]){  
  7.         pRGBXBuffer[i].rgbRed = 0xFF;  
  8.         pRGBXBuffer[i].rgbGreen = 0;  
  9.         pRGBXBuffer[i].rgbBlue = 0;  
  10.         pRGBXBuffer[i].rgbReserved = 0xFF;  
  11.     }  
  12.     else if (pBuffer[i] < depth_min_reliable_distance){  
  13.         pRGBXBuffer[i].rgbRed = 0;  
  14.         pRGBXBuffer[i].rgbGreen = pBuffer[i] & 0x7F + 0x80;  
  15.         pRGBXBuffer[i].rgbBlue = 0;  
  16.         pRGBXBuffer[i].rgbReserved = 0xFF;  
  17.     }  
  18.     else if (pBuffer[i] > depth_max_reliable_distance){  
  19.         pRGBXBuffer[i].rgbBlue = pBuffer[i] & 0x7F + 0x80;  
  20.         pRGBXBuffer[i].rgbGreen = 0;  
  21.         pRGBXBuffer[i].rgbRed = 0;  
  22.         pRGBXBuffer[i].rgbReserved = 0xFF;  
  23.     }  
  24.     else{  
  25.         pRGBXBuffer[i].rgbBlue = pBuffer[i] & 0xFF;  
  26.         pRGBXBuffer[i].rgbGreen = pRGBXBuffer[i].rgbBlue;  
  27.         pRGBXBuffer[i].rgbRed = pRGBXBuffer[i].rgbBlue;  
  28.         pRGBXBuffer[i].rgbReserved = 0xFF;  
  29.     }  
  30. }  

至于获取深度的代码怎么写?其实....您可以把上节中的所有带有"ColorFrame"的替换成"DepthFrame"即可,

还有一些细微的差别(比如要获取有效距离啊等等,都是依葫芦画瓢),微软偷懒,咱也偷懒


大家可以结合范例看看

效果:


"少侠!我见你印堂发黑,看来有血光之灾啊!"

"废话,没见到我身边一片红么!"


从图像看出,居然没有绿色,微软偷懒么!

居然没有蓝色!微。。。额,这是我寝室太小了

还有值得注意的是在物体周围是红色的,说明激光的入射角太大,

几乎没有光线再反射回来,于是就是无效的


下载地址:点击这里



第二部分,红外数据的获取。

从Kinect获得的红外红外数据也是一个16位无符号整数,这个整数直接代表了这个点的灰度值。

如果和一代一样的话,这16位只有高10位是有效的,10位灰度,只有高级显示器才能显示,

我们这一般的显示只能显示256级即8位灰度,所以我们应该舍弃其中2位。

请问是舍弃高2位还是低2位呢?请想想。





自然是高2位。。。不能舍弃啦,毕竟比起扔掉1万块相比,我还是愿意扔掉1块钱。

嗯,同上,微软把接口设计的差不多,把上面项目的代码中”DepthFrame“改成"InfraredFrame"估计差不多了,

详细的请看附带的范例,让我们看看效果吧:


范例下载地址:点击这里

从上看出,因为距离比较远(2米开外),导致本人几乎看不到了。为了应付这种情况,微软提供了一组

ILongExposureInfrared开头的对象,有兴趣的朋友可以去看看,这里就不多说了。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多