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 + -
显示快捷键?