cvCamShift如何运作良好

时间:2013-02-08 04:09:54

标签: c++ opencv tracking

我正在尝试在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 个答案:

答案 0 :(得分:0)

我认为当被跟踪的对象离开框架或其前面有什么东西时,参数prevFaceRect将为空,可能是因为它显示错误。所以在调用此函数之前

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

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