cvhaar.cpp.svn-base
来自「非结构化路识别」· SVN-BASE 代码 · 共 1,285 行 · 第 1/4 页
SVN-BASE
1,285 行
if( !cascade )
CV_ERROR( CV_StsNullPtr, "" );
if( cascade->headerSize != sizeof(*cascade))
CV_ERROR( CV_StsNullPtr, "Invalid CvHidHaarClassifierCascade header" );
if( pt.x < 0 || pt.y < 0 ||
pt.x + cascade->realWindowSize.width >= cascade->sum.width-2 ||
pt.y + cascade->realWindowSize.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->invWindowArea;
variance_norm_factor = cascade->pq0[pq_offset] - cascade->pq1[pq_offset] -
cascade->pq2[pq_offset] + cascade->pq3[pq_offset];
variance_norm_factor =
/*1.*/sqrt(variance_norm_factor*cascade->invWindowArea - mean*mean);
if( cascade->is_stump_based )
{
for( i = start_stage; i < cascade->count; i++ )
{
double stage_sum = 0;
if( cascade->stageClassifier[i].two_rects )
{
for( j = 0; j < cascade->stageClassifier[i].count; j++ )
{
CvHidHaarClassifier* classifier = cascade->stageClassifier[i].classifier + j;
CvHidHaarFeature* feature = classifier->feature;
double sum, t = classifier->threshold[0]*variance_norm_factor, a, b;
sum = calc_sum(feature->rect[0],p_offset) * feature->rect[0].weight;
sum += calc_sum(feature->rect[1],p_offset) * feature->rect[1].weight;
a = classifier->alpha[0];
b = classifier->alpha[1];
stage_sum += sum < t ? a : b;
}
}
else
{
for( j = 0; j < cascade->stageClassifier[i].count; j++ )
{
CvHidHaarClassifier* classifier = cascade->stageClassifier[i].classifier + j;
CvHidHaarFeature* feature = classifier->feature;
double sum, t = classifier->threshold[0]*variance_norm_factor;
sum = calc_sum(feature->rect[0],p_offset) * feature->rect[0].weight;
sum += calc_sum(feature->rect[1],p_offset) * feature->rect[1].weight;
if( feature->rect[2].p0 )
sum += calc_sum(feature->rect[2],p_offset) * feature->rect[2].weight;
stage_sum += classifier->alpha[sum >= t];
}
}
if( stage_sum < cascade->stageClassifier[i].threshold - 0.0001 )
{
result = -i;
EXIT;
}
}
}
else
{
for( i = start_stage; i < cascade->count; i++ )
{
double stage_sum = 0;
for( j = 0; j < cascade->stageClassifier[i].count; j++ )
{
CvHidHaarClassifier* classifier = cascade->stageClassifier[i].classifier + j;
double sum, t;// t = classifier->threshold*variance_norm_factor;
int idx;
idx = 0;
do
{
t = classifier->threshold[idx] * variance_norm_factor;
sum = calc_sum(classifier->feature[idx].rect[0],p_offset)
* classifier->feature[idx].rect[0].weight;
sum += calc_sum(classifier->feature[idx].rect[1],p_offset)
* classifier->feature[idx].rect[1].weight;
if( classifier->feature[idx].rect[2].p0 )
sum += calc_sum(classifier->feature[idx].rect[2],p_offset)
* classifier->feature[idx].rect[2].weight;
idx = ( sum < t ) ? classifier->left[idx] : classifier->right[idx];
}
while( idx > 0 );
stage_sum += classifier->alpha[-idx];
}
if( stage_sum < cascade->stageClassifier[i].threshold - 0.0001 )
{
result = -i;
EXIT;
}
}
}
result = 1;
__END__;
return result;
}
static int is_equal( const void* _r1, const void* _r2, void* )
{
const CvRect* r1 = (const CvRect*)_r1;
const CvRect* r2 = (const CvRect*)_r2;
int distance = cvRound(r1->width*0.2);
return r2->x <= r1->x + distance &&
r2->x >= r1->x - distance &&
r2->y <= r1->y + distance &&
r2->y >= r1->y - distance &&
r2->width <= cvRound( r1->width * 1.2 ) &&
cvRound( r2->width * 1.2 ) >= r1->width;
}
CV_IMPL CvSeq*
cvHaarDetectObjects( const IplImage* img,
CvHidHaarClassifierCascade* hid_cascade,
CvMemStorage* storage, double scale_factor,
int min_neighbors, int flags )
{
int split_stage = 2;
CvSize size = cvGetSize( img ), sumsize = { size.width + 1, size.height + 1 };
IplImage *temp = 0, *sum = 0, *tilted = 0, *sqsum = 0;
IplImage *sumcanny = 0;
CvSeq* seq = 0;
CvSeq* seq2 = 0;
CvSeq* idx_seq = 0;
CvSeq* result_seq = 0;
CvMemStorage* temp_storage = 0;
CvAvgComp* comps = 0;
int ncomp;
int do_canny_pruning = flags & CV_HAAR_DO_CANNY_PRUNING;
CV_FUNCNAME( "cvDetectFaces" );
__BEGIN__;
double factor;
int i, npass = 2;
int hid_cascade_count0;
if( !CV_IS_IMAGE(img) )
CV_ERROR( CV_StsBadArg, "Invalid source image" );
if( !hid_cascade || hid_cascade->headerSize != sizeof(*hid_cascade))
CV_ERROR( CV_StsBadArg, "Invalid classifier cascade" );
if( !storage )
CV_ERROR( CV_StsNullPtr, "Null storage pointer" );
temp = cvCreateImage( size, 8, 1 );
sum = cvCreateImage( sumsize, IPL_DEPTH_32S, 1 );
sqsum = cvCreateImage( sumsize, IPL_DEPTH_64F, 1 );
temp_storage = cvCreateChildMemStorage( storage );
if( hid_cascade->has_tilted_features )
tilted = cvCreateImage( sumsize, IPL_DEPTH_32S, 1 );
seq = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvRect), temp_storage );
seq2 = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvAvgComp), temp_storage );
result_seq = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvAvgComp), storage );
if( min_neighbors == 0 )
seq = result_seq;
if( img->nChannels == 3 )
{
cvCvtColor( img, temp, CV_BGR2GRAY );
img = temp;
}
cvIntegral( img, sum, sqsum, tilted );
if( do_canny_pruning )
{
sumcanny = cvCreateImage( sumsize, IPL_DEPTH_32S, 1 );
cvCanny( img, temp, 0, 50, 3 );
cvIntegral( temp, sumcanny );
}
hid_cascade_count0 = hid_cascade->count;
if( split_stage >= hid_cascade_count0 || split_stage == 0 )
{
split_stage = hid_cascade_count0;
npass = 1;
}
for( factor = 1; factor*hid_cascade->origWindowSize.width <
MIN( size.width - 10, size.height - 10 ); factor *= scale_factor )
{
double const ystep = MAX( 2, factor );
CvSize winSize = cvSize( cvRound( hid_cascade->origWindowSize.width * factor ),
cvRound( hid_cascade->origWindowSize.height * factor ));
CvRect equ_rect = { 0, 0, 0, 0 };
int *p0 = 0, *p1 = 0, *p2 = 0, *p3 = 0;
int *pq0 = 0, *pq1 = 0, *pq2 = 0, *pq3 = 0;
int pass, stage_offset = 0;
int stopHeight = cvRound((size.height - winSize.height - ystep) / ystep);
cvSetImagesForHaarClassifierCascade( hid_cascade, sum, sqsum, tilted, factor );
cvZero( temp );
if( do_canny_pruning )
{
equ_rect.x = cvRound(winSize.width*0.3);
equ_rect.y = cvRound(winSize.height*0.3);
equ_rect.width = cvRound(winSize.width*0.7);
equ_rect.height = cvRound(winSize.height*0.7);
p0 = (int*)(sumcanny->imageData + equ_rect.y*sumcanny->widthStep) + equ_rect.x;
p1 = (int*)(sumcanny->imageData + equ_rect.y*sumcanny->widthStep)
+ equ_rect.x + equ_rect.width;
p2 = (int*)(sumcanny->imageData + (equ_rect.y + equ_rect.height)*sumcanny->widthStep) + equ_rect.x;
p3 = (int*)(sumcanny->imageData + (equ_rect.y + equ_rect.height)*sumcanny->widthStep)
+ equ_rect.x + equ_rect.width;
pq0 = (int*)(sum->imageData + equ_rect.y*sum->widthStep) + equ_rect.x;
pq1 = (int*)(sum->imageData + equ_rect.y*sum->widthStep)
+ equ_rect.x + equ_rect.width;
pq2 = (int*)(sum->imageData + (equ_rect.y + equ_rect.height)*sum->widthStep) + equ_rect.x;
pq3 = (int*)(sum->imageData + (equ_rect.y + equ_rect.height)*sum->widthStep)
+ equ_rect.x + equ_rect.width;
}
hid_cascade->count = split_stage;
for( pass = 0; pass < npass; pass++ )
{
#ifdef _OPENMP
#pragma omp parallel for shared(hid_cascade, stopHeight, seq, ystep, temp, size, winSize, pass, npass, sum, p0, p1, p2 ,p3, pq0, pq1, pq2, pq3, stage_offset)
#endif // _OPENMP
for( int yInt = 0; yInt < stopHeight; yInt++ )
{
int iy = cvRound(yInt*ystep);
int xIntStep = 1;
int xInt, stopWidth = cvRound((size.width - winSize.width - 2*ystep) / ystep);
char* mask_row = temp->imageData + temp->widthStep * iy;
for( xInt = 0; xInt < stopWidth; xInt += xIntStep )
{
int ix = cvRound(xInt*ystep);
if( pass == 0 )
{
int result;
xIntStep = 2;
if( do_canny_pruning )
{
int offset;
int s, sq;
offset = iy*(sum->widthStep/sizeof(p0[0])) + ix;
s = p0[offset] - p1[offset] - p2[offset] + p3[offset];
sq = pq0[offset] - pq1[offset] - pq2[offset] + pq3[offset];
if( s < 100 || sq < 20 )
continue;
}
result = cvRunHaarClassifierCascade( hid_cascade, cvPoint(ix,iy),
0/*stage_offset*/ );
#ifdef _OPENMP
#pragma omp critical
#endif
if( result > 0 )
{
if( pass < npass - 1 )
{
mask_row[ix] = 1;
}
else
{
CvRect rect = cvRect(ix,iy,winSize.width,winSize.height);
cvSeqPush( seq, &rect );
}
}
if( result < 0 )
xIntStep = 1;
}
else if( mask_row[ix] )
{
int result = cvRunHaarClassifierCascade( hid_cascade, cvPoint(ix,iy),
stage_offset );
#ifdef _OPENMP
#pragma omp critical
#endif
if( result > 0 )
{
if( pass == npass - 1 )
{
CvRect rect = cvRect(ix,iy,winSize.width,winSize.height);
cvSeqPush( seq, &rect );
}
}
else
mask_row[ix] = 0;
}
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?