0

opencvでcvCamShift関数を使用しようとしています。私はこれを行うためのクラスを書きました。これはコードです:

#include <cv.h>
#include <highgui.h>
using namespace std;


class Tracker{

    // File-level variables
    IplImage * pHSVImg; // the input image converted to HSV color mode
    IplImage * pHueImg; // the Hue channel of the HSV image
    IplImage * pMask; // this image is used for masking pixels
    IplImage * pProbImg; // the face probability estimates for each pixel
    CvHistogram * pHist; // histogram of hue in the original face image

    CvRect prevFaceRect;  // location of face in previous frame
    CvBox2D faceBox;      // current face-location estimate

    int vmin;
    int vmax;
    int smin;

    void updateHueImage(IplImage* pImg);
public:
    Tracker(IplImage * pImg, CvRect  pFaceRect);
    ~Tracker();
    CvBox2d track(IplImage* pImg);

};



Tracker::Tracker(IplImage * pImg, CvRect pFaceRect){
    // File-level variables
    int   nHistBins = 30;                 // number of histogram bins
    float rangesArr[] = {0,180};          // histogram range
    vmin = 10;
    vmax = 256;
    smin = 55;
    float * pRanges = rangesArr;

    pHSVImg  = cvCreateImage( cvGetSize(pImg), 8, 3 );
    pHueImg  = cvCreateImage( cvGetSize(pImg), 8, 1 );
    pMask    = cvCreateImage( cvGetSize(pImg), 8, 1 );
    pProbImg = cvCreateImage( cvGetSize(pImg), 8, 1 );

    pHist = cvCreateHist( 1, &nHistBins, CV_HIST_ARRAY, &pRanges, 1 );

    float maxVal = 0.f;

    // Create a new hue image
    updateHueImage(pImg);

    // Create a histogram representation for the face
    cvSetImageROI( pHueImg, pFaceRect );
    cvSetImageROI( pMask,   pFaceRect );
    cvCalcHist( &pHueImg, pHist, 0, pMask );
    cvGetMinMaxHistValue( pHist, 0, &maxVal, 0, 0 );
    cvConvertScale( pHist->bins, pHist->bins, maxVal? 255.0/maxVal : 0, 0 );
    cvResetImageROI( pHueImg );
    cvResetImageROI( pMask );

    // Store the previous face location
    prevFaceRect = pFaceRect;


}


Tracker::~Tracker(){
    cvReleaseImage( &pHSVImg );
    cvReleaseImage( &pHueImg );
    cvReleaseImage( &pMask );
    cvReleaseImage( &pProbImg );

    cvReleaseHist( &pHist );
}

void Tracker::updateHueImage(IplImage * pImg)
{
    // Convert to HSV color model
    cvCvtColor( pImg, pHSVImg, CV_BGR2HSV );

    // Mask out-of-range values
    cvInRangeS( pHSVImg, cvScalar(0, smin, MIN(vmin,vmax), 0),
                cvScalar(180, 256, MAX(vmin,vmax) ,0), pMask );

    // Extract the hue channel
    cvSplit( pHSVImg, pHueImg, 0, 0, 0 );
}

CvBox2D Tracker::track(IplImage * pImg)
{
    CvConnectedComp components;


    updateHueImage(pImg);


    cvCalcBackProject( &pHueImg, pProbImg, pHist );
    cvAnd( pProbImg, pMask, pProbImg, 0 );

    cvCamShift( pProbImg, prevFaceRect,
                cvTermCriteria( CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 10, 1 ),
                &components, &faceBox );


    prevFaceRect = components.rect;
    faceBox.angle = -faceBox.angle;

    return faceBox;
}

正常に動作しますが、追跡対象のオブジェクトがフレームから外れたり、何かが前面に出たりすると、ランタイムエラーが発生します。私の友人の1人は、私のコードと非常によく似たコードを持っており、最悪の状況でも実行時エラーは発生しません。これをデバッグする方法を教えてください。

4

1 に答える 1

0

追跡されたオブジェクトがフレームの外に出たり、何かがその前に来ると、パラメータprevFaceRectが null になり、そのためにエラーが表示されている可能性があると思います。したがって、この関数を呼び出す前に

cvCamShift( pProbImg, prevFaceRect,
                cvTermCriteria( CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 10, 1 ),
                &components, &faceBox );

チェックを追加して、prevFaceRectnullかどうかを確認します

于 2013-02-08T05:03:36.157 に答える