【翻譯】Kinect v2程序設計(C++) Color篇


Kinect SDK v2預覽版,獲取數據的基本流程的說明。以及取得Color圖像的示例程序的介紹。

上一節,是關於當前型號Kinect for Windows(后面稱作Kinect v1)和次世代型的Kinect for Windows的開發者預覽版 (后面稱作Kinect v2  預覽版 )的配置比較和介紹。
從這一節開始是Kinect的各種數據的取得方法的比較和介紹。
 
Color Camera
Kinect和通常的Web攝像頭一樣搭載了 Color Camera可以取得Color圖像。關於CameraKinect v1的分辨率是 640×480Kinect v2 分辨率大幅提升到 1920×1080。這次要介紹從Color Camer取得圖像的方法。
 
數據取得的流程
Kinect SDK v1和Kinect SDK v2 預覽版取得數據的基本流程。
這里表示的是最基礎的流程 Kinect SDK 在v2 預覽版里有把多個 「Source」「Reader」一齊處理的API和這里介紹的數據獲取的流程也會有差異。
圖1是Kinect SDK v1和Kinect SDK v2預覽版的數據取得流程
Kinect SDK v1,是從「Sensor」打開「Stream」,從「Stream」取得「Frame」,從「Frame」取得數據這樣的流程。
到了 Kinect SDK v2 預覽版 從「Sensor」取得「Source」從「Source」打開「Reader」從「Reader」取得「Frame」從「Frame」取得數據這樣的流程。
 
  每個Kinect SDK v2預覽版的「Source」,都有一個從Kinect取得Color和Depth的1個數據流,這點和 Kinect SDK v1的「Stream」是一樣的。
 
  Kinect SDK v2預覽版,追加了 「Reader」的階段。 「Reader」能打開1個 「Source」多次。通過這個配置多線程的應用上,不需要 把取得的數據拷貝到其他線程處理。也有多個應用可以從同一個傳感器取得數據的優點。
(注:因為Color Camera和Depth Camera是分離的,所以Color、Depth和Skeleton數據流也是各自獨立的,API通過Event來通知App是否有數據更新。通常為了效率,對每一個數據流都使用單獨的線程來等待Event,然后處理數據。在之前的v1中,Frame是獨立的,取出后數據就被Drop掉了,所以想在Depth里讀取Color之類的操作,必須使用內存拷貝,而多線程讀寫數據又會需要互斥鎖,十分影響效率;還有一個辦法是通過NuiSetFrameEndEvent,也就是c#接口中的AllFrameReady事件,但是這樣等待所有數據不僅太局限而且效率很低。
 
示例程序
  Kinect SDK v2預覽版取得Color畫像的示例程序的展示,圖1展示的是數據取得階段的摘錄解說。這個示例程序的全部內容,在下面的github里公開了。
這個示例程序為了處理圖像數據,使用了 OpenCV。 OpenCV的詳細內容可以參考下面的信息。
「Sensor」
取得「Sensor」
  1. // Sensor
    IKinectSensor* pSensor;   ……1
    HRESULT hResult = S_OK;
    hResult = GetDefaultKinectSensor( &pSensor );  ……2
    if( FAILED( hResult ) ){
      std::cerr << "Error : GetDefaultKinectSensor" << std::endl;
      return -1;
    }
    hResult = pSensor->Open();  ……3
    if( FAILED( hResult ) ){
      std::cerr << "Error : IKinectSensor::Open()" << std::endl;
      return -1;
    } 
    列表1.1 相當於圖1「Sensor」的部分
    1 處理Kinect v2預覽版的Sensor接口。
    2 取得默認的 Sensor。
    3 打開Sensor。
 
「Source」
 從「Sensor」取得「Source」。
  1. // Source
    IColorFrameSource* pColorSource;  ……1
    hResult = pSensor->get_ColorFrameSource( &pColorSource );  ……2
    if( FAILED( hResult ) ){
      std::cerr << "Error : IKinectSensor::get_ColorFrameSource()" << std::endl;
      return -1;
    }
    列表1.2  相當於圖1「Source」的部分
    1 獲取Color Frame的Source接口。
    2 從Sensor取得 Source。
「Reader」
「Source」從打開「Reader」。
  1. // Reader
    IColorFrameReader* pColorReader;  ……1
    hResult = pColorSource->OpenReader( &pColorReader );  ……2
    if( FAILED( hResult ) ){
      std::cerr << "Error : IColorFrameSource::OpenReader()" << std::endl;
      return -1;
    }
    列表1.3 相當於圖1「Reader」的部分
    1 獲取Color Frame的Reader接口。
    2 從Source打開Reader。
「Frame」~「Data」
從「Reader」取得最新的「Frame」。
  1. int width = 1920;   ……1
    int height = 1080;  ……1
    unsigned int bufferSize = width * height * 4 * sizeof( unsigned char );  ……2
    cv::Mat bufferMat( height, width, CV_8UC4 );  ……3
    cv::Mat colorMat( height / 2, width / 2, CV_8UC4 );  ……3
    cv::namedWindow( "Color" );
    while( 1 ){
      // Frame
      IColorFrame* pColorFrame=nullptr;  ……4
      hResult=pColorReader->AcquireLatestFrame( &pColorFrame );  ……5
      if( SUCCEEDED( hResult ) ){
        hResult = pColorFrame->CopyConvertedFrameDataToArray( bufferSize, reinterpret_cast<BYTE*>( bufferMat.data ), ColorImageFormat_Bgra );  ……6
        if( SUCCEEDED( hResult ) ){
          cv::resize( bufferMat, colorMat, cv::Size(), 0.50.5 );   ……7
        }
      }
      SafeRelease( pColorFrame );
      // Show Window
      cv::imshow( "Color", colorMat );
      if( cv::waitKey( 30 ) == VK_ESCAPE ){
        break;
      }
    } 
    列表1.4 相當於圖1「Frame」,「Data」的部分
    1 Color圖像的尺寸(1920×1080)。
       這里為了簡化說明,畫像尺寸用硬編碼來設定,示例程序可以從Source取得着Frame信息。
    2 Color圖像的數據尺寸。
    為了處理Color圖像,准備OpenCV的cv::Mat。
     「bufferMat」是原始的圖像數據,「colorMat」是Resize圖像數據的處理。 
     「CV_8UC4」,是無符號8bit整數(8U),4個channel(C4)並列來表現1個像素的數據格式。
    4 取得Color圖像的Frame接口。
    5 從Reader取得最新的Frame。
    6 從Frame取得Color圖像。
       默認的格式是YUY2(亮度與色差表現的格式),不過可以經過簡單處理變換為BGRA。
    7 縮小為長寬各一半的尺寸(960×540)。
  從「Frame」取得Color圖像的數據時, Kinect SDK v1是預先指定圖像尺寸和格式,Kinect SDK v2不能指定圖像尺寸。因此,取得數據后可以按任意形狀來整理。
  取出的Color圖像直接顯示 的話尺寸太大(1920×1080)在這里采用了 OpenCV的resize命令 (cv::resize())縮小為長寬各一半的尺寸 (960×540)。(注:閱讀理解時不要受這一段縮放代碼的干擾僅僅就是為了考慮在顯示器上顯示的方便觀察沒別的意義。)
  取出的 Color圖像的數據如果指定的是BGRA格式就會像圖2一樣的排列着。藍 (B)綠(G)紅(R)和無效值(A)的共計32bit構成1像素。
圖2 Color圖像的數據排列
 
運行結果
運行這個示例程序的話,就會像圖3那樣,顯示從Kinect v2預覽版中取得的Color圖像。
總結
本節介紹了從 Kinect SDK v2 預覽版中取得數據的基本流程和取得Color圖像的示例程序下一節將介紹取得Depth數據的示例程序。
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM