Kinect v2 와 OF 의 연동 - 컬러프레임 편



이미 KinectV2 관련 에드온들이 있지만, MS 에서 제공하는 레퍼런스를 조금더 유연하게 활용하기 위하여 수동으로 키넥트 라이브러리를 이용하여 보자.


사전에 프로젝트 설정이 필요 하다. 키넥트 라이브러리를 등록 하는 절차 이다.



사전 프로젝트 설정 

1) VC++ Directories 

VC++ Directories -> Include Directories -> (추가) $(KINECTSDK20_DIR)\inc;$(IncludePath)

VC++ Directories -> Library Directories -> (추가) $(KINECTSDK20_DIR)\lib\x86;$(LibraryPath)  //플렛폼에 맞도록 x64로 할 수도 있다.



2) Linker

Linker -> Input -> Additional Dependencies ->(추가) kinect20.lib





ofApp.h

#pragma once

#include "ofMain.h"


class ofApp : public ofBaseApp{

    public:

        ~ofApp();
        void setup();
        void update();
        void draw();

        void keyPressed(int key);
        void keyReleased(int key);
        void mouseMoved(int x, int y );
        void mouseDragged(int x, int y, int button);
        void mousePressed(int x, int y, int button);
        void mouseReleased(int x, int y, int button);
        void windowResized(int w, int h);
        void dragEvent(ofDragInfo dragInfo);
        void gotMessage(ofMessage msg);
        
};



//차후 DebugView 를 위해   작성함
static void Trace(string str)
{
    ostringstream ss;
    ss << "of : " << str << endl;
    OutputDebugStringA( ss.str().c_str() );
}



//안전한? 포인터 메모리 소거를 위해
template<class Interface>
inline void SafeRelease(Interface *& pInterfaceToRelease)
{
    if (pInterfaceToRelease != NULL)
    {
        pInterfaceToRelease->Release();
        pInterfaceToRelease = NULL;
    }
}





ofApp.cpp


#include "ofApp.h"
#include <Kinect.h>



//키넥트 컬러 스트림 크기
static const int        cColorWidth  = 1920;
static const int        cColorHeight = 1080;


IKinectSensor*       m_pKinectSensor;       //키넥트 센서
IColorFrameReader*  m_pColorFrameReader;    //컬러 리더
BYTE*               m_pColorByteBGRA;       //실제 컬러 데이터


ofTexture videoTex;                         //출력 용 Texture
INT64 nTime = 0;



//키넥트 초기화
HRESULT InitializeKinect()

{
    //키넥트 화면을 가져올 텍스쳐 할당
    videoTex.allocate(cColorWidth , cColorHeight , GL_RGBA);
    
    //키넥트 컬러스트림을 담을 실제 컬러 데이터 배열 생성
    m_pColorByteBGRA = new BYTE[cColorWidth * cColorHeight * 4];


    m_pKinectSensor = NULL;
    HRESULT hr;

    //키넥트 찾기
    hr = GetDefaultKinectSensor(&m_pKinectSensor);


    //키넥트 장치가 없을때,
    if(FAILED(hr))
    {
        cout << "Failed" << endl; 
        return E_FAIL;
    }


    //초기화에 성공 하였다면 , 키넥트를 열고 , 컬러 리더를 초기화 함
    if(m_pKinectSensor)
    {
        cout << "ok" << endl;
        
        IColorFrameSource* pColorFrameSource = NULL;
        hr = m_pKinectSensor->Open();

        if(SUCCEEDED(hr))
        {
            hr = m_pKinectSensor->get_ColorFrameSource(&pColorFrameSource);
        }

        if(SUCCEEDED(hr))
        {
            hr = pColorFrameSource->OpenReader(&m_pColorFrameReader);
        }

        SafeRelease(pColorFrameSource);

        cout << "initialized kinect" << endl;
    }


    //키넥트 초기화 실패했을때,
    if(!m_pKinectSensor || FAILED(hr))
    {
        cout << "Failed Kinect" << endl;
        return E_FAIL;
    }


    return hr;
}





//실제로 컬러데이터를 가져와 videoTex 에 데이터를 입력함.
void ColorUpdate()
{
    if(!m_pKinectSensor)
    {
        return;
    }


    IColorFrame* pColorFrame = NULL;
    HRESULT hr = m_pColorFrameReader->AcquireLatestFrame(&pColorFrame);

    //컬러프레임 획득(Acquire)에 문제가 없다면,
    if(SUCCEEDED(hr))
    {
        IFrameDescription* pFrameDescription = NULL;
        int nWidth = 0;
        int nHeight = 0;
        ColorImageFormat imageFormat = ColorImageFormat_None;
        UINT nBufferSize = 0;
        BYTE* pByteBuffer = NULL;

        //프레임의 타임스탬프 획득
        hr = pColorFrame->get_RelativeTime(&nTime);
        if(SUCCEEDED(hr))
        {
            hr = pColorFrame->get_FrameDescription(&pFrameDescription);
        }

        //프레임 정보(pFrameDescription) 획득
        if(SUCCEEDED(hr))
        {
            pFrameDescription->get_Width(&nWidth);
            pFrameDescription->get_Height(&nHeight);
            hr = pColorFrame->get_RawColorImageFormat(&imageFormat);
        }

        //실제로 컬러 데이터를 불러와 VideoTex 에 넣음
        if(SUCCEEDED(hr))
        {
            pByteBuffer = m_pColorByteBGRA;

            nBufferSize = cColorWidth * cColorHeight * 4;
            hr = pColorFrame -> CopyConvertedFrameDataToArray(nBufferSize , pByteBuffer , ColorImageFormat_Bgra);

            videoTex.loadData(pByteBuffer , cColorWidth , cColorHeight , GL_BGRA);
        }

        SafeRelease(pFrameDescription); //메모리 해제
    }

    SafeRelease(pColorFrame); // 메모리 해제
}







//--------------------------------------------------------------
void ofApp::setup(){
    
    InitializeKinect();
    
    ofSetFrameRate(30);
}

ofApp::~ofApp()
{
    //종료시 키넥트도 종료 해 준다.
    if(m_pKinectSensor)
    {
        m_pKinectSensor->Close();
    }
    OutputDebugStringA("Exit\n");
}

//--------------------------------------------------------------
void ofApp::update(){

}

//--------------------------------------------------------------
void ofApp::draw(){

    ofSetColor(ofColor::white);

    //videoTex 에 데이터를 넣고 화면에 출력 한다
    ColorUpdate();
    if(videoTex.isAllocated())
    {
        videoTex.draw(0,0,320,180);
    }
    

    //fps 와 timestamp 를 표시한다
    ofSetColor(ofColor::red);
    ofDrawBitmapString("fps : " +  ofToString(ofGetFrameRate()) + "\ntimestamp : " + ofToString(nTime) ,0 ,30 ,0 );
}


//--------------------------------------------------------------
void ofApp::keyPressed(int key){

}

//--------------------------------------------------------------
void ofApp::keyReleased(int key){

}

//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y ){

}

//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){

}

//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){

}

//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){ 

}




결과 화면



잘 됨. 

Yamecoder 야매코더_
C++(oF) 2015. 5. 18. 18:11

댓글을 달아 주세요

Powerd by Tistory, designed by criuce
rss