2011-08-11 7 views
0

私はopenCVに使用できるフレームにrgbフレームを取得するためにcvSetDataを使用しています。 SkeletalViewerをわずかに変更して、rgbストリームを生成しました。cvShowImageとKinect SDKのメモリに関する問題:スケルトンビューア

void CSkeletalViewerApp::Nui_GotVideoAlert() 
{ 
    const NUI_IMAGE_FRAME * pImageFrame = NULL; 

    IplImage* kinectColorImage = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U, 4); 

    HRESULT hr = NuiImageStreamGetNextFrame(
     m_pVideoStreamHandle, 
     0, 
     &pImageFrame); 
    if(FAILED(hr)) 
    { 
     return; 
    } 

    NuiImageBuffer * pTexture = pImageFrame->pFrameTexture; 
    KINECT_LOCKED_RECT LockedRect; 
    pTexture->LockRect(0, &LockedRect, NULL, 0); 
    if(LockedRect.Pitch != 0) 
    { 
     BYTE * pBuffer = (BYTE*) LockedRect.pBits; 

     m_DrawVideo.DrawFrame((BYTE*) pBuffer); 

     cvSetData(kinectColorImage, (BYTE*) pBuffer,kinectColorImage->widthStep); 

     cvShowImage("Color Image", kinectColorImage); 
     //cvReleaseImage(&kinectColorImage); 
     cvWaitKey(10); 

    } 
    else 
    { 
     OutputDebugString(L"Buffer length of received texture is bogus\r\n"); 
    } 

    cvReleaseImage(&kinectColorImage); 
    NuiImageStreamReleaseFrame(m_pVideoStreamHandle, pImageFrame); 

} 

cvReleaseImageでは、私はcvExceptionエラーが発生します。どちらが指定されていないかは正確にはわかりません。 cvReleaseImageがなければ、私はopenCVウィンドウでrgbビデオを実行していましたが、メモリ不足のために最終的にクラッシュします。

イメージを適切にリリースするにはどうすればよいですか?

答えて

1

ただこの問題を解決しました。

ブレークポイントとデバッグを使用して一連のsleuthingを行った後、問題はcvSetDataで使用されるポインタと関係があるかのように見えます。私の推測では、Nui_GotVideoAlert()は、cvReleaseImageが呼び出される前に、pBufferが指すアドレスを更新します。さらに、cvSetDataは、このアドレスからバイトをコピーすることは決してありません。

次に、存在しなくなったアドレスでcvReleaseImageが呼び出されます。

これは、NuiImpl.cppの先頭でkinectColorImageを宣言し、Nui_GotVideoAlert()でcvSetDataを呼び出し、Nui_Uninit()メソッドでcvReleaseImageを呼び出すことで解決しました。このようにして、kinectColorImageはNui_GotVideoAlert()の各呼び出しで新しいIplImageを作成する代わりに更新されます。

1

これは奇妙です。私が知る限り、cvReleaseImageはイメージヘッダーとイメージデータの両方を公開しました。私は以下のコードを実行しましたが、この特定の例では、cvReleaseImage のデータを含むバッファを解放していません。そこでは、私はcvSetDataを使用しませんでしたが、私はちょうど画像データへのポインタを更新しました。コメント行のコメントを外してそれぞれの行の下にコメントすると、プログラムは実行されますが、メモリリークが発生します。私はOpenCV 2.2を使用しました(これは従来のインターフェースです)。

#include <opencv/cv.h> 
#include <stdlib.h> 
#define NLOOPS 1000 
int main(void){ 
    int i,j 

    char *buff = (char *) malloc(sizeof(char) * 3 * 640 * 480); 
    for(i = 0; i < 640 * 480 * 3; i++) buff[i] = 128; 
    j = 0; 
    while(j++< NLOOPS){ 

     IplImage *im = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U, 3); 
     //cvSetData(im, buff, im->widthStep); ---> If you use that version you'll get memory leaks. Comment line below. 
     im->imageData = buff; 
     cvWaitKey(4); 
     cvShowImage("kk", im); 
     //cvReleaseImageHeader(&im);   ---> If you use that version you'll get memory leaks. Comment line below. 
     cvReleaseImage(&im); 

     free(im); 
    } 

    free(buff); 
    return 0; 
} 
関連する問題