1 #include "opencv2/core/core.hpp"
2 #include "opencv2/core/internal.hpp"
4 #include "haarfeatures.h"
5 #include "cascadeclassifier.h"
10 CvHaarFeatureParams::CvHaarFeatureParams() : mode(BASIC)
15 CvHaarFeatureParams::CvHaarFeatureParams( int _mode ) : mode( _mode )
20 void CvHaarFeatureParams::init( const CvFeatureParams& fp )
22 CvFeatureParams::init( fp );
23 mode = ((const CvHaarFeatureParams&)fp).mode;
26 void CvHaarFeatureParams::write( FileStorage &fs ) const
28 CvFeatureParams::write( fs );
29 string modeStr = mode == BASIC ? CC_MODE_BASIC :
30 mode == CORE ? CC_MODE_CORE :
31 mode == ALL ? CC_MODE_ALL : string();
32 CV_Assert( !modeStr.empty() );
33 fs << CC_MODE << modeStr;
36 bool CvHaarFeatureParams::read( const FileNode &node )
38 if( !CvFeatureParams::read( node ) )
41 FileNode rnode = node[CC_MODE];
42 if( !rnode.isString() )
46 mode = !modeStr.compare( CC_MODE_BASIC ) ? BASIC :
47 !modeStr.compare( CC_MODE_CORE ) ? CORE :
48 !modeStr.compare( CC_MODE_ALL ) ? ALL : -1;
52 void CvHaarFeatureParams::printDefaults() const
54 CvFeatureParams::printDefaults();
55 cout << " [-mode <" CC_MODE_BASIC << "(default) | "
56 << CC_MODE_CORE <<" | " << CC_MODE_ALL << endl;
59 void CvHaarFeatureParams::printAttrs() const
61 CvFeatureParams::printAttrs();
62 string mode_str = mode == BASIC ? CC_MODE_BASIC :
63 mode == CORE ? CC_MODE_CORE :
64 mode == ALL ? CC_MODE_ALL : 0;
65 cout << "mode: " << mode_str << endl;
68 bool CvHaarFeatureParams::scanAttr( const string prmName, const string val)
70 if ( !CvFeatureParams::scanAttr( prmName, val ) )
72 if( !prmName.compare("-mode") )
74 mode = !val.compare( CC_MODE_CORE ) ? CORE :
75 !val.compare( CC_MODE_ALL ) ? ALL :
76 !val.compare( CC_MODE_BASIC ) ? BASIC : -1;
85 //--------------------- HaarFeatureEvaluator ----------------
87 void CvHaarEvaluator::init(const CvFeatureParams *_featureParams,
88 int _maxSampleCount, Size _winSize )
90 CV_Assert(_maxSampleCount > 0);
91 int cols = (_winSize.width + 1) * (_winSize.height + 1);
92 sum.create((int)_maxSampleCount, cols, CV_32SC1);
93 tilted.create((int)_maxSampleCount, cols, CV_32SC1);
94 normfactor.create(1, (int)_maxSampleCount, CV_32FC1);
95 CvFeatureEvaluator::init( _featureParams, _maxSampleCount, _winSize );
98 void CvHaarEvaluator::setImage(const Mat& img, uchar clsLabel, int idx)
100 CV_DbgAssert( !sum.empty() && !tilted.empty() && !normfactor.empty() );
101 CvFeatureEvaluator::setImage( img, clsLabel, idx);
102 Mat innSum(winSize.height + 1, winSize.width + 1, sum.type(), sum.ptr<int>((int)idx));
103 Mat innTilted(winSize.height + 1, winSize.width + 1, tilted.type(), tilted.ptr<int>((int)idx));
105 integral(img, innSum, innSqSum, innTilted);
106 normfactor.ptr<float>(0)[idx] = calcNormFactor( innSum, innSqSum );
109 void CvHaarEvaluator::writeFeatures( FileStorage &fs, const Mat& featureMap ) const
111 _writeFeatures( features, fs, featureMap );
114 void CvHaarEvaluator::writeFeature(FileStorage &fs, int fi) const
116 CV_DbgAssert( fi < (int)features.size() );
117 features[fi].write(fs);
120 void CvHaarEvaluator::generateFeatures()
122 int mode = ((const CvHaarFeatureParams*)((CvFeatureParams*)featureParams))->mode;
123 int offset = winSize.width + 1;
124 for( int x = 0; x < winSize.width; x++ )
126 for( int y = 0; y < winSize.height; y++ )
128 for( int dx = 1; dx <= winSize.width; dx++ )
130 for( int dy = 1; dy <= winSize.height; dy++ )
133 if ( (x+dx*2 <= winSize.width) && (y+dy <= winSize.height) )
135 features.push_back( Feature( offset, false,
137 x+dx, y, dx , dy, +2 ) );
140 if ( (x+dx <= winSize.width) && (y+dy*2 <= winSize.height) )
142 features.push_back( Feature( offset, false,
144 x, y+dy, dx, dy, +2 ) );
147 if ( (x+dx*3 <= winSize.width) && (y+dy <= winSize.height) )
149 features.push_back( Feature( offset, false,
151 x+dx, y, dx , dy, +3 ) );
154 if ( (x+dx <= winSize.width) && (y+dy*3 <= winSize.height) )
156 features.push_back( Feature( offset, false,
158 x, y+dy, dx, dy, +3 ) );
160 if( mode != CvHaarFeatureParams::BASIC )
163 if ( (x+dx*4 <= winSize.width) && (y+dy <= winSize.height) )
165 features.push_back( Feature( offset, false,
167 x+dx, y, dx*2, dy, +2 ) );
170 if ( (x+dx <= winSize.width ) && (y+dy*4 <= winSize.height) )
172 features.push_back( Feature( offset, false,
174 x, y+dy, dx, dy*2, +2 ) );
178 if ( (x+dx*2 <= winSize.width) && (y+dy*2 <= winSize.height) )
180 features.push_back( Feature( offset, false,
181 x, y, dx*2, dy*2, -1,
183 x+dx, y+dy, dx, dy, +2 ) );
185 if (mode != CvHaarFeatureParams::BASIC)
187 if ( (x+dx*3 <= winSize.width) && (y+dy*3 <= winSize.height) )
189 features.push_back( Feature( offset, false,
190 x , y , dx*3, dy*3, -1,
191 x+dx, y+dy, dx , dy , +9) );
194 if (mode == CvHaarFeatureParams::ALL)
197 if ( (x+2*dx <= winSize.width) && (y+2*dx+dy <= winSize.height) && (x-dy>= 0) )
199 features.push_back( Feature( offset, true,
201 x, y, dx, dy, +2 ) );
204 if ( (x+dx <= winSize.width) && (y+dx+2*dy <= winSize.height) && (x-2*dy>= 0) )
206 features.push_back( Feature( offset, true,
208 x, y, dx, dy, +2 ) );
211 if ( (x+3*dx <= winSize.width) && (y+3*dx+dy <= winSize.height) && (x-dy>= 0) )
213 features.push_back( Feature( offset, true,
215 x+dx, y+dx, dx, dy, +3 ) );
218 if ( (x+dx <= winSize.width) && (y+dx+3*dy <= winSize.height) && (x-3*dy>= 0) )
220 features.push_back( Feature( offset, true,
222 x-dy, y+dy, dx, dy, +3 ) );
225 if ( (x+4*dx <= winSize.width) && (y+4*dx+dy <= winSize.height) && (x-dy>= 0) )
227 features.push_back( Feature( offset, true,
229 x+dx, y+dx, dx*2, dy, +2 ) );
232 if ( (x+dx <= winSize.width) && (y+dx+4*dy <= winSize.height) && (x-4*dy>= 0) )
234 features.push_back( Feature( offset, true,
236 x-dy, y+dy, dx, 2*dy, +2 ) );
243 numFeatures = (int)features.size();
246 CvHaarEvaluator::Feature::Feature()
249 rect[0].r = rect[1].r = rect[2].r = Rect(0,0,0,0);
250 rect[0].weight = rect[1].weight = rect[2].weight = 0;
253 CvHaarEvaluator::Feature::Feature( int offset, bool _tilted,
254 int x0, int y0, int w0, int h0, float wt0,
255 int x1, int y1, int w1, int h1, float wt1,
256 int x2, int y2, int w2, int h2, float wt2 )
262 rect[0].r.width = w0;
263 rect[0].r.height = h0;
264 rect[0].weight = wt0;
268 rect[1].r.width = w1;
269 rect[1].r.height = h1;
270 rect[1].weight = wt1;
274 rect[2].r.width = w2;
275 rect[2].r.height = h2;
276 rect[2].weight = wt2;
280 for( int j = 0; j < CV_HAAR_FEATURE_MAX; j++ )
282 if( rect[j].weight == 0.0F )
284 CV_SUM_OFFSETS( fastRect[j].p0, fastRect[j].p1, fastRect[j].p2, fastRect[j].p3, rect[j].r, offset )
289 for( int j = 0; j < CV_HAAR_FEATURE_MAX; j++ )
291 if( rect[j].weight == 0.0F )
293 CV_TILTED_OFFSETS( fastRect[j].p0, fastRect[j].p1, fastRect[j].p2, fastRect[j].p3, rect[j].r, offset )
298 void CvHaarEvaluator::Feature::write( FileStorage &fs ) const
300 fs << CC_RECTS << "[";
301 for( int ri = 0; ri < CV_HAAR_FEATURE_MAX && rect[ri].r.width != 0; ++ri )
303 fs << "[:" << rect[ri].r.x << rect[ri].r.y <<
304 rect[ri].r.width << rect[ri].r.height << rect[ri].weight << "]";
306 fs << "]" << CC_TILTED << tilted;