2013-07-05 40 views
0

我是新来opencv,所以我不知道如果CamShift无法跟踪任何rotaterect返回值是什么。我应该如何处理这个问题?我的意思是,失去追踪目标在现实中是可能的。我应该如何在C++中捕获这个错误?OpenCV的camshift返回值,如果失败

回答

0

读camshift.cpp位于模块\视频\ SCR \

例如cvCamShift():

cvCamShift(const void* imgProb, CvRect windowIn, 
      CvTermCriteria criteria, 
      CvConnectedComp* _comp, 
      CvBox2D* box) 
{ 
    const int TOLERANCE = 10; 
    CvMoments moments; 
    double m00 = 0, m10, m01, mu20, mu11, mu02, inv_m00; 
    double a, b, c, xc, yc; 
    double rotate_a, rotate_c; 
    double theta = 0, square; 
    double cs, sn; 
    double length = 0, width = 0; 
    int itersUsed = 0; 
    CvConnectedComp comp; 
    CvMat cur_win, stub, *mat = (CvMat*)imgProb; 

    comp.rect = windowIn; 

    mat = cvGetMat(mat, &stub); 

    itersUsed = cvMeanShift(mat, windowIn, criteria, &comp); 
    windowIn = comp.rect; 

    windowIn.x -= TOLERANCE; 
    if(windowIn.x < 0) 
     windowIn.x = 0; 

    windowIn.y -= TOLERANCE; 
    if(windowIn.y < 0) 
     windowIn.y = 0; 

    windowIn.width += 2 * TOLERANCE; 
    if(windowIn.x + windowIn.width > mat->width) 
     windowIn.width = mat->width - windowIn.x; 

    windowIn.height += 2 * TOLERANCE; 
    if(windowIn.y + windowIn.height > mat->height) 
     windowIn.height = mat->height - windowIn.y; 

    cvGetSubRect(mat, &cur_win, windowIn); 

    /* Calculating moments in new center mass */ 
    cvMoments(&cur_win, &moments); 

    m00 = moments.m00; 
    m10 = moments.m10; 
    m01 = moments.m01; 
    mu11 = moments.mu11; 
    mu20 = moments.mu20; 
    mu02 = moments.mu02; 

    if(fabs(m00) < DBL_EPSILON) 
     return -1; 

    inv_m00 = 1./m00; 
    xc = cvRound(m10 * inv_m00 + windowIn.x); 
    yc = cvRound(m01 * inv_m00 + windowIn.y); 
    a = mu20 * inv_m00; 
    b = mu11 * inv_m00; 
    c = mu02 * inv_m00; 

    /* Calculating width & height */ 
    square = sqrt(4 * b * b + (a - c) * (a - c)); 

    /* Calculating orientation */ 
    theta = atan2(2 * b, a - c + square); 

    /* Calculating width & length of figure */ 
    cs = cos(theta); 
    sn = sin(theta); 

    rotate_a = cs * cs * mu20 + 2 * cs * sn * mu11 + sn * sn * mu02; 
    rotate_c = sn * sn * mu20 - 2 * cs * sn * mu11 + cs * cs * mu02; 
    length = sqrt(rotate_a * inv_m00) * 4; 
    width = sqrt(rotate_c * inv_m00) * 4; 

    /* In case, when tetta is 0 or 1.57... the Length & Width may be exchanged */ 
    if(length < width) 
    { 
     double t; 

     CV_SWAP(length, width, t); 
     CV_SWAP(cs, sn, t); 
     theta = CV_PI*0.5 - theta; 
    } 

    /* Saving results */ 
    if(_comp || box) 
    { 
     int t0, t1; 
     int _xc = cvRound(xc); 
     int _yc = cvRound(yc); 

     t0 = cvRound(fabs(length * cs)); 
     t1 = cvRound(fabs(width * sn)); 

     t0 = MAX(t0, t1) + 2; 
     comp.rect.width = MIN(t0, (mat->width - _xc) * 2); 

     t0 = cvRound(fabs(length * sn)); 
     t1 = cvRound(fabs(width * cs)); 

     t0 = MAX(t0, t1) + 2; 
     comp.rect.height = MIN(t0, (mat->height - _yc) * 2); 

     comp.rect.x = MAX(0, _xc - comp.rect.width/2); 
     comp.rect.y = MAX(0, _yc - comp.rect.height/2); 

     comp.rect.width = MIN(mat->width - comp.rect.x, comp.rect.width); 
     comp.rect.height = MIN(mat->height - comp.rect.y, comp.rect.height); 
     comp.area = (float) m00; 
    } 

    if(_comp) 
     *_comp = comp; 

    if(box) 
    { 
     box->size.height = (float)length; 
     box->size.width = (float)width; 
     box->angle = (float)((CV_PI*0.5+theta)*180./CV_PI); 
     while(box->angle < 0) 
      box->angle += 360; 
     while(box->angle >= 360) 
      box->angle -= 360; 
     if(box->angle >= 180) 
      box->angle -= 180; 
     box->center = cvPoint2D32f(comp.rect.x + comp.rect.width*0.5f, 
            comp.rect.y + comp.rect.height*0.5f); 
    } 

    return itersUsed; 
}