VS 2015+Kinect V 2 SDK+Opencvによる奥行き画像表示および記憶を実現


Opencv環境の設定
  • VS 2015を開き、新しいC++プロジェクト(空白プロジェクト)を作成します.
  • 【ソリューションエクスプローラ】で項目名を右クリックし、【プロパティ】->「プラットフォーム」を選択【x 64】を選択し、【プロパティ】->「構成」を選択【Debug】
  • を選択
  • 【ソリューションエクスプローラ】で項目名を右クリックし、【プロパティ】->「構成プロパティ」->「VC++ディレクトリ」->「一般」->「ディレクトリを含む」を選択し、以下の内容を追加【D:OpenCVbuildincludeopencv 2】および【D:OpenCVbuildinclude】
  • 【ソリューションエクスプローラ】でアイテム名を右クリックし、【プロパティ】->「構成プロパティ」->「VC++ディレクトリ」->「一般」->「ライブラリディレクトリ」を選択して、次の内容を追加します【D:OpenCVbuildx 64vc 15lib】
  • [ソリューションエクスプローラ]でプロジェクト名を右クリックし、[プロパティ]->「構成プロパティ」->「入力」->「依存項目の追加」を選択し、次のように追加します[opencv_world 410 d.lib]
  • Kinect V 2 SDK環境の構成
  • 【ソリューションエクスプローラ】で項目名を右クリックし、【プロパティ】->「プラットフォーム」を選択【x 64】を選択し、【プロパティ】->「構成」を選択【Debug】
  • を選択
  • 【ソリューションエクスプローラ】でアイテム名を右クリックし、【プロパティ】->「構成プロパティ」->「VC++ディレクトリ」->「一般」->「ディレクトリを含む」を選択して、次の内容を追加します【C:Program FilesMicrosoft SDKsKinectv 2.0_1409inc】
  • [ソリューションエクスプローラ]でプロジェクト名を右クリックし、[プロパティ]->「構成プロパティ」->「VC++ディレクトリ」->「一般」->「ライブラリディレクトリ」を選択して、次の内容を追加します【C:Program FilesMicrosoft SDKsKinectv 2.0_1409Libx 64]
  • [ソリューションエクスプローラ]でプロジェクト名を右クリックし、[プロパティ]->「構成プロパティ」->「入力」->「依存項目の追加」を選択し、次のように追加します[kinect 20.lib]
  • 構成Kinect.hファイル
  • [Kinect.h]が見つからない場合は、[ソリューションエクスプローラ]->「ヘッダファイル」->「マウス右クリック[追加]->「既存のアイテム」->「Kinect.h」(その経路[C:Program FilesMicrosoft SDKsKinectv 2.0_1409inc])
  • をクリックして解決します.
    深さ画像を表示および格納するインスタンスコードの作成
     
    #include 
    #include  
    #include 
    #include 
    #include 
    
    using namespace std;
    using namespace cv;
    
    // Safe release for interfaces
    template
    inline void SafeRelease(Interface *& pInterfaceToRelease)
    {
    	if (pInterfaceToRelease != NULL)
    	{
    		pInterfaceToRelease->Release();
    		pInterfaceToRelease = NULL;
    	}
    }
    
    Mat ConvertMat(const UINT16* pBuffer, int nWidth, int nHeight, USHORT nMinDepth, USHORT nMaxDepth)
    {
    	cv::Mat img(nHeight, nWidth, CV_8UC3);
    	uchar* p_mat = img.data;
    	const UINT16* pBufferEnd = pBuffer + (nWidth * nHeight);
    	while (pBuffer < pBufferEnd)
    	{
    		USHORT depth = *pBuffer;
    		BYTE intensity = static_cast((depth >= nMinDepth) && (depth <= nMaxDepth) ? (depth % 256) : 0);
    		*p_mat = intensity;
    		p_mat++;
    		*p_mat = intensity;
    		p_mat++;
    		*p_mat = intensity;
    		p_mat++;
    		++pBuffer;
    	}
    	return img;
    }
    
    void main()
    {
    	// Get and initialize the default Kinect sensor
    	IKinectSensor* m_pKinectSensor = NULL;
    	// Depth reader  
    	IDepthFrameReader* m_pDepthFrameReader = NULL;
    	HRESULT hr;
    	hr = GetDefaultKinectSensor(&m_pKinectSensor);
    	if (FAILED(hr))
    	{
    		cout << "open kinectsensor failed " << endl;
    	}
    	if (m_pKinectSensor)
    	{
    		// Initialize the Kinect and get the depth reader
    		IDepthFrameSource* pDepthFrameSource = NULL;
    		hr = m_pKinectSensor->Open();
    		if (SUCCEEDED(hr))
    		{
    			hr = m_pKinectSensor->get_DepthFrameSource(&pDepthFrameSource);
    		}
    		if (SUCCEEDED(hr))
    		{
    			hr = pDepthFrameSource->OpenReader(&m_pDepthFrameReader);
    		}
    		SafeRelease(pDepthFrameSource);
    	}
    	if (!m_pKinectSensor || FAILED(hr))
    	{
    		cout << "No ready Kinect found!" << endl;
    	}
    	Mat qImg;
    	while (1)
    	{
    		if (!m_pDepthFrameReader)
    		{
    			return;
    		}
    		IDepthFrame* pDepthFrame = NULL;
    		HRESULT hr = m_pDepthFrameReader->AcquireLatestFrame(&pDepthFrame);
    		if (SUCCEEDED(hr))
    		{
    			INT64 nTime = 0;
    			IFrameDescription* pFrameDescription = NULL;
    			int nWidth = 0;
    			int nHeight = 0;
    			USHORT nDepthMinReliableDistance = 0;
    			USHORT nDepthMaxDistance = 0;
    			UINT nBufferSize = 0;
    			UINT16 *pBuffer = NULL;
    			hr = pDepthFrame->get_RelativeTime(&nTime);
    			if (SUCCEEDED(hr))
    			{
    				hr = pDepthFrame->get_FrameDescription(&pFrameDescription);
    			}
    			if (SUCCEEDED(hr))
    			{
    				hr = pFrameDescription->get_Width(&nWidth);
    			}
    			if (SUCCEEDED(hr))
    			{
    				hr = pFrameDescription->get_Height(&nHeight);
    			}
    			if (SUCCEEDED(hr))
    			{
    				hr = pDepthFrame->get_DepthMinReliableDistance(&nDepthMinReliableDistance);
    			}
    			if (SUCCEEDED(hr))
    			{
    				// In order to see the full range of depth (including the less reliable far field depth)
    				// we are setting nDepthMaxDistance to the extreme potential depth threshold
    				nDepthMaxDistance = USHRT_MAX;
    
    				// Note:  If you wish to filter by reliable depth distance, uncomment the following line.
    				//// hr = pDepthFrame->get_DepthMaxReliableDistance(&nDepthMaxDistance);
    			}
    			if (SUCCEEDED(hr))
    			{
    				hr = pDepthFrame->AccessUnderlyingBuffer(&nBufferSize, &pBuffer);
    			}
    			if (SUCCEEDED(hr))
    			{
    				Mat depthImg_show = cv::Mat::zeros(nHeight, nWidth, CV_8UC3);
    				depthImg_show = ConvertMat(pBuffer, nWidth, nHeight,
    					nDepthMinReliableDistance, nDepthMaxDistance);
    				qImg = depthImg_show.clone();
    				imwrite("depth.jpg", qImg);
    				imshow("depth", depthImg_show);
    			}
    			SafeRelease(pFrameDescription);
    		}
    		SafeRelease(pDepthFrame);
    		if (waitKey(20) == VK_ESCAPE)
    			break;
    	}
    	// done with depth frame reader
    	SafeRelease(m_pDepthFrameReader);
    	// close the Kinect Sensor
    	if (m_pKinectSensor)
    	{
    		m_pKinectSensor->Close();
    	}
    	SafeRelease(m_pKinectSensor);
    }

    深さ図、赤外線図、カラー図の表示を実現
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    using namespace cv;
    using namespace std;
    
    void GetColorDepthInfrared()
    {
        IKinectSensor*          m_pKinectSensor;
    
        IDepthFrameReader*      m_pDepthFrameReader;
        IDepthFrameSource*      pDepthFrameSource = NULL;
    
        IInfraredFrameSource*   pInfraredFrameSource = NULL;
        IInfraredFrameReader*   InfraredFrameReader;
    
        IColorFrameReader*      ColorFrameReader = NULL;
        IColorFrameSource*      ColorFrameSource = NULL;
    
        IFrameDescription*      FrameDescription = NULL;
    
        GetDefaultKinectSensor(&m_pKinectSensor);     
        //     
        m_pKinectSensor->Open();
    
    
        m_pKinectSensor->get_DepthFrameSource(&pDepthFrameSource);
    
        m_pKinectSensor->get_InfraredFrameSource(&pInfraredFrameSource);
    
        m_pKinectSensor->get_ColorFrameSource(&ColorFrameSource);
    
        pDepthFrameSource->OpenReader(&m_pDepthFrameReader);
    
        pInfraredFrameSource->OpenReader(&InfraredFrameReader);
    
        ColorFrameSource->OpenReader(&ColorFrameReader);
    
        while (true)
        {
            IInfraredFrame*       InfraredFrame = NULL;
            IDepthFrame*          pDepthFrame = NULL;
            IColorFrame*          pColorFrame = NULL;
    
    
            while (pDepthFrame == NULL){
                m_pDepthFrameReader->AcquireLatestFrame(&pDepthFrame);
            }
            pDepthFrameSource->get_FrameDescription(&FrameDescription);
            int depth_width, depth_height;
    
            FrameDescription->get_Width(&depth_width);
            FrameDescription->get_Height(&depth_height);
    
            Mat DepthImg(depth_height, depth_width, CV_16UC1);
            pDepthFrame->CopyFrameDataToArray(depth_height * depth_width, (UINT16 *)DepthImg.data);
    
            //   8   
            DepthImg.convertTo(DepthImg, CV_8UC1, 255.0 / 4500);
            //   
            equalizeHist(DepthImg, DepthImg);
    
    
            while (InfraredFrame == NULL){
                InfraredFrameReader->AcquireLatestFrame(&InfraredFrame);
            }
            InfraredFrame->get_FrameDescription(&FrameDescription);
            int nWidth, nHeight;
    
            FrameDescription->get_Width(&nWidth);
            FrameDescription->get_Height(&nHeight);
    
            Mat InfraredImg(nHeight, nWidth, CV_16UC1);
    
            InfraredFrame->CopyFrameDataToArray(nWidth * nHeight, (UINT16 *)InfraredImg.data);
    
    
    
    
    
            while (pColorFrame == NULL){
                ColorFrameReader->AcquireLatestFrame(&pColorFrame);
            }
            pColorFrame->get_FrameDescription(&FrameDescription);
            int CWidth, CHeight;
    
            FrameDescription->get_Width(&CWidth);
            FrameDescription->get_Height(&CHeight);
    
            Mat ColorImg(CHeight, CWidth, CV_8UC4);
    
            pColorFrame->CopyConvertedFrameDataToArray(CWidth * CHeight * 4, (BYTE *)ColorImg.data, ColorImageFormat_Bgra);
    
    
    
            //    
            resize(ColorImg, ColorImg, Size(512, 424));
    
            imshow("InfraredImg", InfraredImg);
            imshow("depthImg", DepthImg);
            imshow("ColorImg", ColorImg);
    
    
    
            DepthImg.release();
            ColorImg.release();
            InfraredImg.release();
    
            if (pDepthFrame)
                pDepthFrame->Release();
            if (pColorFrame)
                pColorFrame->Release();
            if (InfraredFrame)
                InfraredFrame->Release();
            if (27 == waitKey(50))
                break;
        }
    }
    
    int main()
    {
        GetColorDepthInfrared();
    }