1 #include "opencv2/core/core.hpp"
2 #include "opencv2/core/internal.hpp"
4 #include "haarfeatures.h"
5 #include "cascadeclassifier.h"
9 CvHaarFeatureParams::CvHaarFeatureParams() : mode(BASIC)
14 CvHaarFeatureParams::CvHaarFeatureParams( int _mode ) : mode( _mode )
19 void CvHaarFeatureParams::init( const CvFeatureParams& fp )
21 CvFeatureParams::init( fp );
22 mode = ((const CvHaarFeatureParams&)fp).mode;
25 void CvHaarFeatureParams::write( FileStorage &fs ) const
27 CvFeatureParams::write( fs );
28 string modeStr = mode == BASIC ? CC_MODE_BASIC :
29 mode == CORE ? CC_MODE_CORE :
30 mode == ALL ? CC_MODE_ALL : string();
31 CV_Assert( !modeStr.empty() );
32 fs << CC_MODE << modeStr;
35 bool CvHaarFeatureParams::read( const FileNode &node )
37 if( !CvFeatureParams::read( node ) )
40 FileNode rnode = node[CC_MODE];
41 if( !rnode.isString() )
45 mode = !modeStr.compare( CC_MODE_BASIC ) ? BASIC :
46 !modeStr.compare( CC_MODE_CORE ) ? CORE :
47 !modeStr.compare( CC_MODE_ALL ) ? ALL : -1;
51 void CvHaarFeatureParams::printDefaults() const
53 CvFeatureParams::printDefaults();
54 cout << " [-mode <" CC_MODE_BASIC << "(default) | "
55 << CC_MODE_CORE <<" | " << CC_MODE_ALL << endl;
58 void CvHaarFeatureParams::printAttrs() const
60 CvFeatureParams::printAttrs();
61 string mode_str = mode == BASIC ? CC_MODE_BASIC :
62 mode == CORE ? CC_MODE_CORE :
63 mode == ALL ? CC_MODE_ALL : 0;
64 cout << "mode: " << mode_str << endl;
67 bool CvHaarFeatureParams::scanAttr( const string prmName, const string val)
69 if ( !CvFeatureParams::scanAttr( prmName, val ) )
71 if( !prmName.compare("-mode") )
73 mode = !val.compare( CC_MODE_CORE ) ? CORE :
74 !val.compare( CC_MODE_ALL ) ? ALL :
75 !val.compare( CC_MODE_BASIC ) ? BASIC : -1;
84 //--------------------- HaarFeatureEvaluator ----------------
86 void CvHaarEvaluator::init(const CvFeatureParams *_featureParams,
87 int _maxSampleCount, Size _winSize )
89 CV_Assert(_maxSampleCount > 0);
90 int cols = (_winSize.width + 1) * (_winSize.height + 1);
91 sum.create((int)_maxSampleCount, cols, CV_32SC1);
92 tilted.create((int)_maxSampleCount, cols, CV_32SC1);
93 normfactor.create(1, (int)_maxSampleCount, CV_32FC1);
94 CvFeatureEvaluator::init( _featureParams, _maxSampleCount, _winSize );
97 void CvHaarEvaluator::setImage(const Mat& img, uchar clsLabel, int idx)
99 CV_DbgAssert( !sum.empty() && !tilted.empty() && !normfactor.empty() );
100 CvFeatureEvaluator::setImage( img, clsLabel, idx);
101 Mat innSum(winSize.height + 1, winSize.width + 1, sum.type(), sum.ptr<int>((int)idx));
102 Mat innTilted(winSize.height + 1, winSize.width + 1, tilted.type(), tilted.ptr<int>((int)idx));
104 integral(img, innSum, innSqSum, innTilted);
105 normfactor.ptr<float>(0)[idx] = calcNormFactor( innSum, innSqSum );
108 void CvHaarEvaluator::writeFeatures( FileStorage &fs, const Mat& featureMap ) const
110 _writeFeatures( features, fs, featureMap );
113 void CvHaarEvaluator::writeFeature(FileStorage &fs, int fi) const
115 CV_DbgAssert( fi < (int)features.size() );
116 features[fi].write(fs);
119 void CvHaarEvaluator::generateFeatures()
121 int mode = ((const CvHaarFeatureParams*)((CvFeatureParams*)featureParams))->mode;
122 int offset = winSize.width + 1;
123 for( int x = 0; x < winSize.width; x++ )
125 for( int y = 0; y < winSize.height; y++ )
127 for( int dx = 1; dx <= winSize.width; dx++ )
129 for( int dy = 1; dy <= winSize.height; dy++ )
132 if ( (x+dx*2 <= winSize.width) && (y+dy <= winSize.height) )
134 features.push_back( Feature( offset, false,
136 x+dx, y, dx , dy, +2 ) );
139 if ( (x+dx <= winSize.width) && (y+dy*2 <= winSize.height) )
141 features.push_back( Feature( offset, false,
143 x, y+dy, dx, dy, +2 ) );
146 if ( (x+dx*3 <= winSize.width) && (y+dy <= winSize.height) )
148 features.push_back( Feature( offset, false,
150 x+dx, y, dx , dy, +3 ) );
153 if ( (x+dx <= winSize.width) && (y+dy*3 <= winSize.height) )
155 features.push_back( Feature( offset, false,
157 x, y+dy, dx, dy, +3 ) );
159 if( mode != CvHaarFeatureParams::BASIC )
162 if ( (x+dx*4 <= winSize.width) && (y+dy <= winSize.height) )
164 features.push_back( Feature( offset, false,
166 x+dx, y, dx*2, dy, +2 ) );
169 if ( (x+dx <= winSize.width ) && (y+dy*4 <= winSize.height) )
171 features.push_back( Feature( offset, false,
173 x, y+dy, dx, dy*2, +2 ) );
177 if ( (x+dx*2 <= winSize.width) && (y+dy*2 <= winSize.height) )
179 features.push_back( Feature( offset, false,
180 x, y, dx*2, dy*2, -1,
182 x+dx, y+dy, dx, dy, +2 ) );
184 if (mode != CvHaarFeatureParams::BASIC)
186 if ( (x+dx*3 <= winSize.width) && (y+dy*3 <= winSize.height) )
188 features.push_back( Feature( offset, false,
189 x , y , dx*3, dy*3, -1,
190 x+dx, y+dy, dx , dy , +9) );
193 if (mode == CvHaarFeatureParams::ALL)
196 if ( (x+2*dx <= winSize.width) && (y+2*dx+dy <= winSize.height) && (x-dy>= 0) )
198 features.push_back( Feature( offset, true,
200 x, y, dx, dy, +2 ) );
203 if ( (x+dx <= winSize.width) && (y+dx+2*dy <= winSize.height) && (x-2*dy>= 0) )
205 features.push_back( Feature( offset, true,
207 x, y, dx, dy, +2 ) );
210 if ( (x+3*dx <= winSize.width) && (y+3*dx+dy <= winSize.height) && (x-dy>= 0) )
212 features.push_back( Feature( offset, true,
214 x+dx, y+dx, dx, dy, +3 ) );
217 if ( (x+dx <= winSize.width) && (y+dx+3*dy <= winSize.height) && (x-3*dy>= 0) )
219 features.push_back( Feature( offset, true,
221 x-dy, y+dy, dx, dy, +3 ) );
224 if ( (x+4*dx <= winSize.width) && (y+4*dx+dy <= winSize.height) && (x-dy>= 0) )
226 features.push_back( Feature( offset, true,
228 x+dx, y+dx, dx*2, dy, +2 ) );
231 if ( (x+dx <= winSize.width) && (y+dx+4*dy <= winSize.height) && (x-4*dy>= 0) )
233 features.push_back( Feature( offset, true,
235 x-dy, y+dy, dx, 2*dy, +2 ) );
242 numFeatures = (int)features.size();
245 CvHaarEvaluator::Feature::Feature()
248 rect[0].r = rect[1].r = rect[2].r = Rect(0,0,0,0);
249 rect[0].weight = rect[1].weight = rect[2].weight = 0;
252 CvHaarEvaluator::Feature::Feature( int offset, bool _tilted,
253 int x0, int y0, int w0, int h0, float wt0,
254 int x1, int y1, int w1, int h1, float wt1,
255 int x2, int y2, int w2, int h2, float wt2 )
261 rect[0].r.width = w0;
262 rect[0].r.height = h0;
263 rect[0].weight = wt0;
267 rect[1].r.width = w1;
268 rect[1].r.height = h1;
269 rect[1].weight = wt1;
273 rect[2].r.width = w2;
274 rect[2].r.height = h2;
275 rect[2].weight = wt2;
279 for( int j = 0; j < CV_HAAR_FEATURE_MAX; j++ )
281 if( rect[j].weight == 0.0F )
283 CV_SUM_OFFSETS( fastRect[j].p0, fastRect[j].p1, fastRect[j].p2, fastRect[j].p3, rect[j].r, offset )
288 for( int j = 0; j < CV_HAAR_FEATURE_MAX; j++ )
290 if( rect[j].weight == 0.0F )
292 CV_TILTED_OFFSETS( fastRect[j].p0, fastRect[j].p1, fastRect[j].p2, fastRect[j].p3, rect[j].r, offset )
297 void CvHaarEvaluator::Feature::write( FileStorage &fs ) const
299 fs << CC_RECTS << "[";
300 for( int ri = 0; ri < CV_HAAR_FEATURE_MAX && rect[ri].r.width != 0; ++ri )
302 fs << "[:" << rect[ri].r.x << rect[ri].r.y <<
303 rect[ri].r.width << rect[ri].r.height << rect[ri].weight << "]";
305 fs << "]" << CC_TILTED << tilted;