2012-04-12 6 views
2

Kinectの奥行きカメラのピクセルをRGBカメラの上に重ねようとしています。私は、Xbox Kinect、OpenCVでC++ Kinect 1.0 SDKを使用していて、新しい "NuiImageGetColorPixelCoordinateFrameFromDepthPixelFrameAtResolution"メソッドを使用しようとしています。Kinect 1.0 SDKを使用してぼかし画像をRGB画像に変換する

私はイメージがスローモーションでレンダリングされるのを見て、1フレームでピクセルが複数回描画されているかのように見ています。それは最初に上と下の境界からそれ自身を引き出し、次にそれが奇妙な描画を開始する点(そこでは45度の角度を見ることができる)になります。

私は、MSDN forumsでアダム・スミスが書いたC#コードをベースにしていますが、ダイスは使用していません。私はオーバーレイのものを取り除き、深度正規化された奥行きピクセルをRGBイメージ内にあるべき場所に描画したいだけです。

左の画像は、奥行き画像をRGB空間に合わせようとしているときの画像です。右の画像は、「生の」奥行き画像です。私はこの方法が、右のものと似たようなイメージをわずかな歪みで作り出すことを望んでいました。

Messed up depth map

これは、現時点で私が持っているコードとオブジェクトの定義です:

// From initialization 
INuiSensor *m_pNuiInstance; 
NUI_IMAGE_RESOLUTION m_nuiResolution = NUI_IMAGE_RESOLUTION_640x480; 
HANDLE m_pDepthStreamHandle; 
IplImage *m_pIplDepthFrame; 
IplImage *m_pIplFittedDepthFrame; 


m_pIplDepthFrame = cvCreateImage(cvSize(640, 480), 8, 1); 
m_pIplFittedDepthFrame = cvCreateImage(cvSize(640, 480), 8, 1); 

// Method 
IplImage *Kinect::GetRGBFittedDepthFrame() { 
    static long *pMappedBits = NULL; 

    if (!pMappedBits) { 
     pMappedBits = new long[640*480*2]; 
    } 

    NUI_IMAGE_FRAME pNuiFrame; 
    NUI_LOCKED_RECT lockedRect; 
    HRESULT hr = m_pNuiInstance->NuiImageStreamGetNextFrame(m_pDepthStreamHandle, 0, &pNuiFrame); 

    if (FAILED(hr)) { 
     // return the older frame 
     return m_pIplFittedDepthFrame; 
    } 

    bool hasPlayerData = HasSkeletalEngine(m_pNuiInstance); 

    INuiFrameTexture *pTexture = pNuiFrame.pFrameTexture; 
    pTexture->LockRect(0, &lockedRect, NULL, 0); 

    if (lockedRect.Pitch != 0) { 
     cvZero(m_pIplFittedDepthFrame); 

     hr = m_pNuiInstance->NuiImageGetColorPixelCoordinateFrameFromDepthPixelFrameAtResolution(
      m_nuiResolution, 
      NUI_IMAGE_RESOLUTION_640x480, 
      640 * 480, /* size is previous */ (unsigned short*) lockedRect.pBits, 
      (640 * 480) * 2, /* size is previous */ pMappedBits); 

     if (FAILED(hr)) { 
      return m_pIplFittedDepthFrame; 
     } 

    for (int i = 0; i < lockedRect.size; i++) { 
      unsigned char* pBuf = (unsigned char*) lockedRect.pBits + i; 
      unsigned short* pBufS = (unsigned short*) pBuf; 
      unsigned short depth = hasPlayerData ? ((*pBufS) & 0xfff8) >> 3 : ((*pBufS) & 0xffff); 
      unsigned char intensity = depth > 0 ? 255 - (unsigned char) (256 * depth/0x0fff) : 0; 

      long 
       x = pMappedBits[i], // tried with *(pMappedBits + (i * 2)), 
       y = pMappedBits[i + 1]; // tried with *(pMappedBits + (i * 2) + 1); 

      if (x >= 0 && x < m_pIplFittedDepthFrame->width && y >= 0 && y < m_pIplFittedDepthFrame->height) { 
       m_pIplFittedDepthFrame->imageData[x + y * m_pIplFittedDepthFrame->widthStep] = intensity; 
      } 

     } 
    } 

    pTexture->UnlockRect(0); 
    m_pNuiInstance->NuiImageStreamReleaseFrame(m_pDepthStreamHandle, &pNuiFrame); 

    return(m_pIplFittedDepthFrame); 
} 

おかげで

+0

は、あなただけの深度データを開いてください。ストリーム? –

+0

カラーストリームも開かれた。私はそれが必要かどうかは分かりませんが。 –

答えて

2

問題がループということであったことを私が発見した、

for (int i = 0; i < lockedRect.size; i++) { 
    // code 
} 

は、バイト単位で反復されていました。短時間(2バイト)ベース。 lockedRect.sizeは、修正プログラムは、単にI + = 2に増分を変えたバイト数を返すので、さらに良いが(短い)はsizeofにそれを変えることになるので、同様に、

for (int i = 0; i < lockedRect.size; i += sizeof(short)) { 
    // code 
} 
関連する問題