zoukankan      html  css  js  c++  java
  • windows10环境下使用Kinect2.0获取RGB-D图片

    windows10环境下使用Kinect2.0获取RGB-D图片


    Author:yooongchun, Email:yooongchun@foxmail.com


    摘要:这篇文章介绍如何在Windows10环境下使用C++程序驱动Kinect2.0获取RGB-D图片


    • STEP 1 :安装Kinect2.0 SDK

      Kinect2.0设备需要使用usb3.0接口,所以,首先要保证你接入的接口一定是USB3.0!

      接下来,在官网上下载Kinect2.0的SDK :

      https://www.microsoft.com/en-hk/download/confirmation.aspx?id=44561

      下载之后安装,安装完成后会有一个Kinect2.0 SDK和一个Kinect2.0 Studio

      将Kinect2.0设备连接到电脑上,然后打开Kinect2.0 Studio,这时可看到Kinect2.0摄像头的实时镜头照片,表示Kinect2.0安装完成。

    • STEP 2 :获取RGB-D图像

      Kinect2.0 Studio能看到实时的图像,但是没法保存下来,要保存Kinect2.0的照片需要我们调用其SDK来编程获得。

      我们这里使用VS2013+Kinect2.0 SDK 环境来编写代码。

      • 配置Kinect2.0 SDK的开发环境

      安装好Kinect2.0 SDK之后要在VS2013工程环境中使用还需要配置。

      • 新建一个x86的VS2013的工程,注意,楼主这里使用x64 工程时Kinect2.0 SDK出错,因而建议使用x86工程
      • 配置工程:

        • 包含目录下添加:***Microsoft SDKsKinectv2.0_1409inc ,这里*代表你的实际安装地址
        • 库目录下添加***Microsoft SDKsKinectv2.0_1409Libx86
        • 附加依赖项 里添加kinect20.lib
      • 编写代码获取Kinect2.0设备的图像

      
      #include <kinect.h>
      
      
      #include <iostream>
      
      
      #include <opencv2opencv.hpp>
      
      
      #include <opencv2/core/core.hpp>  
      
      
      #include <opencv2/highgui/highgui.hpp>  
      
      
      using namespace cv;
      using namespace std;
      
      // 安全释放指针
      template<class Interface>
      inline void SafeRelease(Interface *& pInterfaceToRelease)
      {
          if (pInterfaceToRelease != NULL)
          {
              pInterfaceToRelease->Release();
              pInterfaceToRelease = NULL;
          }
      }
      
      int GetPicture()
      {
          // 获取Kinect设备
          IKinectSensor* m_pKinectSensor;
          HRESULT hr;
          hr = GetDefaultKinectSensor(&m_pKinectSensor);
          if (FAILED(hr))
          {
              return hr;
          }
      
          IMultiSourceFrameReader* m_pMultiFrameReader;
          if (m_pKinectSensor)
          {
              hr = m_pKinectSensor->Open();
              if (SUCCEEDED(hr))
              {
                  // 获取多数据源到读取器  
                  hr = m_pKinectSensor->OpenMultiSourceFrameReader(
                      FrameSourceTypes::FrameSourceTypes_Color |
                      FrameSourceTypes::FrameSourceTypes_Infrared |
                      FrameSourceTypes::FrameSourceTypes_Depth,
                      &m_pMultiFrameReader);
              }
          }
      
          if (!m_pKinectSensor || FAILED(hr))
          {
              return E_FAIL;
          }
          // 三个数据帧及引用
          IDepthFrameReference* m_pDepthFrameReference;
          IColorFrameReference* m_pColorFrameReference;
          IInfraredFrameReference* m_pInfraredFrameReference;
          IInfraredFrame* m_pInfraredFrame;
          IDepthFrame* m_pDepthFrame;
          IColorFrame* m_pColorFrame;
          // 三个图片格式
          Mat i_rgb(1080, 1920, CV_8UC4);      //注意:这里必须为4通道的图,Kinect的数据只能以Bgra格式传出
          Mat i_depth(424, 512, CV_8UC1);
          Mat i_ir(424, 512, CV_16UC1);
      
          UINT16 *depthData = new UINT16[424 * 512];
          IMultiSourceFrame* m_pMultiFrame = nullptr;
          int sample_id = 1;
          while (true)
          {
              // 获取新的一个多源数据帧
      
              hr = m_pMultiFrameReader->AcquireLatestFrame(&m_pMultiFrame);
              if (FAILED(hr) || !m_pMultiFrame)
              {
                  cout << "!!!" << endl;
                  continue;
              }
      
              // 从多源数据帧中分离出彩色数据,深度数据和红外数据
              if (SUCCEEDED(hr))
                  hr = m_pMultiFrame->get_ColorFrameReference(&m_pColorFrameReference);
              if (SUCCEEDED(hr))
                  hr = m_pColorFrameReference->AcquireFrame(&m_pColorFrame);
              if (SUCCEEDED(hr))
                  hr = m_pMultiFrame->get_DepthFrameReference(&m_pDepthFrameReference);
              if (SUCCEEDED(hr))
                  hr = m_pDepthFrameReference->AcquireFrame(&m_pDepthFrame);
              if (SUCCEEDED(hr))
                  hr = m_pMultiFrame->get_InfraredFrameReference(&m_pInfraredFrameReference);
              if (SUCCEEDED(hr))
                  hr = m_pInfraredFrameReference->AcquireFrame(&m_pInfraredFrame);
      
              // color拷贝到图片中
              UINT nColorBufferSize = 1920 * 1080 * 4;
              if (SUCCEEDED(hr))
                  hr = m_pColorFrame->CopyConvertedFrameDataToArray(nColorBufferSize, reinterpret_cast<BYTE*>(i_rgb.data), ColorImageFormat::ColorImageFormat_Bgra);
      
              // depth拷贝到图片中
              if (SUCCEEDED(hr))
              {
                  hr = m_pDepthFrame->CopyFrameDataToArray(424 * 512, depthData);
                  for (int i = 0; i < 512 * 424; i++)
                  {
                      // 0-255深度图,为了显示明显,只取深度数据的低8位
                      BYTE intensity = static_cast<BYTE>(depthData[i] % 256);
                      reinterpret_cast<BYTE*>(i_depth.data)[i] = intensity;
                  }
      
                  // 实际是16位unsigned int数据
                  //hr = m_pDepthFrame->CopyFrameDataToArray(424 * 512, reinterpret_cast<UINT16*>(i_depth.data));
              }
      
              // infrared拷贝到图片中
              if (SUCCEEDED(hr))
              {
                  hr = m_pInfraredFrame->CopyFrameDataToArray(424 * 512, reinterpret_cast<UINT16*>(i_ir.data));
              }
      
              // 显示
              imshow("rgb", i_rgb);
              if (waitKey(1) == VK_ESCAPE)
                  break;
              imshow("depth", i_depth);
              if (waitKey(1) == VK_ESCAPE)
                  break;
              imshow("ir", i_ir);
              if (waitKey(1) == VK_ESCAPE)
                  break;
              //waitKey(0);
              /*string s1 = "C:\Users\mataiyuan\Desktop\yooongchun\dataset\sample-";
              string s2 = "-rgb.png";
              string s3 = "-depth.png";
              string s4 = "-infrared.png";
              cvSaveImage((s1 + to_string(sample_id) + s2).c_str(), &IplImage(i_rgb));
              cvSaveImage((s1 + to_string(sample_id) + s3).c_str(), &IplImage(i_depth));
              cvSaveImage((s1 + to_string(sample_id) + s4).c_str(), &IplImage(i_ir));
              sample_id += 1;*/
      
              // 释放资源
              SafeRelease(m_pColorFrame);
              SafeRelease(m_pDepthFrame);
              SafeRelease(m_pInfraredFrame);
              SafeRelease(m_pColorFrameReference);
              SafeRelease(m_pDepthFrameReference);
              SafeRelease(m_pInfraredFrameReference);
              SafeRelease(m_pMultiFrame);
          }
          // 关闭窗口,设备
          cv::destroyAllWindows();
          m_pKinectSensor->Close();
      }
      int main()
      {
          GetPicture();
          std::system("pause");
          return 0;
      }

    完成!

  • 相关阅读:
    WebGL学习笔记(一)
    svn和ftp的不同应用场合
    Java 开源博客 Solo 1.8.0 发布
    【C解毒】滥用变量
    【C解毒】答非所问
    【C解毒】错题无解
    【C解毒】怎样写main()函数
    程序员约架事件中,薛非到底是因为不会用Github还是不会写Tokenizer而没有应战?
    『一些同学学不好C语言,把罪责归于「因为教材是谭浩强写的」实在是很滑稽』吗?
    挂羊头卖狗肉蓄意欺骗读者——谭浩强《C程序设计(第四版)》中所谓的“按照C99”(二)
  • 原文地址:https://www.cnblogs.com/yczha/p/13160245.html
Copyright © 2011-2022 走看看