Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/apps/traincascade/haarfeatures.cpp
16337 views
1
#include "opencv2/core.hpp"
2
#include "opencv2/imgproc.hpp"
3
4
#include "haarfeatures.h"
5
#include "cascadeclassifier.h"
6
7
using namespace std;
8
using namespace cv;
9
10
CvHaarFeatureParams::CvHaarFeatureParams() : mode(BASIC)
11
{
12
name = HFP_NAME;
13
}
14
15
CvHaarFeatureParams::CvHaarFeatureParams( int _mode ) : mode( _mode )
16
{
17
name = HFP_NAME;
18
}
19
20
void CvHaarFeatureParams::init( const CvFeatureParams& fp )
21
{
22
CvFeatureParams::init( fp );
23
mode = ((const CvHaarFeatureParams&)fp).mode;
24
}
25
26
void CvHaarFeatureParams::write( FileStorage &fs ) const
27
{
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;
34
}
35
36
bool CvHaarFeatureParams::read( const FileNode &node )
37
{
38
if( !CvFeatureParams::read( node ) )
39
return false;
40
41
FileNode rnode = node[CC_MODE];
42
if( !rnode.isString() )
43
return false;
44
string modeStr;
45
rnode >> modeStr;
46
mode = !modeStr.compare( CC_MODE_BASIC ) ? BASIC :
47
!modeStr.compare( CC_MODE_CORE ) ? CORE :
48
!modeStr.compare( CC_MODE_ALL ) ? ALL : -1;
49
return (mode >= 0);
50
}
51
52
void CvHaarFeatureParams::printDefaults() const
53
{
54
CvFeatureParams::printDefaults();
55
cout << " [-mode <" CC_MODE_BASIC << "(default) | "
56
<< CC_MODE_CORE <<" | " << CC_MODE_ALL << endl;
57
}
58
59
void CvHaarFeatureParams::printAttrs() const
60
{
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;
66
}
67
68
bool CvHaarFeatureParams::scanAttr( const string prmName, const string val)
69
{
70
if ( !CvFeatureParams::scanAttr( prmName, val ) )
71
{
72
if( !prmName.compare("-mode") )
73
{
74
mode = !val.compare( CC_MODE_CORE ) ? CORE :
75
!val.compare( CC_MODE_ALL ) ? ALL :
76
!val.compare( CC_MODE_BASIC ) ? BASIC : -1;
77
if (mode == -1)
78
return false;
79
}
80
return false;
81
}
82
return true;
83
}
84
85
//--------------------- HaarFeatureEvaluator ----------------
86
87
void CvHaarEvaluator::init(const CvFeatureParams *_featureParams,
88
int _maxSampleCount, Size _winSize )
89
{
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 );
96
}
97
98
void CvHaarEvaluator::setImage(const Mat& img, uchar clsLabel, int idx)
99
{
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 innSqSum;
104
if (((const CvHaarFeatureParams*)featureParams)->mode == CvHaarFeatureParams::ALL)
105
{
106
Mat innTilted(winSize.height + 1, winSize.width + 1, tilted.type(), tilted.ptr<int>((int)idx));
107
integral(img, innSum, innSqSum, innTilted);
108
}
109
else
110
integral(img, innSum, innSqSum);
111
normfactor.ptr<float>(0)[idx] = calcNormFactor( innSum, innSqSum );
112
}
113
114
void CvHaarEvaluator::writeFeatures( FileStorage &fs, const Mat& featureMap ) const
115
{
116
_writeFeatures( features, fs, featureMap );
117
}
118
119
void CvHaarEvaluator::writeFeature(FileStorage &fs, int fi) const
120
{
121
CV_DbgAssert( fi < (int)features.size() );
122
features[fi].write(fs);
123
}
124
125
void CvHaarEvaluator::generateFeatures()
126
{
127
int mode = ((const CvHaarFeatureParams*)((CvFeatureParams*)featureParams))->mode;
128
int offset = winSize.width + 1;
129
for( int x = 0; x < winSize.width; x++ )
130
{
131
for( int y = 0; y < winSize.height; y++ )
132
{
133
for( int dx = 1; dx <= winSize.width; dx++ )
134
{
135
for( int dy = 1; dy <= winSize.height; dy++ )
136
{
137
// haar_x2
138
if ( (x+dx*2 <= winSize.width) && (y+dy <= winSize.height) )
139
{
140
features.push_back( Feature( offset, false,
141
x, y, dx*2, dy, -1,
142
x+dx, y, dx , dy, +2 ) );
143
}
144
// haar_y2
145
if ( (x+dx <= winSize.width) && (y+dy*2 <= winSize.height) )
146
{
147
features.push_back( Feature( offset, false,
148
x, y, dx, dy*2, -1,
149
x, y+dy, dx, dy, +2 ) );
150
}
151
// haar_x3
152
if ( (x+dx*3 <= winSize.width) && (y+dy <= winSize.height) )
153
{
154
features.push_back( Feature( offset, false,
155
x, y, dx*3, dy, -1,
156
x+dx, y, dx , dy, +3 ) );
157
}
158
// haar_y3
159
if ( (x+dx <= winSize.width) && (y+dy*3 <= winSize.height) )
160
{
161
features.push_back( Feature( offset, false,
162
x, y, dx, dy*3, -1,
163
x, y+dy, dx, dy, +3 ) );
164
}
165
if( mode != CvHaarFeatureParams::BASIC )
166
{
167
// haar_x4
168
if ( (x+dx*4 <= winSize.width) && (y+dy <= winSize.height) )
169
{
170
features.push_back( Feature( offset, false,
171
x, y, dx*4, dy, -1,
172
x+dx, y, dx*2, dy, +2 ) );
173
}
174
// haar_y4
175
if ( (x+dx <= winSize.width ) && (y+dy*4 <= winSize.height) )
176
{
177
features.push_back( Feature( offset, false,
178
x, y, dx, dy*4, -1,
179
x, y+dy, dx, dy*2, +2 ) );
180
}
181
}
182
// x2_y2
183
if ( (x+dx*2 <= winSize.width) && (y+dy*2 <= winSize.height) )
184
{
185
features.push_back( Feature( offset, false,
186
x, y, dx*2, dy*2, -1,
187
x, y, dx, dy, +2,
188
x+dx, y+dy, dx, dy, +2 ) );
189
}
190
if (mode != CvHaarFeatureParams::BASIC)
191
{
192
if ( (x+dx*3 <= winSize.width) && (y+dy*3 <= winSize.height) )
193
{
194
features.push_back( Feature( offset, false,
195
x , y , dx*3, dy*3, -1,
196
x+dx, y+dy, dx , dy , +9) );
197
}
198
}
199
if (mode == CvHaarFeatureParams::ALL)
200
{
201
// tilted haar_x2
202
if ( (x+2*dx <= winSize.width) && (y+2*dx+dy <= winSize.height) && (x-dy>= 0) )
203
{
204
features.push_back( Feature( offset, true,
205
x, y, dx*2, dy, -1,
206
x, y, dx, dy, +2 ) );
207
}
208
// tilted haar_y2
209
if ( (x+dx <= winSize.width) && (y+dx+2*dy <= winSize.height) && (x-2*dy>= 0) )
210
{
211
features.push_back( Feature( offset, true,
212
x, y, dx, 2*dy, -1,
213
x, y, dx, dy, +2 ) );
214
}
215
// tilted haar_x3
216
if ( (x+3*dx <= winSize.width) && (y+3*dx+dy <= winSize.height) && (x-dy>= 0) )
217
{
218
features.push_back( Feature( offset, true,
219
x, y, dx*3, dy, -1,
220
x+dx, y+dx, dx, dy, +3 ) );
221
}
222
// tilted haar_y3
223
if ( (x+dx <= winSize.width) && (y+dx+3*dy <= winSize.height) && (x-3*dy>= 0) )
224
{
225
features.push_back( Feature( offset, true,
226
x, y, dx, 3*dy, -1,
227
x-dy, y+dy, dx, dy, +3 ) );
228
}
229
// tilted haar_x4
230
if ( (x+4*dx <= winSize.width) && (y+4*dx+dy <= winSize.height) && (x-dy>= 0) )
231
{
232
features.push_back( Feature( offset, true,
233
x, y, dx*4, dy, -1,
234
x+dx, y+dx, dx*2, dy, +2 ) );
235
}
236
// tilted haar_y4
237
if ( (x+dx <= winSize.width) && (y+dx+4*dy <= winSize.height) && (x-4*dy>= 0) )
238
{
239
features.push_back( Feature( offset, true,
240
x, y, dx, 4*dy, -1,
241
x-dy, y+dy, dx, 2*dy, +2 ) );
242
}
243
}
244
}
245
}
246
}
247
}
248
numFeatures = (int)features.size();
249
}
250
251
CvHaarEvaluator::Feature::Feature()
252
{
253
tilted = false;
254
rect[0].r = rect[1].r = rect[2].r = Rect(0,0,0,0);
255
rect[0].weight = rect[1].weight = rect[2].weight = 0;
256
}
257
258
CvHaarEvaluator::Feature::Feature( int offset, bool _tilted,
259
int x0, int y0, int w0, int h0, float wt0,
260
int x1, int y1, int w1, int h1, float wt1,
261
int x2, int y2, int w2, int h2, float wt2 )
262
{
263
tilted = _tilted;
264
265
rect[0].r.x = x0;
266
rect[0].r.y = y0;
267
rect[0].r.width = w0;
268
rect[0].r.height = h0;
269
rect[0].weight = wt0;
270
271
rect[1].r.x = x1;
272
rect[1].r.y = y1;
273
rect[1].r.width = w1;
274
rect[1].r.height = h1;
275
rect[1].weight = wt1;
276
277
rect[2].r.x = x2;
278
rect[2].r.y = y2;
279
rect[2].r.width = w2;
280
rect[2].r.height = h2;
281
rect[2].weight = wt2;
282
283
if( !tilted )
284
{
285
for( int j = 0; j < CV_HAAR_FEATURE_MAX; j++ )
286
{
287
if( rect[j].weight == 0.0F )
288
break;
289
CV_SUM_OFFSETS( fastRect[j].p0, fastRect[j].p1, fastRect[j].p2, fastRect[j].p3, rect[j].r, offset )
290
}
291
}
292
else
293
{
294
for( int j = 0; j < CV_HAAR_FEATURE_MAX; j++ )
295
{
296
if( rect[j].weight == 0.0F )
297
break;
298
CV_TILTED_OFFSETS( fastRect[j].p0, fastRect[j].p1, fastRect[j].p2, fastRect[j].p3, rect[j].r, offset )
299
}
300
}
301
}
302
303
void CvHaarEvaluator::Feature::write( FileStorage &fs ) const
304
{
305
fs << CC_RECTS << "[";
306
for( int ri = 0; ri < CV_HAAR_FEATURE_MAX && rect[ri].r.width != 0; ++ri )
307
{
308
fs << "[:" << rect[ri].r.x << rect[ri].r.y <<
309
rect[ri].r.width << rect[ri].r.height << rect[ri].weight << "]";
310
}
311
fs << "]" << CC_TILTED << tilted;
312
}
313
314