cvRunHaarClassifierCascade

来源:互联网 发布:数据恢复软件破解版app 编辑:程序博客网 时间:2024/05/15 13:39
for( i = 0; i < max_threads; i++ )
{
if( seq_thread[i] )
            cvReleaseMemStorage( &seq_thread[i]->storage );                //如果使用了OpenMP就释放使用的seq_thread
}
#endif
 
    cvReleaseMemStorage( &temp_storage );
    cvReleaseMat( &sum );
    cvReleaseMat( &sqsum );
    cvReleaseMat( &tilted );                                                                //释放使用的空间
    cvReleaseMat( &temp );
    cvReleaseMat( &sumcanny );
    cvReleaseMat( &norm_img );
    cvReleaseMat( &img_small );
    cvFree( &comps );
 
    return result_seq;                                                                                //返回结果
}
 
下面是cvRunHaarClassifierCascade的:
CV_IMPL int
cvRunHaarClassifierCascade( 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;
    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;     //返回结果
}
原创粉丝点击