1 #include "haarfeatures.h"
2 #include "cascadeclassifier.h"
4 CvHaarFeatureParams::CvHaarFeatureParams() : mode(BASIC)
9 CvHaarFeatureParams::CvHaarFeatureParams( int _mode ) : mode( _mode )
14 void CvHaarFeatureParams::init( const CvFeatureParams& fp )
16 CvFeatureParams::init( fp );
17 mode = ((const CvHaarFeatureParams&)fp).mode;
20 void CvHaarFeatureParams::write( FileStorage &fs ) const
22 CvFeatureParams::write( fs );
23 String modeStr = mode == BASIC ? CC_MODE_BASIC :
24 mode == CORE ? CC_MODE_CORE :
25 mode == ALL ? CC_MODE_ALL : String();
26 CV_Assert( !modeStr.empty() );
27 fs << CC_MODE << modeStr;
30 void CvHaarFeatureParams::printDefaults() const
32 CvFeatureParams::printDefaults();
33 cout << " [-mode <" CC_MODE_BASIC << "(default) | "
34 << CC_MODE_CORE <<" | " << CC_MODE_ALL << endl;
37 void CvHaarFeatureParams::printAttrs() const
39 CvFeatureParams::printAttrs();
40 String mode_str = mode == BASIC ? CC_MODE_BASIC :
41 mode == CORE ? CC_MODE_CORE :
42 mode == ALL ? CC_MODE_ALL : 0;
43 cout << "mode: " << mode_str << endl;
46 bool CvHaarFeatureParams::scanAttr( const String prmName, const String val)
48 if ( !CvFeatureParams::scanAttr( prmName, val ) )
50 if( !prmName.compare("-mode") )
52 mode = !val.compare( CC_MODE_CORE ) ? CORE :
53 !val.compare( CC_MODE_ALL ) ? ALL :
54 !val.compare( CC_MODE_BASIC ) ? BASIC : -1;
63 //--------------------- HaarFeatureEvaluator ----------------
65 void CvHaarEvaluator::init(const CvFeatureParams *_featureParams,
66 int _maxSampleCount, Size _winSize )
68 CV_Assert(_maxSampleCount > 0);
69 int cols = (_winSize.width + 1) * (_winSize.height + 1);
70 sum.create((int)_maxSampleCount, cols, CV_32SC1);
71 tilted.create((int)_maxSampleCount, cols, CV_32SC1);
72 normfactor.create(1, (int)_maxSampleCount, CV_32FC1);
73 CvFeatureEvaluator::init( _featureParams, _maxSampleCount, _winSize );
76 void CvHaarEvaluator::setImage(const Mat& img, uchar clsLabel, int idx)
78 CV_DbgAssert( !sum.empty() && !tilted.empty() && !normfactor.empty() );
79 CvFeatureEvaluator::setImage( img, clsLabel, idx);
80 Mat innSum(winSize.height + 1, winSize.width + 1, sum.type(), sum.ptr<int>((int)idx));
81 Mat innTilted(winSize.height + 1, winSize.width + 1, tilted.type(), tilted.ptr<int>((int)idx));
83 integral(img, innSum, innSqSum, innTilted);
84 normfactor.ptr<float>(0)[idx] = calcNormFactor( innSum, innSqSum );
87 void CvHaarEvaluator::writeFeatures( FileStorage &fs, const Mat& featureMap ) const
89 _writeFeatures( features, fs, featureMap );
92 void CvHaarEvaluator::writeFeature(FileStorage &fs, int fi) const
94 CV_DbgAssert( fi < (int)features.size() );
95 features[fi].write(fs);
98 void CvHaarEvaluator::generateFeatures()
100 int mode = ((const CvHaarFeatureParams*)((CvFeatureParams*)featureParams))->mode;
101 int offset = winSize.width + 1;
102 for( int x = 0; x < winSize.width; x++ )
104 for( int y = 0; y < winSize.height; y++ )
106 for( int dx = 1; dx <= winSize.width; dx++ )
108 for( int dy = 1; dy <= winSize.height; dy++ )
111 if ( (x+dx*2 <= winSize.width) && (y+dy <= winSize.height) )
113 if ( x+x+dx*2 <= winSize.width )
114 features.push_back( Feature( offset, false,
116 x+dx, y, dx , dy, +2 ) );
119 if ( (x+dx*2 <= winSize.height) && (y+dy <= winSize.width) )
121 if ( y+y+dy <= winSize.width )
122 features.push_back( Feature( offset, false,
124 y, x+dx, dy, dx, +2 ) );
127 if ( (x+dx*3 <= winSize.width) && (y+dy <= winSize.height) )
129 if ( x+x+dx*3 <= winSize.width )
130 features.push_back( Feature( offset, false,
132 x+dx, y, dx , dy, +3 ) );
135 if ( (x+dx*3 <= winSize.height) && (y+dy <= winSize.width) )
137 if ( y+y+dy <= winSize.width )
138 features.push_back( Feature( offset, false,
140 y, x+dx, dy, dx, +3 ) );
142 if( mode != CvHaarFeatureParams::BASIC )
145 if ( (x+dx*4 <= winSize.width) && (y+dy <= winSize.height) )
147 if ( x+x+dx*4 <= winSize.width )
148 features.push_back( Feature( offset, false,
150 x+dx, y, dx*2, dy, +2 ) );
153 if ( (x+dx*4 <= winSize.height) && (y+dy <= winSize.width ) )
155 if ( y+y+dy <= winSize.width )
156 features.push_back( Feature( offset, false,
158 y, x+dx, dy, dx*2, +2 ) );
162 if ( (x+dx*2 <= winSize.width) && (y+dy*2 <= winSize.height) )
164 if ( x+x+dx*2 <= winSize.width )
165 features.push_back( Feature( offset, false,
166 x, y, dx*2, dy*2, -1,
168 x+dx, y+dy, dx, dy, +2 ) );
170 if (mode != CvHaarFeatureParams::BASIC)
172 if ( (x+dx*3 <= winSize.width) && (y+dy*3 <= winSize.height) )
174 if ( x+x+dx*3 <= winSize.width )
175 features.push_back( Feature( offset, false,
176 x , y , dx*3, dy*3, -1,
177 x+dx, y+dy, dx , dy , +9) );
180 if (mode == CvHaarFeatureParams::ALL)
183 if ( (x+2*dx <= winSize.width) && (y+2*dx+dy <= winSize.height) && (x-dy>= 0) )
185 if ( x <= (winSize.width / 2) )
186 features.push_back( Feature( offset, true,
188 x, y, dx, dy, +2 ) );
191 if ( (x+dx <= winSize.width) && (y+dx+2*dy <= winSize.height) && (x-2*dy>= 0) )
193 if ( x <= (winSize.width / 2) )
194 features.push_back( Feature( offset, true,
196 x, y, dx, dy, +2 ) );
199 if ( (x+3*dx <= winSize.width) && (y+3*dx+dy <= winSize.height) && (x-dy>= 0) )
201 if ( x <= (winSize.width / 2) )
202 features.push_back( Feature( offset, true,
204 x+dx, y+dx, dx, dy, +3 ) );
207 if ( (x+dx <= winSize.width) && (y+dx+3*dy <= winSize.height) && (x-3*dy>= 0) )
209 if ( x <= (winSize.width / 2) )
210 features.push_back( Feature( offset, true,
212 x-dy, y+dy, dx, dy, +3 ) );
215 if ( (x+4*dx <= winSize.width) && (y+4*dx+dy <= winSize.height) && (x-dy>= 0) )
217 if ( x <= (winSize.width / 2) )
218 features.push_back( Feature( offset, true,
220 x+dx, y+dx, dx*2, dy, +2 ) );
223 if ( (x+dx <= winSize.width) && (y+dx+4*dy <= winSize.height) && (x-4*dy>= 0) )
225 if ( x <= (winSize.width / 2) )
226 features.push_back( Feature( offset, true,
228 x-dy, y+dy, dx, 2*dy, +2 ) );
235 numFeatures = (int)features.size();
238 CvHaarEvaluator::Feature::Feature()
241 rect[0].r = rect[1].r = rect[2].r = Rect(0,0,0,0);
242 rect[0].weight = rect[1].weight = rect[2].weight = 0;
245 CvHaarEvaluator::Feature::Feature( int offset, bool _tilted,
246 int x0, int y0, int w0, int h0, float wt0,
247 int x1, int y1, int w1, int h1, float wt1,
248 int x2, int y2, int w2, int h2, float wt2 )
254 rect[0].r.width = w0;
255 rect[0].r.height = h0;
256 rect[0].weight = wt0;
260 rect[1].r.width = w1;
261 rect[1].r.height = h1;
262 rect[1].weight = wt1;
266 rect[2].r.width = w2;
267 rect[2].r.height = h2;
268 rect[2].weight = wt2;
272 for( int j = 0; j < CV_HAAR_FEATURE_MAX; j++ )
274 if( rect[j].weight == 0.0F )
276 CV_SUM_OFFSETS( fastRect[j].p0, fastRect[j].p1, fastRect[j].p2, fastRect[j].p3, rect[j].r, offset )
281 for( int j = 0; j < CV_HAAR_FEATURE_MAX; j++ )
283 if( rect[j].weight == 0.0F )
285 CV_TILTED_OFFSETS( fastRect[j].p0, fastRect[j].p1, fastRect[j].p2, fastRect[j].p3, rect[j].r, offset )
290 void CvHaarEvaluator::Feature::write( FileStorage &fs ) const
292 fs << CC_RECTS << "[";
293 for( int ri = 0; ri < CV_HAAR_FEATURE_MAX && rect[ri].r.width != 0; ++ri )
295 fs << "[:" << rect[ri].r.x << rect[ri].r.y <<
296 rect[ri].r.width << rect[ri].r.height << rect[ri].weight << "]";
298 fs << "]" << CC_TILTED << tilted;