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

它工作得很好,但是当被跟踪的对象超出框架或有东西出现在它前面时,它会产生运行时错误。我的一个朋友的代码与我的代码非常相似,即使在最坏的情况下也不会产生任何运行时错误。请指导我如何调试它。

4

1 回答 1

0

我认为当被跟踪的对象超出框架或前面有东西时,参数prevFaceRect将为空,可能正因为如此,它显示错误。所以在调用这个函数之前

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

添加一个检查,以了解是否prevFaceRect为空

于 2013-02-08T05:03:36.157 回答