1. 程式人生 > >RGB和深度影象獲取最終版

RGB和深度影象獲取最終版

此處在原部落格基礎上進行了改正,調整了深度影象的歸一化處理方法,最終顯示減少了空洞

#include <opencv2\opencv.hpp> 

#include<iostream>
#include <Windows.h>
#include "NuiApi.h"
#include<cv.h>
#include <d3d11.h>


using namespace std;
using namespace cv;
   
  
//最遠距離(mm)
const int MAX_DISTANCE = 3500;
//最近距離(mm)
const int MIN_DISTANCE = 200;
  
const LONG m_depthWidth = 640;
const LONG m_depthHeight = 480;
const LONG m_colorWidth = 640;
const LONG m_colorHeight = 480;
const LONG cBytesPerPixel = 4;   //畫素位數
//計算記憶體大小
  
int main()
{
  //彩色影象
  Mat image_rgb;
  //深度影象
  Mat image_depth;
  
  //建立一個MAT
  image_rgb.create(480,640,CV_8UC3);
  image_depth.create(480,640,CV_8UC1);
  
  //一個KINECT例項指標
  INuiSensor* m_pNuiSensor = NULL;
  
  if (m_pNuiSensor != NULL)
  {
    return 0;
  }
  
  //記錄當前連線KINECT的數量(為多連線做準備)
  int iSensorCount;
  //獲得當前KINECT的數量
  HRESULT hr = NuiGetSensorCount(&iSensorCount);
  
  
  //按照序列初始化KINETC例項,這裡就連線了一個KINECT,所以沒有用到迴圈
  hr = NuiCreateSensorByIndex(iSensorCount - 1, &m_pNuiSensor);
  //初始化,讓其可以接收彩色和深度資料流
  hr = m_pNuiSensor->NuiInitialize(NUI_INITIALIZE_FLAG_USES_COLOR | NUI_INITIALIZE_FLAG_USES_DEPTH);
  
  //判斷是否出錯
  if (FAILED(hr))
  {
    cout<<"NuiInitialize failed"<<endl;
    return hr;
  }
  
  //彩色影象獲取下一幀事件
  HANDLE nextColorFrameEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  //彩色影象事件控制代碼
  HANDLE colorStreamHandle = NULL;
  //深度影象獲取下一幀事件
  HANDLE nextDepthFrameEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  //深度影象事件控制代碼
  HANDLE depthStreamHandle = NULL;
  
  //例項開啟資料流,這裡NUI_IMAGE_TYPE_COLOR表示彩色影象
  hr = m_pNuiSensor->NuiImageStreamOpen(NUI_IMAGE_TYPE_COLOR, NUI_IMAGE_RESOLUTION_640x480, 0,2,nextColorFrameEvent,&colorStreamHandle);
  
  if( FAILED( hr ) )//判斷是否提取正確
  {
    cout<<"Could not open color image stream video"<<endl;
    m_pNuiSensor->NuiShutdown();
    return hr;
  }
  
  //例項開啟資料流,這裡NUI_IMAGE_TYPE_DEPTH表示深度影象
  hr = m_pNuiSensor->NuiImageStreamOpen(NUI_IMAGE_TYPE_DEPTH, NUI_IMAGE_RESOLUTION_640x480, 0,2, nextDepthFrameEvent, &depthStreamHandle);
  
  if( FAILED( hr ) )//判斷是否提取正確
  {
    cout<<"Could not open color image stream video"<<endl;
    m_pNuiSensor->NuiShutdown();
    return hr;
  }
  
  
  
  cv::namedWindow("depth",1);
  moveWindow("depth",300,600);
  cv::namedWindow("colorImage",1);
  moveWindow("colorImage",0,200);
  
  while (1)
  {
    NUI_IMAGE_FRAME pImageFrame_rgb;
    NUI_IMAGE_FRAME pImageFrame_depth;
  
    //無限等待新的彩色資料,等到後返回
    if (WaitForSingleObject(nextColorFrameEvent, 0) == 0)
    {
      //從剛才開啟資料流的流控制代碼中得到該幀資料,讀取到的資料地址存於pImageFrame
      hr = m_pNuiSensor->NuiImageStreamGetNextFrame(colorStreamHandle, 0, &pImageFrame_rgb);
      if (FAILED(hr))
      {
        cout<<"Could not get color image"<<endl;
        m_pNuiSensor->NuiShutdown();
        return -1;
      }
  
  INuiFrameTexture *pTexture = pImageFrame_rgb.pFrameTexture;
  NUI_LOCKED_RECT lockedRect;
  
  //提取資料幀到LockedRect,它包括兩個資料物件:pitch每行位元組數,pBits第一個位元組地址
  //並鎖定資料,這樣當我們讀資料的時候,kinect就不會去修改它
  
  
  pTexture->LockRect(0, &lockedRect, NULL, 0);
      //確認獲得的資料是否有效
    if (lockedRect.Pitch != 0)
    {
     //將資料轉換為OpenCV的Mat格式
    for (int i = 0; i < image_rgb.rows; i++)
    {
          //第i行的指標
      uchar *prt = image_rgb.ptr(i);
  
          //每個位元組代表一個顏色資訊,直接使用uchar
      uchar *pBuffer = (uchar*)(lockedRect.pBits) + i * lockedRect.Pitch;
  
      for (int j = 0; j < image_rgb.cols; j++)
       {  
            prt[3 * j] = pBuffer[4 * j];//內部資料是4個位元組,0-1-2是BGR,第4個現在未使用
            prt[3 * j + 1] = pBuffer[4 * j + 1];
            prt[3 * j + 2] = pBuffer[4 * j + 2];
       }
    }
       // Canny(image_rgb,image_rgb,0,30,3);
        imshow("colorImage",image_rgb);
        //解除鎖定
        pTexture->UnlockRect(0);
        //釋放幀
        m_pNuiSensor->NuiImageStreamReleaseFrame(colorStreamHandle, &pImageFrame_rgb );
      }
      else
      {
        cout<<"Buffer length of received texture is bogus\r\n"<<endl;
      }
  
      BOOL nearMode;
      INuiFrameTexture* pColorToDepthTexture; 
  
  
      //深度影象的處理
      if (WaitForSingleObject(nextDepthFrameEvent, INFINITE) == 0)
      {
  
        hr = m_pNuiSensor->NuiImageStreamGetNextFrame(depthStreamHandle, 0 , &pImageFrame_depth);
  
        if (FAILED(hr))
        {
          cout<<"Could not get depth image"<<endl;
          NuiShutdown();
          return -1;
        }
  
    hr = m_pNuiSensor->NuiImageFrameGetDepthImagePixelFrameTexture( depthStreamHandle, &pImageFrame_depth, &nearMode, &pColorToDepthTexture); 
    INuiFrameTexture *pTexture = pImageFrame_depth.pFrameTexture;
    NUI_LOCKED_RECT lockedRect;
    NUI_LOCKED_RECT ColorToDepthLockRect; 
  
    pTexture->LockRect(0, &lockedRect, NULL, 0);
    pColorToDepthTexture->LockRect(0,&ColorToDepthLockRect,NULL,0); 
  
        //歸一化
    for (int i = 0; i < image_depth.rows; i++)
    {
       uchar *prt = image_depth.ptr<uchar>(i);
  
       uchar* pBuffer = (uchar*)(lockedRect.pBits) + i * lockedRect.Pitch;
          //這裡需要轉換,因為每個深度資料是2個位元組,應將BYTE轉成USHORT
       USHORT *pBufferRun = (USHORT*)pBuffer;
  
       for (int j = 0; j < image_depth.cols; j++)
       {
         //先向,將資料歸一化處理,對深度距離在300mm-3500mm範圍內的畫素,對映到【0—255】內,
         //超出範圍的,都去做是邊緣畫素
        prt[j] = 255 - (BYTE)(256*pBufferRun[j]/0x0fff);//直接將資料歸一化處理
       }
    }
   Mat out;


bilateralFilter(image_depth,out,25,25*2,25/2);

        imshow("depth", image_depth);
  
  
  
        //接下來是對齊部分,將前景摳出來
  
        //存放深度點的引數
        NUI_DEPTH_IMAGE_POINT* depthPoints = new NUI_DEPTH_IMAGE_POINT[640 * 480];
        if (ColorToDepthLockRect.Pitch != 0) 
        { 
          HRESULT hrState = S_OK; 
            
          //一個能在不同空間座標轉變的類(包括:深度,彩色,骨骼)
          INuiCoordinateMapper* pMapper; 
  
          //設定KINECT例項的空間座標系
          hrState = m_pNuiSensor->NuiGetCoordinateMapper(&pMapper); 
  
          if (FAILED(hrState)) 
          { 
            return hrState; 
          } 
  
          //重要的一步:從顏色空間對映到深度空間。引數說明:
          //【引數1】:彩色影象的型別
          //【引數2】:彩色影象的解析度
          //【引數3】:深度影象的解析度
          //【引數4】:深度影象的個數
          //【引數5】:深度畫素點數
          //【引數6】:取記憶體的大小,個數。型別為NUI_DEPTH_IMAGE_PIXEL
          //【引數7】:存放對映結果點的引數
          hrState = pMapper->MapColorFrameToDepthFrame(NUI_IMAGE_TYPE_COLOR, NUI_IMAGE_RESOLUTION_640x480, NUI_IMAGE_RESOLUTION_640x480, 
            640 * 480, (NUI_DEPTH_IMAGE_PIXEL*)ColorToDepthLockRect.pBits,640 * 480, depthPoints); 
  
          if (FAILED(hrState)) 
          { 
            return hrState; 
          } 
  
  
          //顯示的影象
          Mat show;
          show.create(480,640,CV_8UC3);
          show = 0;
  
          for (int i = 0; i < image_rgb.rows; i++)
          {
            for (int j = 0; j < image_rgb.cols; j++)
            {
              uchar *prt_rgb = image_rgb.ptr(i);
              uchar *prt_show = show.ptr(i);
              //在記憶體中偏移量
              long index = i * 640 + j; 
              //從儲存了對映座標的陣列中獲取點
              NUI_DEPTH_IMAGE_POINT depthPointAtIndex = depthPoints[index]; 
  
              //邊界判斷
              if (depthPointAtIndex.x >= 0 && depthPointAtIndex.x < image_depth.cols &&
                depthPointAtIndex.y >=0 && depthPointAtIndex.y < image_depth.rows)
              {
                //深度判斷,在MIN_DISTANCE與MAX_DISTANCE之間的當成前景,顯示出來
                //這個使用也很重要,當使用真正的深度畫素點再在深度影象中獲取深度值來判斷的時候,會出錯
                if (depthPointAtIndex.depth >= MIN_DISTANCE && depthPointAtIndex.depth <= MAX_DISTANCE)
                {
                  prt_show[3 * j]   = prt_rgb[j * 3];
                  prt_show[3 * j + 1] = prt_rgb[j * 3 + 1];
                  prt_show[3 * j + 2] = prt_rgb[j * 3 + 2];
                }
              }
            }
          }
          imshow("show", show);
        }
  
        delete []depthPoints;
          
        pTexture->UnlockRect(0);
        m_pNuiSensor->NuiImageStreamReleaseFrame(depthStreamHandle, &pImageFrame_depth);
      }
  
      else
      {
        cout<<"Buffer length of received texture is bogus\r\n"<<endl;
      }
    }
  
    if (waitKey(20) == 27)
      break;
  }
  return 0;
}

相關推薦

RGB深度影象獲取最終

此處在原部落格基礎上進行了改正,調整了深度影象的歸一化處理方法,最終顯示減少了空洞 #include <opencv2\opencv.hpp>  #include<iostream> #include <Windows.h> #inclu

RGB影象深度影象獲取點雲

#include <iostream> #include <fstream> #include <string> #include <pcl/io/pcd_io.h> #include <pcl/io/ply_io.h> #include

ROS使用openni獲取Kinect彩色影象深度影象

本實驗使用Ubuntu14.04的64bit版本,ROS使用Indigo版本,影象獲取使用OpenNI1(因為OpenNI2中未找到彩色影象和深度影象對齊功能,臺灣的一代大神Heresy已經實現這一功能,但是我更喜歡OpenNI1官方對齊方法),影象處理使用OpenCV2

realsense對齊彩色影象深度影象

首先宣告realsense通道,封裝實際裝置和感測器 //初始化 pipeline pipe; pipeline_profile profile = pipe.start(); rs2_stream align_to = find_stream_to_align(p

RGB-D深度影象介紹RGBD

RGBD = RGB + Depth MapRGB :RGB色彩模式是工業界的一種顏色標準,是通過對紅(R)、綠(G)、藍(B)三個顏色通道的變化以及它們相互之間的疊加來得到各式各樣的顏色的,RGB即是代表紅、綠、藍三個通道的顏色,這個標準幾乎包括了人類視力所能感知的所有顏色

在ROS下,攝像頭kinect V1的RGB深度圖的獲取

    驅動安裝好後,首先在終端輸入“roscore”,啟動節點,然後在新的終端輸入“roslaunch freenect_launch freenect-registered-xyzrgb.launch”或者“roslaunch freenect_launch freenect

Android Studio獲取開發SHA1值發布SHA1值,詳細過程

pre 希望 系統 water target 詳細 andro targe pac 轉自原文 Android Studio獲取開發版SHA1值和發布版SHA1值的史上最詳細方法 前言: 今天我想把百度地圖的定位集成到項目中來,想寫個小小的案例,實現一下,但在集成

Android Studio獲取開發SHA1值發布SHA1值的史上最詳細方法

nal code tail JD rip 通過 提示 打開 tor 前言:使用百度地圖時需要秘鑰,申請秘鑰時需要SHA1值,所以今天就總結一下怎麽獲取這個值。 正常情況下: 一、獲取開發版SHA1: 在此我直接用AndroidStudio提供的命令控制臺了,畢竟做Andro

伺服器(Dell T360+2塊Tesla P100)配置顯示卡驅動cuda最終(終於配置好了)

前言: 一開始我們實驗室嘗試用deb安裝包的方法安裝NVIDIA Tesla P100對應的顯示卡驅動和CUDA,但是總是出現重複登入的問題,迫不得已我們最後採用比較繁瑣的用run檔案安裝顯示卡驅動和CUDA的方法。(還是建議先用deb檔案安裝一下試試,因為比較簡便。) 首先明確一下,我沒有

Android Studio獲取開發SHA1值釋出版SHA1值的史上最詳細方法

前言: 今天我想把百度地圖的定位整合到專案中來,想寫個小小的案例,實現一下,但在整合百度地圖時首先要申請祕鑰,申請祕鑰要用到SHA1值,所以今天就來總結一下怎樣去獲取這個值吧,希望對大家有幫助。 正常情況下: 一、獲取開發版SHA1: 在此我直接用Android

深度學習框架——windows的darknet安裝使用

Windows版darknet安裝和使用,圖片以及視訊的檢測及儲存 1、系統環境 2、darknet安裝 2.1、下載地址(github上的原始碼) 2.2、安裝步驟 3、darknet使用 3.1、圖片的檢測

面向組合子程式設計(Combinator Programming)的PPTDemo(最終

    之前的一篇文章曾經說過我在準備一個面向組合子程式設計的ppt和demo。在公司內部進行試執行之後,今天終於開講了。    當然在這之間的幾個星期裡面,我修改了ppt的內容,還有為demo添加了單元測試。所以我把ppt的內容和demo的程式碼也一起打包上來了。    ppt包含2003和20

深度影象獲取原理

在計算機視覺系統中,三維場景資訊為影象分割、目標檢測、物體跟蹤等各類計算機視覺應用提供了更多的可能性,而深度影象(Depth map)作為一種普遍的三維場景資訊表達方式得到了廣泛的應用。深度影象的每個畫素點的灰度值可用於表徵場景中某一點距離攝像機的遠近。  獲取深度影象的

如何用Python深度神經網路識別影象

來源:王樹義科學網部落格概要:只需要10幾行Python程式碼,你就能自己構建機器視覺模型,對圖

MAC OS 下使用Android Studio獲取開發釋出版SHA1證書

** 釋出版: ** 1、開啟終端 CD 到Android Studio的檔案路徑下 2、輸入 keytool -list 3、 展示出祕鑰庫條目,第一次生成時,會提示你新建條目

一個視覺高手影象處理深度學習方面的博文目錄

hjimce原創博文導航 作者:hjimce 文章一多起來,管理起來就是麻煩,特此寫本篇導航,以便閱讀、編寫。宣告:博文的編寫,主要參考網上資料,並結合個人見解,僅供學習、交流使用,如有侵權,請聯絡博主刪除,原創文章,版權所有,轉載請註明出處。題中如有:“未完待續”

RGB-D(深度影象) & 影象深度

RGB-D(深度影象)   深度影象 = 普通的RGB三通道彩色影象 + Depth Map   在3D計算機圖形中,Depth Map(深度圖)是包含與視點的場景物件的表面的距離有關的資訊的影象或影象通道。其中,Depth Map

Python深度神經網路識別影象

進化的作用,讓人類對影象的處理非常高效。這裡,我給你展示一張照片。如果我這樣問你:你能否分辨出圖片中哪個是貓,哪個是狗?你可能立即會覺得自己遭受到了莫大的侮辱。並且大聲質問我:你覺得我智商有問題嗎?!息怒。換一個問法:你能否把自己分辨貓狗圖片的方法,描述成嚴格的規則,教給計算

android-studio如何獲取除錯正式sha1值

1.除錯版 首先,找到studio的terminal; 然後,找到jdk的bin目錄下,輸入命令:keytool -list -v  -keystore debug.keystore檔案路徑; 例如我的是keytool -list -v  -keystore C:\User

Mac下獲取開發SHA1釋出版SHA1

1.開發版: 直接在終端或Terminal中貼上如下程式碼 keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -k