0

cvSetData を使用して、RGB フレームを openCV に使用できるフレームに変換しています。RGB ストリームを生成するために SkeletalViewer を少し変更しました。

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 ビデオを実行できますが、最終的にはメモリ不足でクラッシュします。

画像を適切にリリースするにはどうすればよいですか?

4

2 に答える 2

1

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

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

その場合、もはや存在しないアドレスで cvReleaseImage が呼び出されます。

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

于 2011-08-16T23:41:03.340 に答える
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; 
}
于 2011-08-12T14:47:50.957 に答える