2

Kinect深度カメラのピクセルをRGBカメラにオーバーレイさせようとしています。Xbox Kinect、OpenCVでC ++ Kinect 1.0 SDKを使用しており、新しい「NuiImageGetColorPixelCoordinateFrameFromDepthPixelFrameAtResolution」メソッドを使用しようとしています。

画像がスローモーションでレンダリングされ、1つのフレームでピクセルが複数回描画されているように見えるのを見てきました。最初に上下の境界線から描画し、次に奇妙な描画を開始するポイント(そこに45度の角度が表示されます)に到達します。

私はMSDNフォーラムでAdamSmithによって書かれたC#コードに基づいてコードを作成しようとしています が、サイコロはありません。オーバーレイのものを取り除き、RGB画像の「あるべき」場所に深度正規化深度ピクセルを描画したいと思います。

左側の画像は、深度画像をRGB空間にフィットさせようとしたときに得られるものであり、右側の画像は、私が見たい「生の」深度画像です。私はこれが私の方法でわずかな歪みのある右側の画像と同様の画像を作成することを望んでいました。

めちゃくちゃデプスマップ

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

// 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);
}

ありがとう

4

1 に答える 1

2

問題はループであることがわかりました。

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

ショートごと(2バイト)ではなく、バイトごとに反復していました。lockedRect.sizeはバイト数を返すので、修正は単に増分をi + = 2に変更していましたが、次のようにsizeof(short)に変更する方がさらに良いでしょう。

for (int i = 0; i < lockedRect.size; i += sizeof(short)) {
    // code
}
于 2012-04-12T22:07:35.980 に答える