cvhaar.cpp.svn-base
来自「非结构化路识别」· SVN-BASE 代码 · 共 1,285 行 · 第 1/4 页
SVN-BASE
1,285 行
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
/* Haar features calculation */
#include "_cvaux.h"
#include <float.h>
#include <stdio.h>
#include "_cvutils.h"
/* these settings affect the quality of detection: change with care */
#define CV_ADJUST_FEATURES 1
#define CV_ADJUST_WEIGHTS 0
typedef int sumtype;
typedef double sqsumtype;
typedef struct CvHidHaarFeature
{
struct
{
sumtype *p0, *p1, *p2, *p3;
float weight;
}
rect[CV_HAAR_FEATURE_MAX];
}
CvHidHaarFeature;
typedef struct CvHidHaarClassifier
{
int count;
CvHaarFeature* origFeature;
CvHidHaarFeature* feature;
float* threshold;
int* left;
int* right;
float* alpha;
}
CvHidHaarClassifier;
typedef struct CvHidHaarStageClassifier
{
int count;
float threshold;
CvHidHaarClassifier* classifier;
int two_rects;
}
CvHidHaarStageClassifier;
struct CvHidHaarClassifierCascade
{
int headerSize;
int count;
int is_stump_based;
int has_tilted_features;
CvSize origWindowSize;
CvSize realWindowSize;
double scale, invWindowArea;
CvHidHaarStageClassifier* stageClassifier;
CvMat sum;
CvMat tiltedSum;
CvMat sqsum;
sqsumtype *pq0, *pq1, *pq2, *pq3;
sumtype *p0, *p1, *p2, *p3;
};
static const char* numSuffix( int i )
{
switch( i % 10 )
{
case 1: return "st";
case 2: return "nd";
case 3: return "rd";
default: return "th";
}
}
static void
updateRealWindowSize( CvHidHaarClassifierCascade* cascade, double scale )
{
assert( cascade != 0 && cascade->headerSize == sizeof(*cascade));
cascade->scale = scale;
cascade->realWindowSize =
cvSize( cvRound( cascade->origWindowSize.width * scale ),
cvRound( cascade->origWindowSize.height * scale ));
}
/* create faster internal representation of haar classifier cascade */
CV_IMPL CvHidHaarClassifierCascade*
cvCreateHidHaarClassifierCascade( CvHaarClassifierCascade* cascade,
const CvArr* sumImage,
const CvArr* sqSumImage,
const CvArr* tiltedSumImage,
double scale )
{
CvHidHaarClassifierCascade* out = 0;
CV_FUNCNAME("cvCreateHidHaarClassifierCascade");
__BEGIN__;
int i, j, k, l;
int pos;
int datasize = sizeof(CvHidHaarClassifierCascade);
int total = 0;
int nodes = 0;
int nodepos = 0;
int alphapos = 0;
int nodecount = 0;
char errorstr[100];
CvHaarFeature* haarFeature0;
CvHidHaarFeature* hidHaarFeature0;
float* threshold0;
int* left0;
int* right0;
float* alpha0;
CvHidHaarClassifier* classifier0;
CvSize origWindowSize;
int has_tilted_features = 0;
if( !cascade || !cascade->stageClassifier )
CV_ERROR( CV_StsNullPtr, "" );
if( cascade->count <= 0 )
CV_ERROR( CV_StsOutOfRange, "Negative classifier counter" );
origWindowSize = cascade->origWindowSize;
if( origWindowSize.width <= 0 || origWindowSize.height <= 0 )
CV_ERROR( CV_StsBadSize, "Negative original window width or height" );
if( scale <= 0 )
CV_ERROR( CV_StsOutOfRange, "Scale must be positive" );
/* check input structure correctness and calculate total memory size needed for
internal representation of the classifier cascade */
for( i = 0; i < cascade->count; i++ )
{
CvHaarStageClassifier* stageClassifier = cascade->stageClassifier + i;
if( !stageClassifier->classifier ||
stageClassifier->count <= 0 )
{
sprintf( errorstr, "%d-%s stage classifier header is invalid "
"(has null pointers or non-positive classfier count)",
i, numSuffix(i));
CV_ERROR( CV_StsNullPtr, errorstr );
}
total += stageClassifier->count;
for( j = 0; j < stageClassifier->count; j++ )
{
CvHaarClassifier* classifier = stageClassifier->classifier + j;
nodes += classifier->count;
for( l = 0; l < classifier->count; l++ )
{
for( k = 0; k < CV_HAAR_FEATURE_MAX; k++ )
{
if( classifier->haarFeature[l].rect[k].weight )
{
CvRect r = classifier->haarFeature[l].rect[k].r;
int tilted = classifier->haarFeature[l].tilted;
has_tilted_features |= tilted != 0;
if( r.width < 0 || r.height < 0 || r.y < 0 ||
r.x + r.width > origWindowSize.width
||
(!tilted &&
(r.x < 0 || r.y + r.height > origWindowSize.height))
||
(tilted && (r.x - r.height < 0 ||
r.y + r.width + r.height > origWindowSize.height)))
{
sprintf( errorstr, "%d-%s rectangle of %d-%s classifier of "
"%d-%s stage classifier is invalid or is outside "
"the original window",
k, numSuffix(k), j, numSuffix(j), i, numSuffix(i) );
CV_ERROR( CV_StsNullPtr, errorstr );
}
}
}
}
}
}
datasize = sizeof(CvHidHaarClassifierCascade) +
sizeof(CvHidHaarStageClassifier)*cascade->count +
sizeof(CvHidHaarClassifier) * total +
( sizeof( CvHidHaarFeature ) + sizeof( CvHaarFeature ) +
sizeof( float ) + 2 * sizeof( int ) ) * nodes +
sizeof( float ) * (nodes + total);
CV_CALL( out = (CvHidHaarClassifierCascade*)cvAlloc( datasize ));
/* init header */
out->headerSize = sizeof(*out);
out->count = cascade->count;
out->origWindowSize = cascade->origWindowSize;
updateRealWindowSize( out, scale );
out->sum.data.ptr = out->sqsum.data.ptr = out->tiltedSum.data.ptr = 0;
out->stageClassifier = (CvHidHaarStageClassifier*)(out + 1);
classifier0 = (CvHidHaarClassifier*)(out->stageClassifier + out->count);
haarFeature0 = (CvHaarFeature*)(classifier0 + total);
hidHaarFeature0 = (CvHidHaarFeature*) (haarFeature0 + nodes);
threshold0 = (float*) (hidHaarFeature0 + nodes);
left0 = (int*) (threshold0 + nodes);
right0 = (int*) (left0 + nodes);
alpha0 = (float*) (right0 + nodes);
out->is_stump_based = 1;
out->has_tilted_features = has_tilted_features;
/* initialize internal representation */
for( i = 0, pos = 0, nodepos = 0, alphapos = 0; i < cascade->count; i++ )
{
CvHaarStageClassifier* stageClassifier = cascade->stageClassifier + i;
CvHidHaarStageClassifier* hidStageClassifier = out->stageClassifier + i;
hidStageClassifier->count = stageClassifier->count;
hidStageClassifier->threshold = stageClassifier->threshold;
hidStageClassifier->classifier = classifier0 + pos;
hidStageClassifier->two_rects = 1;
pos += stageClassifier->count;
for( j = 0; j < stageClassifier->count; j++ )
{
nodecount = stageClassifier->classifier[j].count;
hidStageClassifier->classifier[j].count = nodecount;
hidStageClassifier->classifier[j].origFeature = haarFeature0 + nodepos;
hidStageClassifier->classifier[j].feature = hidHaarFeature0 + nodepos;
hidStageClassifier->classifier[j].threshold = threshold0 + nodepos;
hidStageClassifier->classifier[j].left = left0 + nodepos;
hidStageClassifier->classifier[j].right = right0 + nodepos;
hidStageClassifier->classifier[j].alpha = alpha0 + alphapos;
nodepos += hidStageClassifier->classifier[j].count;
alphapos += hidStageClassifier->classifier[j].count + 1;
for( l = 0; l < nodecount; l++ )
{
/* original haar feature */
hidStageClassifier->classifier[j].origFeature[l] =
stageClassifier->classifier[j].haarFeature[l];
if( hidStageClassifier->classifier[j].origFeature[l].rect[2].weight == 0 ||
hidStageClassifier->classifier[j].origFeature[l].rect[2].r.width == 0 ||
hidStageClassifier->classifier[j].origFeature[l].rect[2].r.height == 0 )
{
memset( &(hidStageClassifier->classifier[j].origFeature[l].rect[2]), 0,
sizeof(hidStageClassifier->classifier[j].origFeature[l].rect[2]) );
}
else
hidStageClassifier->two_rects = 0;
/* threshold */
hidStageClassifier->classifier[j].threshold[l] =
stageClassifier->classifier[j].threshold[l];
/* left */
hidStageClassifier->classifier[j].left[l] =
stageClassifier->classifier[j].left[l];
/* right */
hidStageClassifier->classifier[j].right[l] =
stageClassifier->classifier[j].right[l];
/* alpha */
hidStageClassifier->classifier[j].alpha[l] =
stageClassifier->classifier[j].alpha[l];
}
out->is_stump_based &= nodecount == 1;
hidStageClassifier->classifier[j].alpha[nodecount] =
stageClassifier->classifier[j].alpha[nodecount];
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?