OpenCV的人脸检测:cvRunHaarClassifierCascade函数解析

it2022-05-05  84

cvRunHaarClassifierCascade的:转载:http://2000liuzhenxing.blog.163.com/blog/static/51677475200981952828662/
最近学习OpenCV的人脸检测,有cvHaarDetectObjects,此函数中又有两个函数很重要,一个cvRunHaarClassifierCascade,另一个cvSetImagesForHaarClassifierCascade。这两个函数很重要,上网看到了,就把它转过来了,希望对大家有帮助。
//此函数是一个匹配函数,根据不同的分类器(tree、stump)进行不同的匹配,返回整形值
CV_IMPL intcvRunHaarClassifierCascade( CvHaarClassifierCascade* _cascade,                            CvPoint pt, int start_stage ){    int result = -1;    CV_FUNCNAME(”cvRunHaarClassifierCascade”);
    __BEGIN__;
    int p_offset, pq_offset;    int i, j;    double mean, variance_norm_factor;    CvHidHaarClassifierCascade* cascade;
    if( !CV_IS_HAAR_CLASSIFIER(_cascade) )        CV_ERROR( !_cascade ? CV_StsNullPtr : CV_StsBadArg, “Invalid cascade pointer” );
    cascade = _cascade->hid_cascade;    if( !cascade )        CV_ERROR( CV_StsNullPtr, “Hidden cascade has not been created.\n”            “Use cvSetImagesForHaarClassifierCascade” );
    if( pt.x < 0 || pt.y < 0 ||        pt.x + _cascade->real_window_size.width >= cascade->sum.width-2 ||        pt.y + _cascade->real_window_size.height >= cascade->sum.height-2 )                   //超边退出        EXIT;
    p_offset = pt.y * (cascade->sum.step/sizeof(sumtype)) + pt.x;    pq_offset = pt.y * (cascade->sqsum.step/sizeof(sqsumtype)) + pt.x;    mean = calc_sum(*cascade,p_offset)*cascade->inv_window_area;    variance_norm_factor = cascade->pq0[pq_offset] – cascade->pq1[pq_offset] -                //左上+右下-右上-左下                           cascade->pq2[pq_offset] + cascade->pq3[pq_offset];    variance_norm_factor = variance_norm_factor*cascade->inv_window_area – mean*mean;      //求方差(varance) =Ex2-(Ex)2    if( variance_norm_factor >= 0. )        variance_norm_factor = sqrt(variance_norm_factor);    else        variance_norm_factor = 1.;
    if( cascade->is_tree )           //是树形的分类器,就按照层来匹配.    {        CvHidHaarStageClassifier* ptr;        assert( start_stage == 0 );                      //start_stage==0继续
        result = 1;        ptr = cascade->stage_classifier;
        while( ptr )        {            double stage_sum = 0;
            for( j = 0; j < ptr->count; j++ )            {                stage_sum += icvEvalHidHaarClassifier( ptr->classifier + j,     //层判断                    variance_norm_factor, p_offset );            }
            if( stage_sum >= ptr->threshold )            {                ptr = ptr->child;               //层判断通过,到下一层.            }            else            {                while( ptr && ptr->next == NULL ) ptr = ptr->parent;              //未通过,且当前子分类器没有同层分类器,没有返回上层                if( ptr == NULL )              //如果刚才已经是最顶层了.                {                    result = 0;                  //返回0,退出.                    EXIT;                }                ptr = ptr->next;               //指向下一个分类器.            }        }    }    else if( cascade->is_stump_based )              //如果是stump类的分类器    {        for( i = start_stage; i < cascade->count; i++ )        {            double stage_sum = 0;
            if( cascade->stage_classifier[i].two_rects )            {                for( j = 0; j < cascade->stage_classifier[i].count; j++ )                {                    CvHidHaarClassifier* classifier = cascade->stage_classifier[i].classifier + j;                    CvHidHaarTreeNode* node = classifier->node;                    double sum, t = node->threshold*variance_norm_factor, a, b;
                    sum = calc_sum(node->feature.rect[0],p_offset) * node->feature.rect[0].weight;                    sum += calc_sum(node->feature.rect[1],p_offset) * node->feature.rect[1].weight;
                    a = classifier->alpha[0];                    b = classifier->alpha[1];                    stage_sum += sum < t ? a : b;                }            }            else            {                for( j = 0; j < cascade->stage_classifier[i].count; j++ )                {                    CvHidHaarClassifier* classifier = cascade->stage_classifier[i].classifier + j;                    CvHidHaarTreeNode* node = classifier->node;                    double sum, t = node->threshold*variance_norm_factor, a, b;
                    sum = calc_sum(node->feature.rect[0],p_offset) * node->feature.rect[0].weight;                    sum += calc_sum(node->feature.rect[1],p_offset) * node->feature.rect[1].weight;
                    if( node->feature.rect[2].p0 )                        sum += calc_sum(node->feature.rect[2],p_offset) * node->feature.rect[2].weight;
                    a = classifier->alpha[0];                    b = classifier->alpha[1];                    stage_sum += sum < t ? a : b;                }            }
            if( stage_sum < cascade->stage_classifier[i].threshold )            {                   //没通过.则返回负的没通过的分类器数.                result = -i;                EXIT;            }        }    }    else                    //如果不是那两种强分类器    {        for( i = start_stage; i < cascade->count; i++ )        {            double stage_sum = 0;
            for( j = 0; j < cascade->stage_classifier[i].count; j++ )            {                stage_sum += icvEvalHidHaarClassifier(                    cascade->stage_classifier[i].classifier + j,                    variance_norm_factor, p_offset );            }
            if( stage_sum < cascade->stage_classifier[i].threshold )            {                result = -i;                EXIT;            }        }    }
    result = 1;
    __END__;
    return result;     //返回结果}

转载于:https://www.cnblogs.com/freecloudinsky/archive/2013/05/20/3088890.html


最新回复(0)