2016年4月11日 星期一

Translate Image Format from RealSense to OpenCV

Translate Image Format from RealSense to OpenCV

開始玩RealSense不免俗來一篇影像格式轉換的教學,因為在影像處理上還是習慣用OpenCV當作主要開發的Library,其實RealSense抓到的Color影像是可支援RGB24和RGB32的,比較特別的是Depth影像必須使用16位元的去記錄深度資訊,因為有效範圍是0.2~1.2公尺,我猜測0~255無法完全記錄這麼長一段的深度資訊。所以抓到的對大值應該是65536。依需求自行可以定義某段區間的值在做正歸化就可以明顯看出那段的深度精確程度。
開發環境:
  • Qt 5.5.1
  • Windows 8.1
  • MSVC 2012
  • OpenCV 3.0
#include <pxcsensemanager.h>
#include <pxcsession.h>

#include <iostream>
#include <opencv2\opencv.hpp>

#define WIDTH 640
#define HEIGHT 480

enum ImageFormat {
    STREAM_TYPE_COLOR = 0,
    STREAM_TYPE_DEPTH = 1,
    STREAM_TYPE_IR = 2
};

cv::Mat ConvertPXCImageToOpenCVMat( PXCImage *pxcImg, ImageFormat format){
    cv::Mat dstImg;
    PXCImage::ImageData data;
    PXCImage::ImageInfo imgInfo = pxcImg->QueryInfo();

    switch(format){
        case STREAM_TYPE_COLOR:
            pxcImg->AcquireAccess(PXCImage::ACCESS_READ, PXCImage::PIXEL_FORMAT_RGB24, &data);
            dstImg = cv::Mat( imgInfo.height, imgInfo.width, CV_8UC3 );
            memcpy( dstImg.data, data.planes[0], imgInfo.height*imgInfo.width*3*sizeof(pxcBYTE));
            break;
        case STREAM_TYPE_DEPTH:
            pxcImg->AcquireAccess(PXCImage::ACCESS_READ, PXCImage::PIXEL_FORMAT_DEPTH_RAW, &data);
            dstImg = cv::Mat( imgInfo.height, imgInfo.width, CV_16U );
            memcpy( dstImg.data, data.planes[0], imgInfo.height*imgInfo.width*2*sizeof(pxcBYTE));
            break;
    }

    pxcImg->ReleaseAccess(&data);
    return dstImg;
}


void main()
{
    PXCSenseManager *psm = NULL;
    psm = PXCSenseManager::CreateInstance();
    if ( psm == NULL ){
        std::cout<<"Unabel to create the PXCSenseManager"<<std::endl;
        return;
    }

    PXCSession::ImplVersion version = psm->QuerySession()->QueryVersion();
    std::cout<<"SDK Version:"<<version.major<<"."<<version.minor<<std::endl;

    psm->EnableStream( PXCCapture::STREAM_TYPE_COLOR, WIDTH, HEIGHT);
    psm->EnableStream( PXCCapture::STREAM_TYPE_DEPTH, WIDTH, HEIGHT);

    // Set the coordinate system
    PXCSession *session = psm->QuerySession();
    session->SetCoordinateSystem( PXCSession::COORDINATE_SYSTEM_REAR_OPENCV );

    if( psm->Init() != PXC_STATUS_NO_ERROR ){
        std::cout<<"Unable to Init the PXCSenseManager"<<std::endl;
        return;
    }

    PXCImage *colorIm, *depthIm;

    while(true){
        if( psm->AcquireFrame(true) < PXC_STATUS_NO_ERROR ){
            break;
        }

        PXCCapture::Sample *sample = psm->QuerySample();
        if( sample ){
            if( sample->color ){
                colorIm = sample->color;
                cv::Mat colorMat = ConvertPXCImageToOpenCVMat( colorIm, ImageFormat::STREAM_TYPE_COLOR);
                cv::imshow("OpenCV Window Color", colorMat);
            }
            if( sample->depth ){
                depthIm = sample->depth;
                cv::Mat depthMat = ConvertPXCImageToOpenCVMat( depthIm, ImageFormat::STREAM_TYPE_DEPTH);
                cv::imshow("OpenCV Window Depth", depthMat);
            }
            cv::waitKey(1);
        }
        psm->ReleaseFrame();
    }
    psm->Release();
}

更多OpenCV文章請參考:OpenCV Tutorial (學習筆記)

更多RealSense文章請參考:RealSense Tutorial

0 意見:

張貼留言