cvhaar.cpp.svn-base

来自「非结构化路识别」· SVN-BASE 代码 · 共 1,285 行 · 第 1/4 页

SVN-BASE
1,285
字号
    if( sumImage )
        CV_CALL( cvSetImagesForHaarClassifierCascade( out, sumImage, sqSumImage,
                                                      tiltedSumImage, scale ));

    __END__;

    if( cvGetErrStatus() < 0 )
        cvFree( (void**)&out );

    return out;
}


CV_IMPL CvSize
cvGetHaarClassifierCascadeWindowSize( CvHidHaarClassifierCascade* cascade )
{
    CvSize realWindowSize = { -1, -1 };

    CV_FUNCNAME("cvGetHaarClassifierCascadeWindowSize");

    __BEGIN__;

    if( !cascade )
        CV_ERROR( CV_StsNullPtr, "" );

    if( cascade->headerSize != sizeof(*cascade))
        CV_ERROR( CV_StsNullPtr, "Invalid CvHidHaarClassifierCascade header" );

    realWindowSize = cascade->realWindowSize;

    __END__;

    return realWindowSize;
}


CV_IMPL double
cvGetHaarClassifierCascadeWindowScale( CvHidHaarClassifierCascade* cascade )
{
    double scale = -1;
    
    CV_FUNCNAME("cvGetHaarClassifierCascadeWindowSize");

    __BEGIN__;

    if( !cascade )
        CV_ERROR( CV_StsNullPtr, "" );

    if( cascade->headerSize != sizeof(*cascade))
        CV_ERROR( CV_StsNullPtr, "Invalid CvHidHaarClassifierCascade header" );

    scale = cascade->scale;

    __END__;

    return scale;
}


#define sum_elem_ptr(sum,row,col)  \
    ((sumtype*)CV_MAT_ELEM_PTR_FAST((sum),(row),(col),sizeof(sumtype)))

#define sqsum_elem_ptr(sqsum,row,col)  \
    ((sqsumtype*)CV_MAT_ELEM_PTR_FAST((sqsum),(row),(col),sizeof(sqsumtype)))

#define calc_sum(rect,offset) \
    ((rect).p0[offset] - (rect).p1[offset] - (rect).p2[offset] + (rect).p3[offset])


CV_IMPL void
cvSetImagesForHaarClassifierCascade( CvHidHaarClassifierCascade* cascade,
                                     const CvArr* sumImage,
                                     const CvArr* sqSumImage,
                                     const CvArr* tiltedSumImage,
                                     double scale )
{
    CV_FUNCNAME("cvSetImagesForHaarClassifierCascade");

    __BEGIN__;

    CvMat sum_stub, *sum = (CvMat*)sumImage;
    CvMat sqsum_stub, *sqsum = (CvMat*)sqSumImage;
    CvMat tilted_stub, *tilted = (CvMat*)tiltedSumImage;
    int coi0 = 0, coi1 = 0;
    int i, j, k, l;
    int pixSize;
    CvSize winSize;
    CvRect equ_rect;
    double weight_scale;

    if( !cascade )
        CV_ERROR( CV_StsNullPtr, "" );

    if( cascade->headerSize != sizeof(*cascade))
        CV_ERROR( CV_StsNullPtr, "Invalid CvHidHaarClassifierCascade header" );

    if( scale <= 0 )
        CV_ERROR( CV_StsOutOfRange, "Scale must be positive" );

    CV_CALL( sum = cvGetMat( sum, &sum_stub, &coi0 ));
    CV_CALL( sqsum = cvGetMat( sqsum, &sqsum_stub, &coi1 ));

    if( !CV_ARE_SIZES_EQ( sum, sqsum ))
        CV_ERROR( CV_StsUnmatchedSizes, "All integral images must have the same size" );

    if( CV_MAT_TYPE(sqsum->type) != CV_64FC1 ||
        CV_MAT_TYPE(sum->type) != CV_32SC1 )
        CV_ERROR( CV_StsUnsupportedFormat,
        "Only (32s, 64f, 32s) combination of (sum,sqsum,tiltedsum) formats is allowed" );

    if( cascade->has_tilted_features )
    {
        CV_CALL( tilted = cvGetMat( tilted, &tilted_stub, &coi1 ));

        if( CV_MAT_TYPE(tilted->type) != CV_32SC1 )
            CV_ERROR( CV_StsUnsupportedFormat,
            "Only (32s, 64f, 32s) combination of (sum,sqsum,tiltedsum) formats is allowed" );

        if( sum->step != tilted->step )
            CV_ERROR( CV_StsUnmatchedSizes,
            "Sum and tiltedSum must have the same stride (step, widthStep)" );

        if( !CV_ARE_SIZES_EQ( sum, tilted ))
            CV_ERROR( CV_StsUnmatchedSizes, "All integral images must have the same size" );
        cascade->tiltedSum = *tilted;
    }
    else
    {
        cascade->tiltedSum = *sum;
    }

    cascade->sum = *sum;
    cascade->sqsum = *sqsum;
    
    pixSize = CV_ELEM_SIZE( CV_MAT_TYPE( sum->type ));
    updateRealWindowSize( cascade, scale );
    winSize = cascade->realWindowSize;
    
    equ_rect.x = equ_rect.y = cvRound(scale);
    equ_rect.width = cvRound((cascade->origWindowSize.width-2)*scale);
    equ_rect.height = cvRound((cascade->origWindowSize.height-2)*scale);
    weight_scale = 1./(equ_rect.width*equ_rect.height);
    cascade->invWindowArea = weight_scale;

    cascade->p0 = sum_elem_ptr(*sum, equ_rect.y, equ_rect.x);
    cascade->p1 = sum_elem_ptr(*sum, equ_rect.y, equ_rect.x + equ_rect.width );
    cascade->p2 = sum_elem_ptr(*sum, equ_rect.y + equ_rect.height, equ_rect.x );
    cascade->p3 = sum_elem_ptr(*sum, equ_rect.y + equ_rect.height,
                                     equ_rect.x + equ_rect.width );

    cascade->pq0 = sqsum_elem_ptr(*sqsum, equ_rect.y, equ_rect.x);
    cascade->pq1 = sqsum_elem_ptr(*sqsum, equ_rect.y, equ_rect.x + equ_rect.width );
    cascade->pq2 = sqsum_elem_ptr(*sqsum, equ_rect.y + equ_rect.height, equ_rect.x );
    cascade->pq3 = sqsum_elem_ptr(*sqsum, equ_rect.y + equ_rect.height,
                                          equ_rect.x + equ_rect.width );

    /* init pointers in haar features according to real window size and
       given image pointers */
    for( i = 0; i < cascade->count; i++ )
    {
        for( j = 0; j < cascade->stageClassifier[i].count; j++ )
        {
            for( l = 0; l < cascade->stageClassifier[i].classifier[j].count; l++ )
            {
                CvHaarFeature* feature = 
                    cascade->stageClassifier[i].classifier[j].origFeature + l;
                /* CvHidHaarClassifier* classifier =
                    cascade->stageClassifier[i].classifier + j; */
                CvHidHaarFeature* hidfeature = 
                    cascade->stageClassifier[i].classifier[j].feature + l;
                double sum0 = 0, area0 = 0;
                CvRect r[3];
#if CV_ADJUST_FEATURES
                int base_w = -1, base_h = -1;
                int new_base_w = 0, new_base_h = 0;
                int kx, ky;
                int flagx = 0, flagy = 0;
                int x0 = 0, y0 = 0;
#endif
                int nr;

                /* align blocks */
                for( k = 0; k < CV_HAAR_FEATURE_MAX; k++ )
                {
                    r[k] = feature->rect[k].r;
                    if( r[k].width == 0 )
                    {
                        memset( hidfeature->rect + k, 0, sizeof(hidfeature->rect[k]));
                        break;
                    }
#if CV_ADJUST_FEATURES
                    base_w = (int)CV_IMIN( (unsigned)base_w, (unsigned)(r[k].width-1) );
                    base_w = (int)CV_IMIN( (unsigned)base_w, (unsigned)(r[k].x - r[0].x-1) );
                    base_h = (int)CV_IMIN( (unsigned)base_h, (unsigned)(r[k].height-1) );
                    base_h = (int)CV_IMIN( (unsigned)base_h, (unsigned)(r[k].y - r[0].y-1) );
#endif
                }

                base_w += 1;
                base_h += 1;
                nr = k;

#if CV_ADJUST_FEATURES
                kx = r[0].width / base_w;
                ky = r[0].height / base_h;

                if( kx <= 0 )
                {
                    flagx = 1;
                    new_base_w = cvRound( r[0].width * scale ) / kx;
                    x0 = cvRound( r[0].x * scale );
                }

                if( ky <= 0 )
                {
                    flagy = 1;
                    new_base_h = cvRound( r[0].height * scale ) / ky;
                    y0 = cvRound( r[0].y * scale );
                }
#endif
            
                for( k = 0; k < CV_HAAR_FEATURE_MAX; k++ )
                {
                    CvRect tr;
                    double correctionRatio;
                
                    if( k < nr )
                    {
#if CV_ADJUST_FEATURES
                        if( flagx )
                        {
                            tr.x = (r[k].x - r[0].x) * new_base_w / base_w + x0;
                            tr.width = r[k].width * new_base_w / base_w;
                        }
                        else
#endif
                        {
                            tr.x = cvRound( r[k].x * scale );
                            tr.width = cvRound( r[k].width * scale );
                        }

#if CV_ADJUST_FEATURES
                        if( flagy )
                        {
                            tr.y = (r[k].y - r[0].y) * new_base_h / base_h + y0;
                            tr.height = r[k].height * new_base_h / base_h;
                        }
                        else
#endif
                        {
                            tr.y = cvRound( r[k].y * scale );
                            tr.height = cvRound( r[k].height * scale );
                        }

#if CV_ADJUST_WEIGHTS
                        {
                        // RAINER START
                        const float origFeatureSize =  (float)(feature->rect[k].r.width)*feature->rect[k].r.height; 
                        const float origNormSize = (float)(cascade->origWindowSize.width)*(cascade->origWindowSize.height);
                        const float featureSize = float(tr.width*tr.height);
                        //const float normSize    = float(equ_rect.width*equ_rect.height);
                        float targetRatio = origFeatureSize / origNormSize;
                        //float isRatio = featureSize / normSize;
                        //correctionRatio = targetRatio / isRatio / normSize;
                        correctionRatio = targetRatio / featureSize;
                        // RAINER END
                        }
#else
                        correctionRatio = weight_scale * (!feature->tilted ? 1 : 0.5);
#endif

                        if( !feature->tilted )
                        {
                            hidfeature->rect[k].p0 = sum_elem_ptr(*sum, tr.y, tr.x);
                            hidfeature->rect[k].p1 = sum_elem_ptr(*sum, tr.y, tr.x + tr.width);
                            hidfeature->rect[k].p2 = sum_elem_ptr(*sum, tr.y + tr.height, tr.x);
                            hidfeature->rect[k].p3 = sum_elem_ptr(*sum, tr.y + tr.height, tr.x + tr.width);
                        }
                        else
                        {
                            hidfeature->rect[k].p2 = sum_elem_ptr(*tilted, tr.y + tr.width, tr.x + tr.width);
                            hidfeature->rect[k].p3 = sum_elem_ptr(*tilted, tr.y + tr.width + tr.height,
                                                                  tr.x + tr.width - tr.height);
                            hidfeature->rect[k].p0 = sum_elem_ptr(*tilted, tr.y, tr.x);
                            hidfeature->rect[k].p1 = sum_elem_ptr(*tilted, tr.y + tr.height, tr.x - tr.height);
                        }

                        hidfeature->rect[k].weight = (float)(feature->rect[k].weight * correctionRatio);

                        if( k == 0 )
                            area0 = tr.width * tr.height;
                        else
                            sum0 += hidfeature->rect[k].weight * tr.width * tr.height;
                    }
                    else
                    {
                        memset( hidfeature->rect + k, 0, sizeof(hidfeature->rect[k]));
                        hidfeature->rect[k].weight = 0;
                    }
                }

                hidfeature->rect[0].weight = (float)(-sum0/area0);
            } /* l */
        } /* j */
    }

    __END__;
}


CV_IMPL int
cvRunHaarClassifierCascade( CvHidHaarClassifierCascade* 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;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?