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

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


Author:yooongchun, Email:[email protected]


摘要:这篇文章介绍如何在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 SDKs\Kinect\v2.0_1409\inc ,这里*代表你的实际安装地址
      • 库目录下添加***\Microsoft SDKs\Kinect\v2.0_1409\Lib\x86
      • 附加依赖项 里添加kinect20.lib
    • 编写代码获取Kinect2.0设备的图像

    
    #include <kinect.h>
    
    
    #include <iostream>
    
    
    #include <opencv2\opencv.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;
    }

完成!

猜你喜欢

转载自blog.csdn.net/zyc121561/article/details/80226151
今日推荐