Commit b277fd20fe92fa7f3e128e5fbc3724a150aa2149

Authored by Jordan Cheney
1 parent 447ef443

Integrated representations into the backend and reformatted into a classifier

openbr/core/boost.cpp
... ... @@ -137,6 +137,28 @@ static CvMat* cvPreprocessIndexArray( const CvMat* idx_arr, int data_arr_size, b
137 137 return idx;
138 138 }
139 139  
  140 +//------------------------------------- FeatureEvaluator ---------------------------------------
  141 +
  142 +void FeatureEvaluator::init(Representation *_representation, int _maxSampleCount)
  143 +{
  144 + representation = _representation;
  145 + data.create((int)_maxSampleCount, representation->postWindowSize().area(), CV_32SC1);
  146 + cls.create( (int)_maxSampleCount, 1, CV_32FC1 );
  147 +}
  148 +
  149 +void FeatureEvaluator::setImage(const Mat &img, uchar clsLabel, int idx)
  150 +{
  151 + cls.ptr<float>(idx)[0] = clsLabel;
  152 +
  153 + Mat integralImg(representation->postWindowSize(), data.type(), data.ptr<int>(idx));
  154 + representation->preprocess(img, integralImg);
  155 +}
  156 +
  157 +void FeatureEvaluator::writeFeatures(FileStorage &fs, const Mat &featureMap) const
  158 +{
  159 + representation->write(fs, featureMap);
  160 +}
  161 +
140 162 //----------------------------- CascadeBoostParams -------------------------------------------------
141 163  
142 164 CascadeBoostParams::CascadeBoostParams() : minHitRate( 0.995F), maxFalseAlarm( 0.5F )
... ...
openbr/core/boost.h
1 1 #ifndef _BOOST_H_
2 2 #define _BOOST_H_
3 3  
4   -#include "features.h"
5 4 #include "ml.h"
  5 +#include <openbr/openbr_plugin.h>
  6 +
  7 +#define CC_CASCADE_FILENAME "cascade.xml"
  8 +#define CC_PARAMS_FILENAME "params.xml"
  9 +
  10 +#define CC_CASCADE_PARAMS "cascadeParams"
  11 +#define CC_STAGE_TYPE "stageType"
  12 +#define CC_FEATURE_TYPE "featureType"
  13 +#define CC_HEIGHT "height"
  14 +#define CC_WIDTH "width"
  15 +
  16 +#define CC_STAGE_NUM "stageNum"
  17 +#define CC_STAGES "stages"
  18 +#define CC_STAGE_PARAMS "stageParams"
  19 +
  20 +#define CC_BOOST "BOOST"
  21 +#define CC_BOOST_TYPE "boostType"
  22 +#define CC_DISCRETE_BOOST "DAB"
  23 +#define CC_REAL_BOOST "RAB"
  24 +#define CC_LOGIT_BOOST "LB"
  25 +#define CC_GENTLE_BOOST "GAB"
  26 +#define CC_MINHITRATE "minHitRate"
  27 +#define CC_MAXFALSEALARM "maxFalseAlarm"
  28 +#define CC_TRIM_RATE "weightTrimRate"
  29 +#define CC_MAX_DEPTH "maxDeptrh"
  30 +#define CC_WEAK_COUNT "maxWeakCount"
  31 +#define CC_STAGE_THRESHOLD "stageThreshold"
  32 +#define CC_WEAK_CLASSIFIERS "weakClassifiers"
  33 +#define CC_INTERNAL_NODES "internalNodes"
  34 +#define CC_LEAF_VALUES "leafValues"
  35 +
  36 +#define CC_FEATURES "features"
  37 +#define CC_FEATURE_PARAMS "featureParams"
  38 +#define CC_MAX_CAT_COUNT "maxCatCount"
  39 +#define CC_FEATURE_SIZE "featSize"
  40 +
  41 +#define CC_LBP "LBP"
  42 +#define CC_RECT "rect"
  43 +
  44 +#ifdef _WIN32
  45 +#define TIME( arg ) (((double) clock()) / CLOCKS_PER_SEC)
  46 +#else
  47 +#define TIME( arg ) (time( arg ))
  48 +#endif
6 49  
7 50 namespace br
8 51 {
9 52  
  53 +struct FeatureEvaluator
  54 +{
  55 + ~FeatureEvaluator() {}
  56 + void init(Representation *_representation, int _maxSampleCount);
  57 + void setImage(const cv::Mat& img, uchar clsLabel, int idx);
  58 + void writeFeatures(cv::FileStorage &fs, const cv::Mat& featureMap) const;
  59 + float operator()(int featureIdx, int sampleIdx) const { return representation->evaluate(data.row(sampleIdx), featureIdx); }
  60 +
  61 + int getNumFeatures() const { return representation->numFeatures(); }
  62 + int getMaxCatCount() const { return representation->maxCatCount(); }
  63 + int getFeatureSize() const { return 1; }
  64 + const cv::Mat& getCls() const { return cls; }
  65 + float getCls(int si) const { return cls.at<float>(si, 0); }
  66 +
  67 + cv::Mat data, cls;
  68 + Representation *representation;
  69 +};
  70 +
10 71 struct CascadeBoostParams : CvBoostParams
11 72 {
12 73 float minHitRate;
... ...
openbr/core/cascade.cpp deleted
1   -#include "cascade.h"
2   -#include <stdio.h>
3   -#include <iostream>
4   -#include <fstream>
5   -
6   -using namespace std;
7   -using namespace br;
8   -using namespace cv;
9   -
10   -bool CascadeImageReader::create(const QList<Mat> &_posImages, const QList<Mat> &_negImages, Size _winSize)
11   -{
12   - posImages = _posImages;
13   - negImages = _negImages;
14   - winSize = _winSize;
15   -
16   - posIdx = negIdx = 0;
17   -
18   - src.create( 0, 0 , CV_8UC1 );
19   - img.create( 0, 0, CV_8UC1 );
20   - point = offset = Point( 0, 0 );
21   - scale = 1.0F;
22   - scaleFactor = 1.4142135623730950488016887242097F;
23   - stepFactor = 0.5F;
24   - round = 0;
25   -
26   - return true;
27   -}
28   -
29   -bool CascadeImageReader::nextNeg()
30   -{
31   - Point _offset = Point(0,0);
32   - size_t count = negImages.size();
33   - for (size_t i = 0; i < count; i++) {
34   - src = negImages[negIdx++];
35   - if( src.empty() )
36   - continue;
37   - round += negIdx / count;
38   - round = round % (winSize.width * winSize.height);
39   - negIdx %= count;
40   -
41   - _offset.x = std::min( (int)round % winSize.width, src.cols - winSize.width );
42   - _offset.y = std::min( (int)round / winSize.width, src.rows - winSize.height );
43   - if( !src.empty() && src.type() == CV_8UC1 && _offset.x >= 0 && _offset.y >= 0 )
44   - break;
45   - }
46   -
47   - if( src.empty() )
48   - return false; // no appropriate image
49   - point = offset = _offset;
50   - scale = max( ((float)winSize.width + point.x) / ((float)src.cols),
51   - ((float)winSize.height + point.y) / ((float)src.rows) );
52   -
53   - Size sz( (int)(scale*src.cols + 0.5F), (int)(scale*src.rows + 0.5F) );
54   - resize( src, img, sz );
55   - return true;
56   -}
57   -
58   -bool CascadeImageReader::getNeg( Mat& _img )
59   -{
60   - CV_Assert( !_img.empty() );
61   - CV_Assert( _img.type() == CV_8UC1 );
62   - CV_Assert( _img.cols == winSize.width );
63   - CV_Assert( _img.rows == winSize.height );
64   -
65   - if( img.empty() )
66   - if ( !nextNeg() )
67   - return false;
68   -
69   - Mat mat( winSize.height, winSize.width, CV_8UC1,
70   - (void*)(img.data + point.y * img.step + point.x * img.elemSize()), img.step );
71   - mat.copyTo(_img);
72   -
73   - if( (int)( point.x + (1.0F + stepFactor ) * winSize.width ) < img.cols )
74   - point.x += (int)(stepFactor * winSize.width);
75   - else
76   - {
77   - point.x = offset.x;
78   - if( (int)( point.y + (1.0F + stepFactor ) * winSize.height ) < img.rows )
79   - point.y += (int)(stepFactor * winSize.height);
80   - else
81   - {
82   - point.y = offset.y;
83   - scale *= scaleFactor;
84   - if( scale <= 1.0F )
85   - resize( src, img, Size( (int)(scale*src.cols), (int)(scale*src.rows) ) );
86   - else
87   - {
88   - if ( !nextNeg() )
89   - return false;
90   - }
91   - }
92   - }
93   - return true;
94   -}
95   -
96   -
97   -bool CascadeImageReader::getPos(Mat &_img)
98   -{
99   - posImages[posIdx++].copyTo(_img);
100   - return true;
101   -}
102   -
103   -//---------------------------- CascadeClassifier --------------------------------------
104   -
105   -bool BrCascadeClassifier::train(const string _cascadeDirName,
106   - const QList<Mat> &_posImages,
107   - const QList<Mat> &_negImages,
108   - int _numPos, int _numNeg,
109   - int _precalcValBufSize, int _precalcIdxBufSize,
110   - int _numStages,
111   - Size _winSize,
112   - const CascadeBoostParams& _stageParams)
113   -{
114   - // Start recording clock ticks for training time output
115   - const clock_t begin_time = clock();
116   -
117   - if (_cascadeDirName.empty())
118   - CV_Error( CV_StsBadArg, "_cascadeDirName is NULL" );
119   -
120   - string dirName;
121   - if (_cascadeDirName.find_last_of("/\\") == (_cascadeDirName.length() - 1) )
122   - dirName = _cascadeDirName;
123   - else
124   - dirName = _cascadeDirName + '/';
125   -
126   - winSize = _winSize;
127   -
128   - numPos = _numPos;
129   - numNeg = _numNeg;
130   - numStages = _numStages;
131   - imgReader.create(_posImages, _negImages, winSize);
132   -
133   - Representation *representation = Representation::make("MBLBP(24,24)", NULL);
134   -
135   - stageParams = new CascadeBoostParams;
136   - *stageParams = _stageParams;
137   - featureEvaluator = new FeatureEvaluator;
138   - featureEvaluator->init(representation, numPos + numNeg);
139   - stageClassifiers.reserve( numStages );
140   -
141   - double requiredLeafFARate = pow( (double) stageParams->maxFalseAlarm, (double) numStages ) /
142   - (double)stageParams->max_depth;
143   - double tempLeafFARate;
144   -
145   - for (int i = 0; i < numStages; i++) {
146   - cout << endl << "===== TRAINING " << i << "-stage =====" << endl;
147   - cout << "<BEGIN" << endl;
148   - if (!updateTrainingSet(tempLeafFARate)) {
149   - cout << "Train dataset for temp stage can not be filled. "
150   - "Branch training terminated." << endl;
151   - break;
152   - }
153   - if (tempLeafFARate <= requiredLeafFARate) {
154   - cout << "Required leaf false alarm rate achieved. "
155   - "Branch training terminated." << endl;
156   - break;
157   - }
158   -
159   - CascadeBoost* tempStage = new CascadeBoost;
160   - bool isStageTrained = tempStage->train( (FeatureEvaluator*)featureEvaluator,
161   - curNumSamples, _precalcValBufSize, _precalcIdxBufSize,
162   - *((CascadeBoostParams*)stageParams) );
163   - cout << "END>" << endl;
164   -
165   - if (!isStageTrained)
166   - break;
167   -
168   - stageClassifiers.push_back(tempStage);
169   -
170   - // Output training time up till now
171   - float seconds = float( clock () - begin_time ) / CLOCKS_PER_SEC;
172   - int days = int(seconds) / 60 / 60 / 24;
173   - int hours = (int(seconds) / 60 / 60) % 24;
174   - int minutes = (int(seconds) / 60) % 60;
175   - int seconds_left = int(seconds) % 60;
176   - cout << "Training until now has taken " << days << " days " << hours << " hours " << minutes << " minutes " << seconds_left <<" seconds." << endl;
177   - }
178   -
179   - if (stageClassifiers.size() == 0) {
180   - cout << "Cascade classifier can't be trained. Check the used training parameters." << endl;
181   - return false;
182   - }
183   -
184   - save(dirName + CC_CASCADE_FILENAME);
185   -
186   - return true;
187   -}
188   -
189   -int BrCascadeClassifier::predict( int sampleIdx )
190   -{
191   - CV_DbgAssert( sampleIdx < numPos + numNeg );
192   - for (vector< Ptr<CascadeBoost> >::iterator it = stageClassifiers.begin();
193   - it != stageClassifiers.end(); it++ )
194   - {
195   - if ( (*it)->predict( sampleIdx ) == 0.f )
196   - return 0;
197   - }
198   - return 1;
199   -}
200   -
201   -bool BrCascadeClassifier::updateTrainingSet( double& acceptanceRatio)
202   -{
203   - int64 posConsumed = 0, negConsumed = 0;
204   - imgReader.restart();
205   -
206   - int posCount = fillPassedSamples( 0, numPos, true, posConsumed );
207   - if( !posCount )
208   - return false;
209   - cout << "POS count : consumed " << posCount << " : " << (int)posConsumed << endl;
210   -
211   - int proNumNeg = cvRound( ( ((double)numNeg) * ((double)posCount) ) / numPos ); // apply only a fraction of negative samples. double is required since overflow is possible
212   - int negCount = fillPassedSamples( posCount, proNumNeg, false, negConsumed );
213   - if ( !negCount )
214   - return false;
215   -
216   - curNumSamples = posCount + negCount;
217   - acceptanceRatio = negConsumed == 0 ? 0 : ( (double)negCount/(double)(int64)negConsumed );
218   - cout << "NEG count : acceptanceRatio " << negCount << " : " << acceptanceRatio << endl;
219   - return true;
220   -}
221   -
222   -int BrCascadeClassifier::fillPassedSamples( int first, int count, bool isPositive, int64& consumed )
223   -{
224   - int getcount = 0;
225   - Mat img(winSize, CV_8UC1);
226   - for( int i = first; i < first + count; i++ )
227   - {
228   - for( ; ; )
229   - {
230   - bool isGetImg = isPositive ? imgReader.getPos( img ) :
231   - imgReader.getNeg( img );
232   - if( !isGetImg )
233   - return getcount;
234   - consumed++;
235   -
236   - featureEvaluator->setImage( img, isPositive ? 1 : 0, i );
237   - if( predict( i ) == 1.0F )
238   - {
239   - getcount++;
240   - printf("%s current samples: %d\r", isPositive ? "POS":"NEG", getcount);
241   - break;
242   - }
243   - }
244   - }
245   - return getcount;
246   -}
247   -
248   -void BrCascadeClassifier::writeParams( FileStorage &fs ) const
249   -{
250   - fs << CC_STAGE_TYPE << CC_BOOST;
251   - fs << CC_FEATURE_TYPE << CC_LBP;
252   - fs << CC_HEIGHT << winSize.height;
253   - fs << CC_WIDTH << winSize.width;
254   -
255   - fs << CC_STAGE_PARAMS << "{"; stageParams->write( fs ); fs << "}";
256   -
257   - fs << CC_FEATURE_PARAMS << "{";
258   - fs << CC_MAX_CAT_COUNT << featureEvaluator->getMaxCatCount();
259   - fs << CC_FEATURE_SIZE << featureEvaluator->getFeatureSize();
260   - fs << "}";
261   -}
262   -
263   -void BrCascadeClassifier::writeFeatures( FileStorage &fs, const Mat& featureMap ) const
264   -{
265   - ((FeatureEvaluator*)((Ptr<FeatureEvaluator>)featureEvaluator))->writeFeatures( fs, featureMap );
266   -}
267   -
268   -void BrCascadeClassifier::writeStages( FileStorage &fs, const Mat& featureMap ) const
269   -{
270   - char cmnt[30];
271   - int i = 0;
272   - fs << CC_STAGES << "[";
273   - for( vector< Ptr<CascadeBoost> >::const_iterator it = stageClassifiers.begin();
274   - it != stageClassifiers.end(); it++, i++ )
275   - {
276   - sprintf( cmnt, "stage %d", i );
277   - cvWriteComment( fs.fs, cmnt, 0 );
278   - fs << "{";
279   - ((CascadeBoost*)((Ptr<CascadeBoost>)*it))->write( fs, featureMap );
280   - fs << "}";
281   - }
282   - fs << "]";
283   -}
284   -
285   -void BrCascadeClassifier::save(const string filename)
286   -{
287   - FileStorage fs( filename, FileStorage::WRITE );
288   -
289   - if ( !fs.isOpened() )
290   - return;
291   -
292   - fs << FileStorage::getDefaultObjectName(filename) << "{";
293   -
294   - Mat featureMap;
295   - getUsedFeaturesIdxMap( featureMap );
296   - writeParams( fs );
297   - fs << CC_STAGE_NUM << (int)stageClassifiers.size();
298   - writeStages( fs, featureMap );
299   - writeFeatures( fs, featureMap );
300   -
301   - fs << "}";
302   -}
303   -
304   -void BrCascadeClassifier::getUsedFeaturesIdxMap( Mat& featureMap )
305   -{
306   - int varCount = featureEvaluator->getNumFeatures() * featureEvaluator->getFeatureSize();
307   - featureMap.create( 1, varCount, CV_32SC1 );
308   - featureMap.setTo(Scalar(-1));
309   -
310   - for( vector< Ptr<CascadeBoost> >::const_iterator it = stageClassifiers.begin();
311   - it != stageClassifiers.end(); it++ )
312   - ((CascadeBoost*)((Ptr<CascadeBoost>)(*it)))->markUsedFeaturesInMap( featureMap );
313   -
314   - for( int fi = 0, idx = 0; fi < varCount; fi++ )
315   - if ( featureMap.at<int>(0, fi) >= 0 )
316   - featureMap.ptr<int>(0)[fi] = idx++;
317   -}
318   -
openbr/core/cascade.h deleted
1   -#ifndef CASCADE_H
2   -#define CASCADE_H
3   -
4   -#include <openbr/openbr_plugin.h>
5   -#include <opencv2/highgui/highgui.hpp>
6   -#include "features.h"
7   -#include "boost.h"
8   -
9   -namespace br
10   -{
11   -
12   -class CascadeImageReader
13   -{
14   -public:
15   - bool create( const QList<cv::Mat> &_posImages, const QList<cv::Mat> &_negImages, cv::Size _winSize );
16   - void restart() { posIdx = 0; }
17   - bool getNeg(cv::Mat &_img);
18   - bool getPos(cv::Mat &_img);
19   -
20   - QList<cv::Mat> posImages, negImages;
21   -
22   - int posIdx, negIdx;
23   -
24   - cv::Mat src, img;
25   - cv::Point offset, point;
26   - float scale;
27   - float scaleFactor;
28   - float stepFactor;
29   - size_t round;
30   - cv::Size winSize;
31   -
32   -private:
33   - bool nextNeg();
34   -};
35   -
36   -
37   -class BrCascadeClassifier
38   -{
39   -public:
40   - bool train(const std::string _cascadeDirName,
41   - const QList<cv::Mat> &_posImages,
42   - const QList<cv::Mat> &_negImages,
43   - int _numPos, int _numNeg,
44   - int _precalcValBufSize, int _precalcIdxBufSize,
45   - int _numStages,
46   - cv::Size _winSize,
47   - const CascadeBoostParams& _stageParams);
48   -private:
49   - int predict(int sampleIdx);
50   - void save(const std::string cascadeDirName);
51   - bool updateTrainingSet(double& acceptanceRatio);
52   - int fillPassedSamples(int first, int count, bool isPositive, int64& consumed);
53   -
54   - void writeParams(cv::FileStorage &fs) const;
55   - void writeStages(cv::FileStorage &fs, const cv::Mat& featureMap) const;
56   - void writeFeatures(cv::FileStorage &fs, const cv::Mat& featureMap) const;
57   -
58   - void getUsedFeaturesIdxMap(cv::Mat& featureMap);
59   -
60   - cv::Ptr<CascadeBoostParams> stageParams;
61   -
62   - cv::Ptr<FeatureEvaluator> featureEvaluator;
63   - std::vector< cv::Ptr<CascadeBoost> > stageClassifiers;
64   - CascadeImageReader imgReader;
65   - int numStages, curNumSamples;
66   - int numPos, numNeg;
67   - cv::Size winSize;
68   -};
69   -
70   -} // namespace br
71   -
72   -#endif // CASCADE_H
openbr/core/features.cpp deleted
1   -#include "features.h"
2   -
3   -using namespace cv;
4   -using namespace br;
5   -
6   -//------------------------------------- FeatureEvaluator ---------------------------------------
7   -
8   -void FeatureEvaluator::init(Representation *_representation, int _maxSampleCount)
9   -{
10   - representation = _representation;
11   - data.create((int)_maxSampleCount, representation->postWindowSize().area(), CV_32SC1);
12   - cls.create( (int)_maxSampleCount, 1, CV_32FC1 );
13   -}
14   -
15   -void FeatureEvaluator::setImage(const Mat &img, uchar clsLabel, int idx)
16   -{
17   - cls.ptr<float>(idx)[0] = clsLabel;
18   -
19   - Mat integralImg(representation->postWindowSize(), data.type(), data.ptr<int>(idx));
20   - representation->preprocess(img, integralImg);
21   -}
22   -
23   -void FeatureEvaluator::writeFeatures(FileStorage &fs, const Mat &featureMap) const
24   -{
25   - representation->write(fs, featureMap);
26   -}
openbr/core/features.h deleted
1   -#ifndef FEATURE_H
2   -#define FEATURE_H
3   -
4   -#include <openbr/openbr_plugin.h>
5   -#include "opencv2/imgproc/imgproc.hpp"
6   -#include <iostream>
7   -
8   -#define CC_CASCADE_FILENAME "cascade.xml"
9   -#define CC_PARAMS_FILENAME "params.xml"
10   -
11   -#define CC_CASCADE_PARAMS "cascadeParams"
12   -#define CC_STAGE_TYPE "stageType"
13   -#define CC_FEATURE_TYPE "featureType"
14   -#define CC_HEIGHT "height"
15   -#define CC_WIDTH "width"
16   -
17   -#define CC_STAGE_NUM "stageNum"
18   -#define CC_STAGES "stages"
19   -#define CC_STAGE_PARAMS "stageParams"
20   -
21   -#define CC_BOOST "BOOST"
22   -#define CC_BOOST_TYPE "boostType"
23   -#define CC_DISCRETE_BOOST "DAB"
24   -#define CC_REAL_BOOST "RAB"
25   -#define CC_LOGIT_BOOST "LB"
26   -#define CC_GENTLE_BOOST "GAB"
27   -#define CC_MINHITRATE "minHitRate"
28   -#define CC_MAXFALSEALARM "maxFalseAlarm"
29   -#define CC_TRIM_RATE "weightTrimRate"
30   -#define CC_MAX_DEPTH "maxDeptrh"
31   -#define CC_WEAK_COUNT "maxWeakCount"
32   -#define CC_STAGE_THRESHOLD "stageThreshold"
33   -#define CC_WEAK_CLASSIFIERS "weakClassifiers"
34   -#define CC_INTERNAL_NODES "internalNodes"
35   -#define CC_LEAF_VALUES "leafValues"
36   -
37   -#define CC_FEATURES "features"
38   -#define CC_FEATURE_PARAMS "featureParams"
39   -#define CC_MAX_CAT_COUNT "maxCatCount"
40   -#define CC_FEATURE_SIZE "featSize"
41   -
42   -#define CC_LBP "LBP"
43   -#define CC_RECT "rect"
44   -
45   -#ifdef _WIN32
46   -#define TIME( arg ) (((double) clock()) / CLOCKS_PER_SEC)
47   -#else
48   -#define TIME( arg ) (time( arg ))
49   -#endif
50   -
51   -namespace br
52   -{
53   -
54   -class FeatureEvaluator
55   -{
56   -public:
57   - ~FeatureEvaluator() {}
58   - void init(Representation *_representation, int _maxSampleCount);
59   - void setImage(const cv::Mat& img, uchar clsLabel, int idx);
60   - void writeFeatures(cv::FileStorage &fs, const cv::Mat& featureMap) const;
61   - float operator()(int featureIdx, int sampleIdx) const { return representation->evaluate(data.row(sampleIdx), featureIdx); }
62   -
63   - int getNumFeatures() const { return representation->numFeatures(); }
64   - int getMaxCatCount() const { return representation->maxCatCount(); }
65   - int getFeatureSize() const { return 1; }
66   - const cv::Mat& getCls() const { return cls; }
67   - float getCls(int si) const { return cls.at<float>(si, 0); }
68   -
69   - cv::Mat data, cls;
70   - Representation *representation;
71   -};
72   -
73   -} // namespace br
74   -
75   -#endif // FEATURE_H
openbr/openbr_plugin.h
... ... @@ -1395,11 +1395,6 @@ class BR_EXPORT Representation : public Object
1395 1395 {
1396 1396 Q_OBJECT
1397 1397  
1398   - Q_PROPERTY(int winWidth READ get_winWidth WRITE set_winWidth RESET reset_winWidth STORED false)
1399   - Q_PROPERTY(int winHeight READ get_winHeight WRITE set_winHeight RESET reset_winHeight STORED false)
1400   - BR_PROPERTY(int, winWidth, 24)
1401   - BR_PROPERTY(int, winHeight, 24)
1402   -
1403 1398 public:
1404 1399 virtual ~Representation() {}
1405 1400  
... ...
openbr/plugins/classification/boostedforest.cpp
1 1 #include <openbr/plugins/openbr_internal.h>
2 2 #include <openbr/core/boost.h>
3   -#include <openbr/core/features.h>
4 3  
5 4 using namespace cv;
6 5  
... ...
openbr/plugins/classification/cascade.cpp
  1 +#include <opencv2/imgproc/imgproc.hpp>
  2 +
1 3 #include <openbr/plugins/openbr_internal.h>
2   -#include <openbr/core/features.h>
3 4 #include <openbr/core/boost.h>
4 5  
5 6 using namespace cv;
... ... @@ -9,7 +10,7 @@ namespace br
9 10  
10 11 struct ImageHandler
11 12 {
12   - bool create( const QList<cv::Mat> &_posImages, const QList<cv::Mat> &_negImages, cv::Size _winSize )
  13 + bool create(const QList<Mat> &_posImages, const QList<Mat> &_negImages, Size _winSize)
13 14 {
14 15 posImages = _posImages;
15 16 negImages = _negImages;
... ... @@ -30,72 +31,57 @@ struct ImageHandler
30 31  
31 32 void restart() { posIdx = 0; }
32 33  
33   - int numPos() const { return posImages.size(); }
34   - int numNeg() const { return negImages.size(); }
35   -
36   - bool nextNeg()
  34 + void nextNeg()
37 35 {
38   - Point _offset = Point(0,0);
39   - size_t count = negImages.size();
40   - for (size_t i = 0; i < count; i++) {
  36 + int count = negImages.size();
  37 + for (int i = 0; i < count; i++) {
41 38 src = negImages[negIdx++];
42   - if( src.empty() )
43   - continue;
  39 +
44 40 round += negIdx / count;
45 41 round = round % (winSize.width * winSize.height);
46 42 negIdx %= count;
47 43  
48   - _offset.x = std::min( (int)round % winSize.width, src.cols - winSize.width );
49   - _offset.y = std::min( (int)round / winSize.width, src.rows - winSize.height );
50   - if( !src.empty() && src.type() == CV_8UC1 && _offset.x >= 0 && _offset.y >= 0 )
  44 + offset.x = qMin( (int)round % winSize.width, src.cols - winSize.width );
  45 + offset.y = qMin( (int)round / winSize.width, src.rows - winSize.height );
  46 + if (!src.empty() && src.type() == CV_8UC1 && offset.x >= 0 && offset.y >= 0)
51 47 break;
52 48 }
53 49  
54   - if( src.empty() )
55   - return false; // no appropriate image
56   - point = offset = _offset;
57   - scale = max( ((float)winSize.width + point.x) / ((float)src.cols),
58   - ((float)winSize.height + point.y) / ((float)src.rows) );
  50 + point = offset;
  51 + scale = max(((float)winSize.width + point.x) / ((float)src.cols),
  52 + ((float)winSize.height + point.y) / ((float)src.rows));
59 53  
60   - Size sz( (int)(scale*src.cols + 0.5F), (int)(scale*src.rows + 0.5F) );
61   - resize( src, img, sz );
62   - return true;
  54 + Size sz((int)(scale*src.cols + 0.5F), (int)(scale*src.rows + 0.5F));
  55 + resize(src, img, sz);
63 56 }
64 57  
65   - bool getNeg(cv::Mat &_img)
  58 + bool getNeg(Mat &_img)
66 59 {
67   - if( img.empty() )
68   - if ( !nextNeg() )
69   - return false;
  60 + if (img.empty())
  61 + nextNeg();
70 62  
71   - Mat mat( winSize.height, winSize.width, CV_8UC1,
72   - (void*)(img.data + point.y * img.step + point.x * img.elemSize()), img.step );
73   - mat.copyTo(_img);
  63 + Mat m(winSize.height, winSize.width, CV_8UC1, (void*)(img.data + point.y * img.step + point.x * img.elemSize()), img.step);
  64 + m.copyTo(_img);
74 65  
75   - if( (int)( point.x + (1.0F + stepFactor ) * winSize.width ) < img.cols )
  66 + if ((int)(point.x + (1.0F + stepFactor) * winSize.width) < img.cols)
76 67 point.x += (int)(stepFactor * winSize.width);
77   - else
78   - {
  68 + else {
79 69 point.x = offset.x;
80   - if( (int)( point.y + (1.0F + stepFactor ) * winSize.height ) < img.rows )
  70 + if ((int)( point.y + (1.0F + stepFactor ) * winSize.height ) < img.rows)
81 71 point.y += (int)(stepFactor * winSize.height);
82   - else
83   - {
  72 + else {
84 73 point.y = offset.y;
85 74 scale *= scaleFactor;
86   - if( scale <= 1.0F )
87   - resize( src, img, Size( (int)(scale*src.cols), (int)(scale*src.rows) ) );
  75 + if (scale <= 1.0F)
  76 + resize(src, img, Size((int)(scale*src.cols), (int)(scale*src.rows)));
88 77 else
89   - {
90   - if ( !nextNeg() )
91   - return false;
92   - }
  78 + nextNeg();
93 79 }
94 80 }
95 81 return true;
96 82 }
97 83  
98   - bool getPos(cv::Mat &_img)
  84 + bool getPos(Mat &_img)
99 85 {
100 86 if (posIdx >= posImages.size())
101 87 return false;
... ... @@ -104,20 +90,20 @@ struct ImageHandler
104 90 return true;
105 91 }
106 92  
107   - QList<cv::Mat> posImages, negImages;
  93 + QList<Mat> posImages, negImages;
108 94  
109 95 int posIdx, negIdx;
110 96  
111   - cv::Mat src, img;
112   - cv::Point offset, point;
  97 + Mat src, img;
  98 + Point offset, point;
113 99 float scale;
114 100 float scaleFactor;
115 101 float stepFactor;
116 102 size_t round;
117   - cv::Size winSize;
  103 + Size winSize;
118 104 };
119 105  
120   -class _CascadeClassifier : public Classifier
  106 +class CascadeClassifier : public Classifier
121 107 {
122 108 Q_OBJECT
123 109  
... ... @@ -242,6 +228,7 @@ private:
242 228 qFatal("Cannot get another positive sample!");
243 229  
244 230 if (classify(pos) == 1.0f) {
  231 + printf("POS current samples: %d\r", images.size());
245 232 images.append(pos);
246 233 labels.append(1.0f);
247 234 }
... ... @@ -257,6 +244,7 @@ private:
257 244 qFatal("Cannot get another negative sample!");
258 245  
259 246 if (classify(neg) == 1.0f) {
  247 + printf("NEG current samples: %d\r", images.size() - posCount);
260 248 images.append(neg);
261 249 labels.append(0.0f);
262 250 }
... ... @@ -269,7 +257,7 @@ private:
269 257 }
270 258 };
271 259  
272   -BR_REGISTER(Classifier, _CascadeClassifier)
  260 +BR_REGISTER(Classifier, CascadeClassifier)
273 261  
274 262 } // namespace br
275 263  
... ...
openbr/plugins/metadata/cascade.cpp
... ... @@ -22,7 +22,6 @@
22 22 #include <openbr/core/opencvutils.h>
23 23 #include <openbr/core/resource.h>
24 24 #include <openbr/core/qtutils.h>
25   -#include <openbr/core/cascade.h>
26 25  
27 26 using namespace cv;
28 27  
... ... @@ -65,34 +64,19 @@ private:
65 64 * \author Josh Klontz \cite jklontz
66 65 * \author David Crouse \cite dgcrouse
67 66 */
68   -class CascadeTransform : public MetaTransform
  67 +class CascadeTransform : public UntrainableMetaTransform
69 68 {
70 69 Q_OBJECT
71 70 Q_PROPERTY(QString model READ get_model WRITE set_model RESET reset_model STORED false)
72 71 Q_PROPERTY(int minSize READ get_minSize WRITE set_minSize RESET reset_minSize STORED false)
73 72 Q_PROPERTY(int minNeighbors READ get_minNeighbors WRITE set_minNeighbors RESET reset_minNeighbors STORED false)
74 73 Q_PROPERTY(bool ROCMode READ get_ROCMode WRITE set_ROCMode RESET reset_ROCMode STORED false)
75   -
76   - // Training parameters
77   - Q_PROPERTY(QString vecFile READ get_vecFile WRITE set_vecFile RESET reset_vecFile STORED false)
78   - Q_PROPERTY(QString negFile READ get_negFile WRITE set_negFile RESET reset_negFile STORED false)
79   - Q_PROPERTY(int winWidth READ get_winWidth WRITE set_winWidth RESET reset_winWidth STORED false)
80   - Q_PROPERTY(int winHeight READ get_winHeight WRITE set_winHeight RESET reset_winHeight STORED false)
81   - Q_PROPERTY(int numPos READ get_numPos WRITE set_numPos RESET reset_numPos STORED false)
82   - Q_PROPERTY(int numNeg READ get_numNeg WRITE set_numNeg RESET reset_numNeg STORED false)
83 74  
84 75 BR_PROPERTY(QString, model, "FrontalFace")
85 76 BR_PROPERTY(int, minSize, 64)
86 77 BR_PROPERTY(int, minNeighbors, 5)
87 78 BR_PROPERTY(bool, ROCMode, false)
88 79  
89   - BR_PROPERTY(QString, vecFile, "data.vec")
90   - BR_PROPERTY(QString, negFile, "neg.txt")
91   - BR_PROPERTY(int, winWidth, 24)
92   - BR_PROPERTY(int, winHeight, 24)
93   - BR_PROPERTY(int, numPos, 1000)
94   - BR_PROPERTY(int, numNeg, 1000)
95   -
96 80 Resource<CascadeClassifier> cascadeResource;
97 81  
98 82 void init()
... ... @@ -101,99 +85,6 @@ class CascadeTransform : public MetaTransform
101 85 if (model == "Ear" || model == "Eye" || model == "FrontalFace" || model == "ProfileFace")
102 86 this->trainable = false;
103 87 }
104   -
105   - QList<Mat> getPos()
106   - {
107   - FILE *file = fopen(vecFile.toStdString().c_str(), "rb");
108   - if ( !file )
109   - qFatal("Couldn't open the file");
110   -
111   - short* vec = 0;
112   - int count, vecSize, last, base;
113   -
114   - short tmp = 0;
115   - if( fread( &count, sizeof( count ), 1, file ) != 1 ||
116   - fread( &vecSize, sizeof( vecSize ), 1, file ) != 1 ||
117   - fread( &tmp, sizeof( tmp ), 1, file ) != 1 ||
118   - fread( &tmp, sizeof( tmp ), 1, file ) != 1 )
119   - CV_Error_( CV_StsParseError, ("wrong file format for %s\n", qPrintable(vecFile)) );
120   - base = sizeof( count ) + sizeof( vecSize ) + 2*sizeof( tmp );
121   -
122   - last = 0;
123   - vec = (short*) cvAlloc( sizeof( *vec ) * vecSize );
124   - CV_Assert( vec );
125   -
126   - QList<Mat> posImages;
127   - for (int i = 0; i < 35770; i++) {
128   - Mat pos(winHeight, winWidth, CV_8UC1);
129   -
130   - CV_Assert( pos.rows * pos.cols == vecSize );
131   - uchar tmp = 0;
132   - size_t elements_read = fread( &tmp, sizeof( tmp ), 1, file );
133   - if( elements_read != 1 )
134   - CV_Error( CV_StsBadArg, "Can not get new positive sample. The most possible reason is "
135   - "insufficient count of samples in given vec-file.\n");
136   - elements_read = fread( vec, sizeof( vec[0] ), vecSize, file );
137   - if( elements_read != (size_t)(vecSize) )
138   - CV_Error( CV_StsBadArg, "Can not get new positive sample. Seems that vec-file has incorrect structure.\n");
139   -
140   - if( feof( file ) || last++ >= count )
141   - CV_Error( CV_StsBadArg, "Can not get new positive sample. vec-file is over.\n");
142   -
143   - for( int r = 0; r < pos.rows; r++ )
144   - for( int c = 0; c < pos.cols; c++ )
145   - pos.ptr(r)[c] = (uchar)vec[r * pos.cols + c];
146   - posImages.append(pos);
147   - }
148   - return posImages;
149   - }
150   -
151   - QList<Mat> getNeg()
152   - {
153   - QList<Mat> negs;
154   -
155   - std::string dirname, str;
156   - std::ifstream file(negFile.toStdString().c_str());
157   -
158   - size_t pos = negFile.toStdString().rfind('\\');
159   - char dlmrt = '\\';
160   - if (pos == string::npos)
161   - {
162   - pos = negFile.toStdString().rfind('/');
163   - dlmrt = '/';
164   - }
165   - dirname = pos == string::npos ? "" : negFile.toStdString().substr(0, pos) + dlmrt;
166   - while( !file.eof() )
167   - {
168   - std::getline(file, str);
169   - if (str.empty()) break;
170   - if (str.at(0) == '#' ) continue;
171   - negs.append(imread(dirname + str, CV_LOAD_IMAGE_GRAYSCALE));
172   - }
173   - file.close();
174   -
175   - return negs;
176   - }
177   -
178   - // Train transform
179   - void train(const TemplateList& data)
180   - {
181   - (void)data;
182   -
183   - BrCascadeClassifier classifier;
184   -
185   - QList<Mat> posImages = getPos();
186   - QList<Mat> negImages = getNeg();
187   -
188   - CascadeBoostParams stageParams(CvBoost::GENTLE, 0.999, 0.5, 0.95, 1, 200);
189   -
190   - QString cascadeDir = Globals->sdkPath + "/share/openbr/models/openbrcascades/" + model;
191   - classifier.train(cascadeDir.toStdString(),
192   - posImages, negImages,
193   - numPos, numNeg, 1024, 1024, 12,
194   - Size(winWidth, winHeight),
195   - stageParams);
196   - }
197 88  
198 89 void project(const Template &src, Template &dst) const
199 90 {
... ...
openbr/plugins/representation/mblbp.cpp
... ... @@ -22,6 +22,11 @@ class MBLBPRepresentation : public Representation
22 22 {
23 23 Q_OBJECT
24 24  
  25 + Q_PROPERTY(int winWidth READ get_winWidth WRITE set_winWidth RESET reset_winWidth STORED false)
  26 + Q_PROPERTY(int winHeight READ get_winHeight WRITE set_winHeight RESET reset_winHeight STORED false)
  27 + BR_PROPERTY(int, winWidth, 24)
  28 + BR_PROPERTY(int, winHeight, 24)
  29 +
25 30 void init()
26 31 {
27 32 int offset = winWidth + 1;
... ... @@ -45,9 +50,11 @@ class MBLBPRepresentation : public Representation
45 50  
46 51 Mat evaluate(const Mat &image, const QList<int> &indices) const
47 52 {
48   - Mat result(1, indices.size(), CV_32FC1);
49   - for (int i = 0; i < indices.size(); i++)
50   - result.at<float>(i) = (float)features[indices[i]].calc(image);
  53 + int size = indices.empty() ? numFeatures() : indices.size();
  54 +
  55 + Mat result(1, size, CV_32FC1);
  56 + for (int i = 0; i < size; i++)
  57 + result.at<float>(i) = evaluate(image, indices.empty() ? i : indices[i]);
51 58 return result;
52 59 }
53 60  
... ...