]> rtime.felk.cvut.cz Git - opencv.git/blob - opencv/include/opencv/cvaux.hpp
renamed guard macros; moved some common inter-module stuff to the new cvinternal...
[opencv.git] / opencv / include / opencv / cvaux.hpp
1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 //  By downloading, copying, installing or using the software you agree to this license.
6 //  If you do not agree to this license, do not download, install,
7 //  copy or use the software.
8 //
9 //
10 //                        Intel License Agreement
11 //                For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
15 //
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
18 //
19 //   * Redistribution's of source code must retain the above copyright notice,
20 //     this list of conditions and the following disclaimer.
21 //
22 //   * Redistribution's in binary form must reproduce the above copyright notice,
23 //     this list of conditions and the following disclaimer in the documentation
24 //     and/or other materials provided with the distribution.
25 //
26 //   * The name of Intel Corporation may not be used to endorse or promote products
27 //     derived from this software without specific prior written permission.
28 //
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
39 //
40 //M*/
41
42 #ifndef __OPENCV_AUX_HPP__
43 #define __OPENCV_AUX_HPP__
44
45 #ifdef __cplusplus
46
47 #include <iosfwd>
48
49 class CV_EXPORTS CvImage
50 {
51 public:
52     CvImage() : image(0), refcount(0) {}
53     CvImage( CvSize size, int depth, int channels )
54     {
55         image = cvCreateImage( size, depth, channels );
56         refcount = image ? new int(1) : 0;
57     }
58
59     CvImage( IplImage* img ) : image(img)
60     {
61         refcount = image ? new int(1) : 0;
62     }
63
64     CvImage( const CvImage& img ) : image(img.image), refcount(img.refcount)
65     {
66         if( refcount ) ++(*refcount);
67     }
68
69     CvImage( const char* filename, const char* imgname=0, int color=-1 ) : image(0), refcount(0)
70     { load( filename, imgname, color ); }
71
72     CvImage( CvFileStorage* fs, const char* mapname, const char* imgname ) : image(0), refcount(0)
73     { read( fs, mapname, imgname ); }
74
75     CvImage( CvFileStorage* fs, const char* seqname, int idx ) : image(0), refcount(0)
76     { read( fs, seqname, idx ); }
77
78     ~CvImage()
79     {
80         if( refcount && !(--*refcount) )
81         {
82             cvReleaseImage( &image );
83             delete refcount;
84         }
85     }
86
87     CvImage clone() { return CvImage(image ? cvCloneImage(image) : 0); }
88
89     void create( CvSize size, int depth, int channels )
90     {
91         if( !image || !refcount ||
92             image->width != size.width || image->height != size.height ||
93             image->depth != depth || image->nChannels != channels )
94             attach( cvCreateImage( size, depth, channels ));
95     }
96
97     void release() { detach(); }
98     void clear() { detach(); }
99
100     void attach( IplImage* img, bool use_refcount=true )
101     {
102         if( refcount && --*refcount == 0 )
103         {
104             cvReleaseImage( &image );
105             delete refcount;
106         }
107         image = img;
108         refcount = use_refcount && image ? new int(1) : 0;
109     }
110
111     void detach()
112     {
113         if( refcount && --*refcount == 0 )
114         {
115             cvReleaseImage( &image );
116             delete refcount;
117         }
118         image = 0;
119         refcount = 0;
120     }
121
122     bool load( const char* filename, const char* imgname=0, int color=-1 );
123     bool read( CvFileStorage* fs, const char* mapname, const char* imgname );
124     bool read( CvFileStorage* fs, const char* seqname, int idx );
125     void save( const char* filename, const char* imgname, const int* params=0 );
126     void write( CvFileStorage* fs, const char* imgname );
127
128     void show( const char* window_name );
129     bool is_valid() { return image != 0; }
130
131     int width() const { return image ? image->width : 0; }
132     int height() const { return image ? image->height : 0; }
133
134     CvSize size() const { return image ? cvSize(image->width, image->height) : cvSize(0,0); }
135
136     CvSize roi_size() const
137     {
138         return !image ? cvSize(0,0) :
139             !image->roi ? cvSize(image->width,image->height) :
140             cvSize(image->roi->width, image->roi->height);
141     }
142
143     CvRect roi() const
144     {
145         return !image ? cvRect(0,0,0,0) :
146             !image->roi ? cvRect(0,0,image->width,image->height) :
147             cvRect(image->roi->xOffset,image->roi->yOffset,
148                    image->roi->width,image->roi->height);
149     }
150
151     int coi() const { return !image || !image->roi ? 0 : image->roi->coi; }
152
153     void set_roi(CvRect roi) { cvSetImageROI(image,roi); }
154     void reset_roi() { cvResetImageROI(image); }
155     void set_coi(int coi) { cvSetImageCOI(image,coi); }
156     int depth() const { return image ? image->depth : 0; }
157     int channels() const { return image ? image->nChannels : 0; }
158     int pix_size() const { return image ? ((image->depth & 255)>>3)*image->nChannels : 0; }
159
160     uchar* data() { return image ? (uchar*)image->imageData : 0; }
161     const uchar* data() const { return image ? (const uchar*)image->imageData : 0; }
162     int step() const { return image ? image->widthStep : 0; }
163     int origin() const { return image ? image->origin : 0; }
164
165     uchar* roi_row(int y)
166     {
167         assert(0<=y);
168         assert(!image ?
169                 1 : image->roi ?
170                 y<image->roi->height : y<image->height);
171         
172         return !image ? 0 :
173             !image->roi ?
174                 (uchar*)(image->imageData + y*image->widthStep) :
175                 (uchar*)(image->imageData + (y+image->roi->yOffset)*image->widthStep +
176                 image->roi->xOffset*((image->depth & 255)>>3)*image->nChannels);
177     }
178
179     const uchar* roi_row(int y) const
180     {
181         assert(0<=y);
182         assert(!image ?
183                 1 : image->roi ?
184                 y<image->roi->height : y<image->height); 
185
186         return !image ? 0 :
187             !image->roi ?
188                 (const uchar*)(image->imageData + y*image->widthStep) :
189                 (const uchar*)(image->imageData + (y+image->roi->yOffset)*image->widthStep +
190                 image->roi->xOffset*((image->depth & 255)>>3)*image->nChannels);
191     }
192
193     operator const IplImage* () const { return image; }
194     operator IplImage* () { return image; }
195
196     CvImage& operator = (const CvImage& img)
197     {
198         if( img.refcount )
199             ++*img.refcount;
200         if( refcount && !(--*refcount) )
201             cvReleaseImage( &image );
202         image=img.image;
203         refcount=img.refcount;
204         return *this;
205     }
206
207 protected:
208     IplImage* image;
209     int* refcount;
210 };
211
212
213 class CV_EXPORTS CvMatrix
214 {
215 public:
216     CvMatrix() : matrix(0) {}
217     CvMatrix( int rows, int cols, int type )
218     { matrix = cvCreateMat( rows, cols, type ); }
219
220     CvMatrix( int rows, int cols, int type, CvMat* hdr,
221               void* data=0, int step=CV_AUTOSTEP )
222     { matrix = cvInitMatHeader( hdr, rows, cols, type, data, step ); }
223
224     CvMatrix( int rows, int cols, int type, CvMemStorage* storage, bool alloc_data=true );
225
226     CvMatrix( int rows, int cols, int type, void* data, int step=CV_AUTOSTEP )
227     { matrix = cvCreateMatHeader( rows, cols, type );
228       cvSetData( matrix, data, step ); }
229
230     CvMatrix( CvMat* m )
231     { matrix = m; }
232
233     CvMatrix( const CvMatrix& m )
234     {
235         matrix = m.matrix;
236         addref();
237     }
238
239     CvMatrix( const char* filename, const char* matname=0, int color=-1 ) : matrix(0)
240     {  load( filename, matname, color ); }
241
242     CvMatrix( CvFileStorage* fs, const char* mapname, const char* matname ) : matrix(0)
243     {  read( fs, mapname, matname ); }
244
245     CvMatrix( CvFileStorage* fs, const char* seqname, int idx ) : matrix(0)
246     {  read( fs, seqname, idx ); }
247
248     ~CvMatrix()
249     {
250         release();
251     }
252
253     CvMatrix clone() { return CvMatrix(matrix ? cvCloneMat(matrix) : 0); }
254
255     void set( CvMat* m, bool add_ref )
256     {
257         release();
258         matrix = m;
259         if( add_ref )
260             addref();
261     }
262
263     void create( int rows, int cols, int type )
264     {
265         if( !matrix || !matrix->refcount ||
266             matrix->rows != rows || matrix->cols != cols ||
267             CV_MAT_TYPE(matrix->type) != type )
268             set( cvCreateMat( rows, cols, type ), false );
269     }
270
271     void addref() const
272     {
273         if( matrix )
274         {
275             if( matrix->hdr_refcount )
276                 ++matrix->hdr_refcount;
277             else if( matrix->refcount )
278                 ++*matrix->refcount;
279         }
280     }
281
282     void release()
283     {
284         if( matrix )
285         {
286             if( matrix->hdr_refcount )
287             {
288                 if( --matrix->hdr_refcount == 0 )
289                     cvReleaseMat( &matrix );
290             }
291             else if( matrix->refcount )
292             {
293                 if( --*matrix->refcount == 0 )
294                     cvFree( &matrix->refcount );
295             }
296             matrix = 0;
297         }
298     }
299
300     void clear()
301     {
302         release();
303     }
304
305     bool load( const char* filename, const char* matname=0, int color=-1 );
306     bool read( CvFileStorage* fs, const char* mapname, const char* matname );
307     bool read( CvFileStorage* fs, const char* seqname, int idx );
308     void save( const char* filename, const char* matname, const int* params=0 );
309     void write( CvFileStorage* fs, const char* matname );
310
311     void show( const char* window_name );
312
313     bool is_valid() { return matrix != 0; }
314
315     int rows() const { return matrix ? matrix->rows : 0; }
316     int cols() const { return matrix ? matrix->cols : 0; }
317
318     CvSize size() const
319     {
320         return !matrix ? cvSize(0,0) : cvSize(matrix->rows,matrix->cols);
321     }
322
323     int type() const { return matrix ? CV_MAT_TYPE(matrix->type) : 0; }
324     int depth() const { return matrix ? CV_MAT_DEPTH(matrix->type) : 0; }
325     int channels() const { return matrix ? CV_MAT_CN(matrix->type) : 0; }
326     int pix_size() const { return matrix ? CV_ELEM_SIZE(matrix->type) : 0; }
327
328     uchar* data() { return matrix ? matrix->data.ptr : 0; }
329     const uchar* data() const { return matrix ? matrix->data.ptr : 0; }
330     int step() const { return matrix ? matrix->step : 0; }
331
332     void set_data( void* data, int step=CV_AUTOSTEP )
333     { cvSetData( matrix, data, step ); }
334
335     uchar* row(int i) { return !matrix ? 0 : matrix->data.ptr + i*matrix->step; }
336     const uchar* row(int i) const
337     { return !matrix ? 0 : matrix->data.ptr + i*matrix->step; }
338
339     operator const CvMat* () const { return matrix; }
340     operator CvMat* () { return matrix; }
341
342     CvMatrix& operator = (const CvMatrix& _m)
343     {
344         _m.addref();
345         release();
346         matrix = _m.matrix;
347         return *this;
348     }
349
350 protected:
351     CvMat* matrix;
352 };
353
354 /****************************************************************************************\
355 *                                       CamShiftTracker                                  *
356 \****************************************************************************************/
357
358 class CV_EXPORTS CvCamShiftTracker
359 {
360 public:
361
362     CvCamShiftTracker();
363     virtual ~CvCamShiftTracker();
364
365     /**** Characteristics of the object that are calculated by track_object method *****/
366     float   get_orientation() const // orientation of the object in degrees
367     { return m_box.angle; }
368     float   get_length() const // the larger linear size of the object
369     { return m_box.size.height; }
370     float   get_width() const // the smaller linear size of the object
371     { return m_box.size.width; }
372     CvPoint2D32f get_center() const // center of the object
373     { return m_box.center; }
374     CvRect get_window() const // bounding rectangle for the object
375     { return m_comp.rect; }
376
377     /*********************** Tracking parameters ************************/
378     int     get_threshold() const // thresholding value that applied to back project
379     { return m_threshold; }
380
381     int     get_hist_dims( int* dims = 0 ) const // returns number of histogram dimensions and sets
382     { return m_hist ? cvGetDims( m_hist->bins, dims ) : 0; }
383
384     int     get_min_ch_val( int channel ) const // get the minimum allowed value of the specified channel
385     { return m_min_ch_val[channel]; }
386
387     int     get_max_ch_val( int channel ) const // get the maximum allowed value of the specified channel
388     { return m_max_ch_val[channel]; }
389
390     // set initial object rectangle (must be called before initial calculation of the histogram)
391     bool    set_window( CvRect window)
392     { m_comp.rect = window; return true; }
393
394     bool    set_threshold( int threshold ) // threshold applied to the histogram bins
395     { m_threshold = threshold; return true; }
396
397     bool    set_hist_bin_range( int dim, int min_val, int max_val );
398
399     bool    set_hist_dims( int c_dims, int* dims );// set the histogram parameters
400
401     bool    set_min_ch_val( int channel, int val ) // set the minimum allowed value of the specified channel
402     { m_min_ch_val[channel] = val; return true; }
403     bool    set_max_ch_val( int channel, int val ) // set the maximum allowed value of the specified channel
404     { m_max_ch_val[channel] = val; return true; }
405
406     /************************ The processing methods *********************************/
407     // update object position
408     virtual bool  track_object( const IplImage* cur_frame );
409
410     // update object histogram
411     virtual bool  update_histogram( const IplImage* cur_frame );
412
413     // reset histogram
414     virtual void  reset_histogram();
415
416     /************************ Retrieving internal data *******************************/
417     // get back project image
418     virtual IplImage* get_back_project()
419     { return m_back_project; }
420
421     float query( int* bin ) const
422     { return m_hist ? (float)cvGetRealND(m_hist->bins, bin) : 0.f; }
423
424 protected:
425
426     // internal method for color conversion: fills m_color_planes group
427     virtual void color_transform( const IplImage* img );
428
429     CvHistogram* m_hist;
430
431     CvBox2D    m_box;
432     CvConnectedComp m_comp;
433
434     float      m_hist_ranges_data[CV_MAX_DIM][2];
435     float*     m_hist_ranges[CV_MAX_DIM];
436
437     int        m_min_ch_val[CV_MAX_DIM];
438     int        m_max_ch_val[CV_MAX_DIM];
439     int        m_threshold;
440
441     IplImage*  m_color_planes[CV_MAX_DIM];
442     IplImage*  m_back_project;
443     IplImage*  m_temp;
444     IplImage*  m_mask;
445 };
446
447 /****************************************************************************************\
448 *                                   Adaptive Skin Detector                               *
449 \****************************************************************************************/
450
451 class CV_EXPORTS CvAdaptiveSkinDetector
452 {
453 private:
454         enum {
455                 GSD_HUE_LT = 3,
456                 GSD_HUE_UT = 33,
457                 GSD_INTENSITY_LT = 15,
458                 GSD_INTENSITY_UT = 250
459         };
460
461         class CV_EXPORTS Histogram
462         {
463         private:
464                 enum {
465                         HistogramSize = (GSD_HUE_UT - GSD_HUE_LT + 1)
466                 };
467
468         protected:
469                 int findCoverageIndex(double surfaceToCover, int defaultValue = 0);
470
471         public:
472                 CvHistogram *fHistogram;
473                 Histogram();
474                 virtual ~Histogram();
475
476                 void findCurveThresholds(int &x1, int &x2, double percent = 0.05);
477                 void mergeWith(Histogram *source, double weight);
478         };
479
480         int nStartCounter, nFrameCount, nSkinHueLowerBound, nSkinHueUpperBound, nMorphingMethod, nSamplingDivider;
481         double fHistogramMergeFactor, fHuePercentCovered;
482         Histogram histogramHueMotion, skinHueHistogram;
483         IplImage *imgHueFrame, *imgSaturationFrame, *imgLastGrayFrame, *imgMotionFrame, *imgFilteredFrame;
484         IplImage *imgShrinked, *imgTemp, *imgGrayFrame, *imgHSVFrame;
485
486 protected:
487         void initData(IplImage *src, int widthDivider, int heightDivider);
488         void adaptiveFilter();
489
490 public:
491
492         enum {
493                 MORPHING_METHOD_NONE = 0,
494                 MORPHING_METHOD_ERODE = 1,
495                 MORPHING_METHOD_ERODE_ERODE     = 2,
496                 MORPHING_METHOD_ERODE_DILATE = 3
497         };
498
499         CvAdaptiveSkinDetector(int samplingDivider = 1, int morphingMethod = MORPHING_METHOD_NONE);
500         virtual ~CvAdaptiveSkinDetector();
501
502         virtual void process(IplImage *inputBGRImage, IplImage *outputHueMask);
503 };
504
505
506 /****************************************************************************************\
507 *                                  Fuzzy MeanShift Tracker                               *
508 \****************************************************************************************/
509
510 class CV_EXPORTS CvFuzzyPoint {
511 public:
512         double x, y, value;
513
514         CvFuzzyPoint(double _x, double _y);
515 };
516
517 class CV_EXPORTS CvFuzzyCurve {
518 private:
519     std::vector<CvFuzzyPoint> points;
520         double value, centre;
521
522         bool between(double x, double x1, double x2);
523
524 public:
525         CvFuzzyCurve();
526         ~CvFuzzyCurve();
527
528         void setCentre(double _centre);
529         double getCentre();
530         void clear();
531         void addPoint(double x, double y);
532         double calcValue(double param);
533         double getValue();
534         void setValue(double _value);
535 };
536
537 class CV_EXPORTS CvFuzzyFunction {
538 public:
539     std::vector<CvFuzzyCurve> curves;
540
541         CvFuzzyFunction();
542         ~CvFuzzyFunction();
543         void addCurve(CvFuzzyCurve *curve, double value = 0);
544         void resetValues();
545         double calcValue();
546         CvFuzzyCurve *newCurve();
547 };
548
549 class CV_EXPORTS CvFuzzyRule {
550 private:
551         CvFuzzyCurve *fuzzyInput1, *fuzzyInput2;
552         CvFuzzyCurve *fuzzyOutput;
553 public:
554         CvFuzzyRule();
555         ~CvFuzzyRule();
556         void setRule(CvFuzzyCurve *c1, CvFuzzyCurve *c2, CvFuzzyCurve *o1);
557         double calcValue(double param1, double param2);
558         CvFuzzyCurve *getOutputCurve();
559 };
560
561 class CV_EXPORTS CvFuzzyController {
562 private:
563     std::vector<CvFuzzyRule*> rules;
564 public:
565         CvFuzzyController();
566         ~CvFuzzyController();
567         void addRule(CvFuzzyCurve *c1, CvFuzzyCurve *c2, CvFuzzyCurve *o1);
568         double calcOutput(double param1, double param2);
569 };
570
571 class CV_EXPORTS CvFuzzyMeanShiftTracker
572 {
573 private:
574         class FuzzyResizer
575         {
576         private:
577                 CvFuzzyFunction iInput, iOutput;
578                 CvFuzzyController fuzzyController;
579         public:
580                 FuzzyResizer();
581                 int calcOutput(double edgeDensity, double density);
582         };
583
584         class SearchWindow
585         {
586         public:
587                 FuzzyResizer *fuzzyResizer;
588                 int x, y;
589                 int width, height, maxWidth, maxHeight, ellipseHeight, ellipseWidth;
590                 int ldx, ldy, ldw, ldh, numShifts, numIters;
591                 int xGc, yGc;
592                 long m00, m01, m10, m11, m02, m20;
593                 double ellipseAngle;
594                 double density;
595                 unsigned int depthLow, depthHigh;
596                 int verticalEdgeLeft, verticalEdgeRight, horizontalEdgeTop, horizontalEdgeBottom;
597
598                 SearchWindow();
599                 ~SearchWindow();
600                 void setSize(int _x, int _y, int _width, int _height);
601                 void initDepthValues(IplImage *maskImage, IplImage *depthMap);
602                 bool shift();
603                 void extractInfo(IplImage *maskImage, IplImage *depthMap, bool initDepth);
604                 void getResizeAttribsEdgeDensityLinear(int &resizeDx, int &resizeDy, int &resizeDw, int &resizeDh);
605                 void getResizeAttribsInnerDensity(int &resizeDx, int &resizeDy, int &resizeDw, int &resizeDh);
606                 void getResizeAttribsEdgeDensityFuzzy(int &resizeDx, int &resizeDy, int &resizeDw, int &resizeDh);
607                 bool meanShift(IplImage *maskImage, IplImage *depthMap, int maxIteration, bool initDepth);
608         };
609
610 public:
611         enum TrackingState
612         {
613                 tsNone                  = 0,
614                 tsSearching     = 1,
615                 tsTracking              = 2,
616                 tsSetWindow     = 3,
617                 tsDisabled              = 10
618         };
619
620         enum ResizeMethod {
621                 rmEdgeDensityLinear             = 0,
622                 rmEdgeDensityFuzzy              = 1,
623                 rmInnerDensity                  = 2
624         };
625
626         enum {
627                 MinKernelMass                   = 1000
628         };
629
630         SearchWindow kernel;
631         int searchMode;
632
633 private:
634         enum
635         {
636                 MaxMeanShiftIteration   = 5,
637                 MaxSetSizeIteration     = 5
638         };
639
640         void findOptimumSearchWindow(SearchWindow &searchWindow, IplImage *maskImage, IplImage *depthMap, int maxIteration, int resizeMethod, bool initDepth);
641
642 public:
643         CvFuzzyMeanShiftTracker();
644         ~CvFuzzyMeanShiftTracker();
645
646         void track(IplImage *maskImage, IplImage *depthMap, int resizeMethod, bool resetSearch, int minKernelMass = MinKernelMass);
647 };
648
649
650 namespace cv
651 {
652
653 class CV_EXPORTS Octree
654 {
655 public:    
656     struct Node
657     {
658         Node() {}
659         int begin, end;
660         float x_min, x_max, y_min, y_max, z_min, z_max;         
661         int maxLevels;
662         bool isLeaf;
663         int children[8];
664     };
665
666     Octree();
667     Octree( const vector<Point3f>& points, int maxLevels = 10, int minPoints = 20 );
668     virtual ~Octree();
669
670     virtual void buildTree( const vector<Point3f>& points, int maxLevels = 10, int minPoints = 20 );
671     virtual void getPointsWithinSphere( const Point3f& center, float radius,
672                                         vector<Point3f>& points ) const;
673     const vector<Node>& getNodes() const { return nodes; }
674 private:
675     int minPoints;
676     vector<Point3f> points;
677     vector<Node> nodes;
678         
679         virtual void buildNext(size_t node_ind);
680 };
681
682
683 class CV_EXPORTS Mesh3D
684 {
685 public:
686     struct EmptyMeshException {};
687
688     Mesh3D();
689     Mesh3D(const vector<Point3f>& vtx);
690     ~Mesh3D();
691
692     void buildOctree();
693     void clearOctree();
694     float estimateResolution(float tryRatio = 0.1f);        
695     void computeNormals(float normalRadius, int minNeighbors = 20);
696     void computeNormals(const vector<int>& subset, float normalRadius, int minNeighbors = 20);
697     
698     void writeAsVrml(const String& file, const vector<Scalar>& colors = vector<Scalar>()) const;
699     
700     vector<Point3f> vtx;
701     vector<Point3f> normals;
702     float resolution;    
703     Octree octree;
704
705     const static Point3f allzero;
706 };
707
708 class CV_EXPORTS SpinImageModel
709 {
710 public:
711     
712     /* model parameters, leave unset for default or auto estimate */
713     float normalRadius;
714     int minNeighbors;
715
716     float binSize;
717     int imageWidth;
718
719     float lambda;                        
720     float gamma;
721
722     float T_GeometriccConsistency;
723     float T_GroupingCorespondances;
724
725     /* public interface */
726     SpinImageModel();
727     explicit SpinImageModel(const Mesh3D& mesh);
728     ~SpinImageModel();
729
730     void setLogger(std::ostream* log);
731     void selectRandomSubset(float ratio);         
732     void setSubset(const vector<int>& subset);         
733     void compute();
734
735     void match(const SpinImageModel& scene, vector< vector<Vec2i> >& result);    
736
737     Mat packRandomScaledSpins(bool separateScale = false, size_t xCount = 10, size_t yCount = 10) const;
738     
739     size_t getSpinCount() const { return spinImages.rows; }
740     Mat getSpinImage(size_t index) const { return spinImages.row(index); }
741     const Point3f& getSpinVertex(size_t index) const { return mesh.vtx[subset[index]]; }
742     const Point3f& getSpinNormal(size_t index) const { return mesh.normals[subset[index]]; }
743
744     const Mesh3D& getMesh() const { return mesh; }
745     Mesh3D& getMesh() { return mesh; }
746
747     /* static utility functions */
748     static bool spinCorrelation(const Mat& spin1, const Mat& spin2, float lambda, float& result);
749
750     static Point2f calcSpinMapCoo(const Point3f& point, const Point3f& vertex, const Point3f& normal);
751
752     static float geometricConsistency(const Point3f& pointScene1, const Point3f& normalScene1,
753                                       const Point3f& pointModel1, const Point3f& normalModel1,   
754                                       const Point3f& pointScene2, const Point3f& normalScene2,                               
755                                       const Point3f& pointModel2, const Point3f& normalModel2);
756
757     static float groupingCreteria(const Point3f& pointScene1, const Point3f& normalScene1,
758                                   const Point3f& pointModel1, const Point3f& normalModel1,
759                                   const Point3f& pointScene2, const Point3f& normalScene2,                               
760                                   const Point3f& pointModel2, const Point3f& normalModel2, 
761                                   float gamma);
762 protected:       
763     void defaultParams();
764
765     void matchSpinToModel(const Mat& spin, vector<int>& indeces, 
766         vector<float>& corrCoeffs, bool useExtremeOutliers = true) const; 
767
768     void repackSpinImages(const vector<uchar>& mask, Mat& spinImages, bool reAlloc = true) const;
769              
770     vector<int> subset;
771     Mesh3D mesh;
772     Mat spinImages;
773     std::ostream* out;
774 };
775
776 class CV_EXPORTS TickMeter
777 {
778 public:
779     TickMeter();
780     void start();    
781     void stop();
782
783     int64 getTimeTicks() const;
784     double getTimeMicro() const;
785     double getTimeMilli() const;
786     double getTimeSec()   const;
787     int64 getCounter() const;
788
789     void reset();
790 private:
791     int64 counter;
792     int64 sumTime;
793     int64 startTime;
794 };
795
796 CV_EXPORTS std::ostream& operator<<(std::ostream& out, const TickMeter& tm);
797
798 /****************************************************************************************\
799 *            HOG (Histogram-of-Oriented-Gradients) Descriptor and Object Detector        *
800 \****************************************************************************************/
801
802 struct CV_EXPORTS HOGDescriptor
803 {
804 public:
805     enum { L2Hys=0 };
806
807     HOGDescriptor() : winSize(64,128), blockSize(16,16), blockStride(8,8),
808         cellSize(8,8), nbins(9), derivAperture(1), winSigma(-1),
809         histogramNormType(L2Hys), L2HysThreshold(0.2), gammaCorrection(true)
810     {}
811
812     HOGDescriptor(Size _winSize, Size _blockSize, Size _blockStride,
813         Size _cellSize, int _nbins, int _derivAperture=1, double _winSigma=-1,
814         int _histogramNormType=L2Hys, double _L2HysThreshold=0.2, bool _gammaCorrection=false)
815         : winSize(_winSize), blockSize(_blockSize), blockStride(_blockStride), cellSize(_cellSize),
816         nbins(_nbins), derivAperture(_derivAperture), winSigma(_winSigma),
817         histogramNormType(_histogramNormType), L2HysThreshold(_L2HysThreshold),
818         gammaCorrection(_gammaCorrection)
819     {}
820
821     HOGDescriptor(const String& filename)
822     {
823         load(filename);
824     }
825
826     virtual ~HOGDescriptor() {}
827
828     size_t getDescriptorSize() const;
829     bool checkDetectorSize() const;
830     double getWinSigma() const;
831
832     virtual void setSVMDetector(const vector<float>& _svmdetector);
833
834     virtual bool load(const String& filename, const String& objname=String());
835     virtual void save(const String& filename, const String& objname=String()) const;
836
837     virtual void compute(const Mat& img,
838                          vector<float>& descriptors,
839                          Size winStride=Size(), Size padding=Size(),
840                          const vector<Point>& locations=vector<Point>()) const;
841     virtual void detect(const Mat& img, vector<Point>& foundLocations,
842                         double hitThreshold=0, Size winStride=Size(),
843                         Size padding=Size(),
844                         const vector<Point>& searchLocations=vector<Point>()) const;
845     virtual void detectMultiScale(const Mat& img, vector<Rect>& foundLocations,
846                                   double hitThreshold=0, Size winStride=Size(),
847                                   Size padding=Size(), double scale=1.05,
848                                   int groupThreshold=2) const;
849     virtual void computeGradient(const Mat& img, Mat& grad, Mat& angleOfs,
850                                  Size paddingTL=Size(), Size paddingBR=Size()) const;
851
852     static vector<float> getDefaultPeopleDetector();
853
854     Size winSize;
855     Size blockSize;
856     Size blockStride;
857     Size cellSize;
858     int nbins;
859     int derivAperture;
860     double winSigma;
861     int histogramNormType;
862     double L2HysThreshold;
863     bool gammaCorrection;
864     vector<float> svmDetector;
865 };
866
867
868 class CV_EXPORTS SelfSimDescriptor
869 {
870 public:
871     SelfSimDescriptor();
872     SelfSimDescriptor(int _ssize, int _lsize,
873         int _startDistanceBucket=DEFAULT_START_DISTANCE_BUCKET,
874         int _numberOfDistanceBuckets=DEFAULT_NUM_DISTANCE_BUCKETS,
875         int _nangles=DEFAULT_NUM_ANGLES);
876         SelfSimDescriptor(const SelfSimDescriptor& ss);
877         virtual ~SelfSimDescriptor();
878     SelfSimDescriptor& operator = (const SelfSimDescriptor& ss);
879
880     size_t getDescriptorSize() const;
881     Size getGridSize( Size imgsize, Size winStride ) const;
882
883     virtual void compute(const Mat& img, vector<float>& descriptors, Size winStride=Size(),
884                          const vector<Point>& locations=vector<Point>()) const;
885     virtual void computeLogPolarMapping(Mat& mappingMask) const;
886     virtual void SSD(const Mat& img, Point pt, Mat& ssd) const;
887
888         int smallSize;
889         int largeSize;
890     int startDistanceBucket;
891     int numberOfDistanceBuckets;
892     int numberOfAngles;
893
894     enum { DEFAULT_SMALL_SIZE = 5, DEFAULT_LARGE_SIZE = 41,
895         DEFAULT_NUM_ANGLES = 20, DEFAULT_START_DISTANCE_BUCKET = 3,
896         DEFAULT_NUM_DISTANCE_BUCKETS = 7 };
897 };
898
899     
900 class CV_EXPORTS PatchGenerator
901 {
902 public:
903     PatchGenerator();
904     PatchGenerator(double _backgroundMin, double _backgroundMax,
905                    double _noiseRange, bool _randomBlur=true,
906                    double _lambdaMin=0.6, double _lambdaMax=1.5,
907                    double _thetaMin=-CV_PI, double _thetaMax=CV_PI,
908                    double _phiMin=-CV_PI, double _phiMax=CV_PI );
909     void operator()(const Mat& image, Point2f pt, Mat& patch, Size patchSize, RNG& rng) const;
910     void operator()(const Mat& image, const Mat& transform, Mat& patch,
911                     Size patchSize, RNG& rng) const;
912     void warpWholeImage(const Mat& image, Mat& _T, Mat& buf,
913                         Mat& warped, int border, RNG& rng) const;
914     void generateRandomTransform(Point2f srcCenter, Point2f dstCenter,
915                                  Mat& transform, RNG& rng, bool inverse=false) const;
916     double backgroundMin, backgroundMax;
917     double noiseRange;
918     bool randomBlur;
919     double lambdaMin, lambdaMax;
920     double thetaMin, thetaMax;
921     double phiMin, phiMax;
922 };
923
924     
925 class CV_EXPORTS LDetector
926 {
927 public:    
928     LDetector();
929     LDetector(int _radius, int _threshold, int _nOctaves,
930               int _nViews, double _baseFeatureSize, double _clusteringDistance);
931     void operator()(const Mat& image, vector<KeyPoint>& keypoints, int maxCount=0, bool scaleCoords=true) const;
932     void operator()(const vector<Mat>& pyr, vector<KeyPoint>& keypoints, int maxCount=0, bool scaleCoords=true) const;
933     void getMostStable2D(const Mat& image, vector<KeyPoint>& keypoints,
934                          int maxCount, const PatchGenerator& patchGenerator) const;
935     void setVerbose(bool verbose);
936     
937     void read(const FileNode& node);
938     void write(FileStorage& fs, const String& name=String()) const;
939     
940     int radius;
941     int threshold;
942     int nOctaves;
943     int nViews;
944     bool verbose;
945     
946     double baseFeatureSize;
947     double clusteringDistance;
948 };
949
950 typedef LDetector YAPE;
951
952 class CV_EXPORTS FernClassifier
953 {
954 public:
955     FernClassifier();
956     FernClassifier(const FileNode& node);
957     FernClassifier(const vector<Point2f>& points,
958                    const vector<Ptr<Mat> >& refimgs,
959                    const vector<int>& labels=vector<int>(),
960                    int _nclasses=0, int _patchSize=PATCH_SIZE,
961                    int _signatureSize=DEFAULT_SIGNATURE_SIZE,
962                    int _nstructs=DEFAULT_STRUCTS,
963                    int _structSize=DEFAULT_STRUCT_SIZE,
964                    int _nviews=DEFAULT_VIEWS,
965                    int _compressionMethod=COMPRESSION_NONE,
966                    const PatchGenerator& patchGenerator=PatchGenerator());
967     virtual ~FernClassifier();
968     virtual void read(const FileNode& n);
969     virtual void write(FileStorage& fs, const String& name=String()) const;
970     virtual void trainFromSingleView(const Mat& image,
971                                      const vector<KeyPoint>& keypoints,
972                                      int _patchSize=PATCH_SIZE,
973                                      int _signatureSize=DEFAULT_SIGNATURE_SIZE,
974                                      int _nstructs=DEFAULT_STRUCTS,
975                                      int _structSize=DEFAULT_STRUCT_SIZE,
976                                      int _nviews=DEFAULT_VIEWS,
977                                      int _compressionMethod=COMPRESSION_NONE,
978                                      const PatchGenerator& patchGenerator=PatchGenerator());
979     virtual void train(const vector<Point2f>& points,
980                        const vector<Ptr<Mat> >& refimgs,
981                        const vector<int>& labels=vector<int>(),
982                        int _nclasses=0, int _patchSize=PATCH_SIZE,
983                        int _signatureSize=DEFAULT_SIGNATURE_SIZE,
984                        int _nstructs=DEFAULT_STRUCTS,
985                        int _structSize=DEFAULT_STRUCT_SIZE,
986                        int _nviews=DEFAULT_VIEWS,
987                        int _compressionMethod=COMPRESSION_NONE,
988                        const PatchGenerator& patchGenerator=PatchGenerator());
989     virtual int operator()(const Mat& img, Point2f kpt, vector<float>& signature) const;
990     virtual int operator()(const Mat& patch, vector<float>& signature) const;
991     virtual void clear();
992     void setVerbose(bool verbose);
993     
994     int getClassCount() const;
995     int getStructCount() const;
996     int getStructSize() const;
997     int getSignatureSize() const;
998     int getCompressionMethod() const;
999     Size getPatchSize() const;    
1000     
1001     struct Feature
1002     {
1003         uchar x1, y1, x2, y2;
1004         Feature() : x1(0), y1(0), x2(0), y2(0) {}
1005         Feature(int _x1, int _y1, int _x2, int _y2)
1006         : x1((uchar)_x1), y1((uchar)_y1), x2((uchar)_x2), y2((uchar)_y2)
1007         {}
1008         template<typename _Tp> bool operator ()(const Mat_<_Tp>& patch) const
1009         { return patch(y1,x1) > patch(y2, x2); }
1010     };
1011     
1012     enum
1013     {
1014         PATCH_SIZE = 31,
1015         DEFAULT_STRUCTS = 50,
1016         DEFAULT_STRUCT_SIZE = 9,
1017         DEFAULT_VIEWS = 5000,
1018         DEFAULT_SIGNATURE_SIZE = 176,
1019         COMPRESSION_NONE = 0,
1020         COMPRESSION_RANDOM_PROJ = 1,
1021         COMPRESSION_PCA = 2,
1022         DEFAULT_COMPRESSION_METHOD = COMPRESSION_NONE
1023     };
1024     
1025 protected:
1026     virtual void prepare(int _nclasses, int _patchSize, int _signatureSize,
1027                          int _nstructs, int _structSize,
1028                          int _nviews, int _compressionMethod);
1029     virtual void finalize(RNG& rng);
1030     virtual int getLeaf(int fidx, const Mat& patch) const;
1031     
1032     bool verbose;
1033     int nstructs;
1034     int structSize;
1035     int nclasses;
1036     int signatureSize;
1037     int compressionMethod;
1038     int leavesPerStruct;
1039     Size patchSize;
1040     vector<Feature> features;
1041     vector<int> classCounters;
1042     vector<float> posteriors;
1043 };
1044
1045 class CV_EXPORTS PlanarObjectDetector
1046 {
1047 public:
1048     PlanarObjectDetector();
1049     PlanarObjectDetector(const FileNode& node);
1050     PlanarObjectDetector(const vector<Mat>& pyr, int _npoints=300,
1051                          int _patchSize=FernClassifier::PATCH_SIZE,
1052                          int _nstructs=FernClassifier::DEFAULT_STRUCTS,
1053                          int _structSize=FernClassifier::DEFAULT_STRUCT_SIZE,
1054                          int _nviews=FernClassifier::DEFAULT_VIEWS,
1055                          const LDetector& detector=LDetector(),
1056                          const PatchGenerator& patchGenerator=PatchGenerator()); 
1057     virtual ~PlanarObjectDetector();
1058     virtual void train(const vector<Mat>& pyr, int _npoints=300,
1059                        int _patchSize=FernClassifier::PATCH_SIZE,
1060                        int _nstructs=FernClassifier::DEFAULT_STRUCTS,
1061                        int _structSize=FernClassifier::DEFAULT_STRUCT_SIZE,
1062                        int _nviews=FernClassifier::DEFAULT_VIEWS,
1063                        const LDetector& detector=LDetector(),
1064                        const PatchGenerator& patchGenerator=PatchGenerator());
1065     virtual void train(const vector<Mat>& pyr, const vector<KeyPoint>& keypoints,
1066                        int _patchSize=FernClassifier::PATCH_SIZE,
1067                        int _nstructs=FernClassifier::DEFAULT_STRUCTS,
1068                        int _structSize=FernClassifier::DEFAULT_STRUCT_SIZE,
1069                        int _nviews=FernClassifier::DEFAULT_VIEWS,
1070                        const LDetector& detector=LDetector(),
1071                        const PatchGenerator& patchGenerator=PatchGenerator());
1072     Rect getModelROI() const;
1073     vector<KeyPoint> getModelPoints() const;
1074     const LDetector& getDetector() const;
1075     const FernClassifier& getClassifier() const;
1076     void setVerbose(bool verbose);
1077     
1078     void read(const FileNode& node);
1079     void write(FileStorage& fs, const String& name=String()) const;
1080     bool operator()(const Mat& image, Mat& H, vector<Point2f>& corners) const;
1081     bool operator()(const vector<Mat>& pyr, const vector<KeyPoint>& keypoints,
1082                     Mat& H, vector<Point2f>& corners, vector<int>* pairs=0) const;
1083     
1084 protected:
1085     bool verbose;
1086     Rect modelROI;
1087     vector<KeyPoint> modelPoints;
1088     LDetector ldetector;
1089     FernClassifier fernClassifier;
1090 };
1091
1092
1093
1094
1095 // detect corners using FAST algorithm
1096 CV_EXPORTS void FAST( const Mat& image, vector<KeyPoint>& keypoints, int threshold, bool nonmax_supression=true );
1097
1098
1099 class CV_EXPORTS LevMarqSparse
1100 {
1101 public:
1102     LevMarqSparse();
1103     LevMarqSparse(int npoints, // number of points
1104             int ncameras, // number of cameras
1105             int nPointParams, // number of params per one point  (3 in case of 3D points)
1106             int nCameraParams, // number of parameters per one camera
1107             int nErrParams, // number of parameters in measurement vector
1108                             // for 1 point at one camera (2 in case of 2D projections)
1109             Mat& visibility, // visibility matrix. rows correspond to points, columns correspond to cameras
1110                              // 1 - point is visible for the camera, 0 - invisible
1111             Mat& P0, // starting vector of parameters, first cameras then points
1112             Mat& X, // measurements, in order of visibility. non visible cases are skipped 
1113             TermCriteria criteria, // termination criteria
1114             
1115             // callback for estimation of Jacobian matrices
1116             void (CV_CDECL * fjac)(int i, int j, Mat& point_params,
1117                                    Mat& cam_params, Mat& A, Mat& B, void* data),
1118             // callback for estimation of backprojection errors
1119             void (CV_CDECL * func)(int i, int j, Mat& point_params,
1120                                    Mat& cam_params, Mat& estim, void* data),
1121             void* data // user-specific data passed to the callbacks
1122             );
1123     virtual ~LevMarqSparse();
1124     
1125     virtual void run( int npoints, // number of points
1126             int ncameras, // number of cameras
1127             int nPointParams, // number of params per one point  (3 in case of 3D points)
1128             int nCameraParams, // number of parameters per one camera
1129             int nErrParams, // number of parameters in measurement vector
1130                             // for 1 point at one camera (2 in case of 2D projections)
1131             Mat& visibility, // visibility matrix. rows correspond to points, columns correspond to cameras
1132                              // 1 - point is visible for the camera, 0 - invisible
1133             Mat& P0, // starting vector of parameters, first cameras then points
1134             Mat& X, // measurements, in order of visibility. non visible cases are skipped 
1135             TermCriteria criteria, // termination criteria
1136             
1137             // callback for estimation of Jacobian matrices
1138             void (CV_CDECL * fjac)(int i, int j, Mat& point_params,
1139                                    Mat& cam_params, Mat& A, Mat& B, void* data),
1140             // callback for estimation of backprojection errors
1141             void (CV_CDECL * func)(int i, int j, Mat& point_params,
1142                                    Mat& cam_params, Mat& estim, void* data),
1143             void* data // user-specific data passed to the callbacks
1144             );
1145
1146     virtual void clear();
1147     
1148     // useful function to do simple bundle adjastment tasks
1149     static void bundleAdjust(vector<Point3d>& points, //positions of points in global coordinate system (input and output)
1150                              const vector<vector<Point2d> >& imagePoints, //projections of 3d points for every camera 
1151                              const vector<vector<int> >& visibility, //visibility of 3d points for every camera 
1152                              vector<Mat>& cameraMatrix, //intrinsic matrices of all cameras (input and output)
1153                              vector<Mat>& R, //rotation matrices of all cameras (input and output)
1154                              vector<Mat>& T, //translation vector of all cameras (input and output)
1155                              vector<Mat>& distCoeffs, //distortion coefficients of all cameras (input and output)
1156                              const TermCriteria& criteria=
1157                              TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, DBL_EPSILON));
1158     
1159 protected:
1160     virtual void optimize(); //main function that runs minimization
1161     
1162     //iteratively asks for measurement for visible camera-point pairs
1163     void ask_for_proj();                                        
1164     //iteratively asks for Jacobians for every camera_point pair
1165     void ask_for_projac();    
1166         
1167     CvMat* err; //error X-hX
1168     double prevErrNorm, errNorm;
1169     double lambda;
1170     CvTermCriteria criteria;
1171     int iters;
1172     
1173     CvMat** U; //size of array is equal to number of cameras
1174     CvMat** V; //size of array is equal to number of points
1175     CvMat** inv_V_star; //inverse of V*
1176
1177     CvMat* A;
1178     CvMat* B;
1179     CvMat* W; 
1180
1181     CvMat* X; //measurement 
1182     CvMat* hX; //current measurement extimation given new parameter vector 
1183     
1184     CvMat* prevP; //current already accepted parameter. 
1185     CvMat* P; // parameters used to evaluate function with new params
1186               // this parameters may be rejected 
1187     
1188     CvMat* deltaP; //computed increase of parameters (result of normal system solution )
1189
1190     CvMat** ea; // sum_i  AijT * e_ij , used as right part of normal equation
1191                 // length of array is j = number of cameras  
1192     CvMat** eb; // sum_j  BijT * e_ij , used as right part of normal equation
1193                 // length of array is i = number of points
1194
1195     CvMat** Yj; //length of array is i = num_points
1196
1197     CvMat* S; //big matrix of block Sjk  , each block has size num_cam_params x num_cam_params 
1198
1199     CvMat* JtJ_diag; //diagonal of JtJ,  used to backup diagonal elements before augmentation
1200
1201     CvMat* Vis_index; // matrix which element is index of measurement for point i and camera j
1202                
1203     int num_cams;
1204     int num_points;
1205     int num_err_param;
1206     int num_cam_param;
1207     int num_point_param;
1208
1209     //target function and jacobian pointers, which needs to be initialized 
1210     void (*fjac)(int i, int j, Mat& point_params, Mat& cam_params, Mat& A, Mat& B, void* data);
1211     void (*func)(int i, int j, Mat& point_params, Mat& cam_params, Mat& estim, void* data );
1212
1213     void* data;
1214 };
1215
1216 struct DefaultRngAuto
1217 {
1218     const static uint64 def_state = (uint64)-1;
1219     const uint64 old_state;
1220
1221     DefaultRngAuto() : old_state(theRNG().state) { theRNG().state = def_state; }
1222     ~DefaultRngAuto() { theRNG().state = old_state; }   
1223
1224     DefaultRngAuto& operator=(const DefaultRngAuto&);
1225 };
1226
1227         /****************************************************************************************\
1228         *            Calonder Descriptor                                                                                                                 *
1229         \****************************************************************************************/
1230         /*!
1231         A pseudo-random number generator usable with std::random_shuffle.
1232         */
1233         typedef cv::RNG CalonderRng;
1234         typedef unsigned int int_type;
1235
1236         //----------------------------
1237         //randomized_tree.h
1238
1239         //class RTTester;
1240
1241         //namespace features {
1242         static const size_t DEFAULT_REDUCED_NUM_DIM = 176;  
1243         static const float LOWER_QUANT_PERC = .03f;
1244         static const float UPPER_QUANT_PERC = .92f;
1245         static const int PATCH_SIZE = 32;
1246         static const int DEFAULT_DEPTH = 9;
1247         static const int DEFAULT_VIEWS = 5000;
1248         struct RTreeNode;
1249
1250         struct BaseKeypoint
1251         {
1252                 int x;
1253                 int y;
1254                 IplImage* image;
1255
1256                 BaseKeypoint()
1257                         : x(0), y(0), image(NULL)
1258                 {}
1259
1260                 BaseKeypoint(int x, int y, IplImage* image)
1261                         : x(x), y(y), image(image)
1262                 {}
1263         };
1264
1265         class CSMatrixGenerator {
1266         public:
1267                 typedef enum { PDT_GAUSS=1, PDT_BERNOULLI, PDT_DBFRIENDLY } PHI_DISTR_TYPE;
1268                 ~CSMatrixGenerator();
1269                 static float* getCSMatrix(int m, int n, PHI_DISTR_TYPE dt);     // do NOT free returned pointer   
1270
1271
1272         private:
1273                 static float *cs_phi_;    // matrix for compressive sensing
1274                 static int cs_phi_m_, cs_phi_n_;
1275         };
1276
1277         class CV_EXPORTS RandomizedTree
1278         {  
1279         public:
1280                 friend class RTreeClassifier;  
1281                 //friend class ::RTTester;
1282
1283
1284                 RandomizedTree();
1285                 ~RandomizedTree();
1286
1287                 void train(std::vector<BaseKeypoint> const& base_set, cv::RNG &rng,
1288                         int depth, int views, size_t reduced_num_dim, int num_quant_bits);
1289                 void train(std::vector<BaseKeypoint> const& base_set, cv::RNG &rng,
1290                         PatchGenerator &make_patch, int depth, int views, size_t reduced_num_dim,
1291                         int num_quant_bits);
1292
1293                 // following two funcs are EXPERIMENTAL (do not use unless you know exactly what you do)
1294                 static void quantizeVector(float *vec, int dim, int N, float bnds[2], int clamp_mode=0);
1295                 static void quantizeVector(float *src, int dim, int N, float bnds[2], uchar *dst);  
1296
1297                 // patch_data must be a 32x32 array (no row padding)
1298                 float* getPosterior(uchar* patch_data);
1299                 const float* getPosterior(uchar* patch_data) const;
1300                 uchar* getPosterior2(uchar* patch_data);
1301
1302                 void read(const char* file_name, int num_quant_bits);
1303                 void read(std::istream &is, int num_quant_bits);
1304                 void write(const char* file_name) const;
1305                 void write(std::ostream &os) const;
1306
1307                 int classes() { return classes_; }
1308                 int depth() { return depth_; }
1309
1310                 //void setKeepFloatPosteriors(bool b) { keep_float_posteriors_ = b; }
1311                 void discardFloatPosteriors() { freePosteriors(1); }
1312
1313                 inline void applyQuantization(int num_quant_bits) { makePosteriors2(num_quant_bits); }
1314
1315                 // debug
1316                 void savePosteriors(std::string url, bool append=false);
1317                 void savePosteriors2(std::string url, bool append=false);
1318
1319         private:
1320                 int classes_;
1321                 int depth_;
1322                 int num_leaves_;  
1323                 std::vector<RTreeNode> nodes_;  
1324                 float **posteriors_;        // 16-bytes aligned posteriors
1325                 uchar **posteriors2_;     // 16-bytes aligned posteriors
1326                 std::vector<int> leaf_counts_;
1327
1328                 void createNodes(int num_nodes, cv::RNG &rng);
1329                 void allocPosteriorsAligned(int num_leaves, int num_classes);
1330                 void freePosteriors(int which);    // which: 1=posteriors_, 2=posteriors2_, 3=both
1331                 void init(int classes, int depth, cv::RNG &rng);
1332                 void addExample(int class_id, uchar* patch_data);
1333                 void finalize(size_t reduced_num_dim, int num_quant_bits);  
1334                 int getIndex(uchar* patch_data) const;
1335                 inline float* getPosteriorByIndex(int index);
1336                 inline uchar* getPosteriorByIndex2(int index);
1337                 inline const float* getPosteriorByIndex(int index) const;
1338                 //void makeRandomMeasMatrix(float *cs_phi, PHI_DISTR_TYPE dt, size_t reduced_num_dim);  
1339                 void convertPosteriorsToChar();
1340                 void makePosteriors2(int num_quant_bits);
1341                 void compressLeaves(size_t reduced_num_dim);  
1342                 void estimateQuantPercForPosteriors(float perc[2]);
1343         };
1344
1345         struct RTreeNode
1346         {
1347                 short offset1, offset2;
1348
1349                 RTreeNode() {}
1350
1351                 RTreeNode(uchar x1, uchar y1, uchar x2, uchar y2)
1352                         : offset1(y1*PATCH_SIZE + x1),
1353                         offset2(y2*PATCH_SIZE + x2)
1354                 {}
1355
1356                 //! Left child on 0, right child on 1
1357                 inline bool operator() (uchar* patch_data) const
1358                 {
1359                         return patch_data[offset1] > patch_data[offset2];
1360                 }
1361         };
1362
1363
1364
1365         //} // namespace features
1366         //----------------------------
1367         //rtree_classifier.h
1368         //class RTTester;
1369
1370         //namespace features {
1371
1372         class CV_EXPORTS RTreeClassifier
1373         {   
1374         public:
1375                 //friend class ::RTTester;
1376                 static const int DEFAULT_TREES = 48;
1377                 static const size_t DEFAULT_NUM_QUANT_BITS = 4;  
1378
1379                 RTreeClassifier();
1380
1381                 //modified
1382                 void train(std::vector<BaseKeypoint> const& base_set, 
1383                         cv::RNG &rng,
1384                         int num_trees = RTreeClassifier::DEFAULT_TREES,
1385                         int depth = DEFAULT_DEPTH,
1386                         int views = DEFAULT_VIEWS,
1387                         size_t reduced_num_dim = DEFAULT_REDUCED_NUM_DIM,
1388                         int num_quant_bits = DEFAULT_NUM_QUANT_BITS, bool print_status = true);
1389                 void train(std::vector<BaseKeypoint> const& base_set,
1390                         cv::RNG &rng, 
1391                         PatchGenerator &make_patch,
1392                         int num_trees = RTreeClassifier::DEFAULT_TREES,
1393                         int depth = DEFAULT_DEPTH,
1394                         int views = DEFAULT_VIEWS,
1395                         size_t reduced_num_dim = DEFAULT_REDUCED_NUM_DIM,
1396                         int num_quant_bits = DEFAULT_NUM_QUANT_BITS, bool print_status = true);
1397
1398                 // sig must point to a memory block of at least classes()*sizeof(float|uchar) bytes
1399                 void getSignature(IplImage *patch, uchar *sig);
1400                 void getSignature(IplImage *patch, float *sig);
1401                 void getSparseSignature(IplImage *patch, float *sig, float thresh);
1402                 // TODO: deprecated in favor of getSignature overload, remove
1403                 void getFloatSignature(IplImage *patch, float *sig) { getSignature(patch, sig); }
1404
1405                 static int countNonZeroElements(float *vec, int n, double tol=1e-10);
1406                 static inline void safeSignatureAlloc(uchar **sig, int num_sig=1, int sig_len=176);
1407                 static inline uchar* safeSignatureAlloc(int num_sig=1, int sig_len=176);  
1408
1409                 inline int classes() { return classes_; }
1410                 inline int original_num_classes() { return original_num_classes_; }
1411
1412                 void setQuantization(int num_quant_bits);
1413                 void discardFloatPosteriors();
1414
1415                 void read(const char* file_name);
1416                 void read(std::istream &is);
1417                 void write(const char* file_name) const;
1418                 void write(std::ostream &os) const;
1419
1420                 // experimental and debug
1421                 void saveAllFloatPosteriors(std::string file_url);
1422                 void saveAllBytePosteriors(std::string file_url);
1423                 void setFloatPosteriorsFromTextfile_176(std::string url);
1424                 float countZeroElements();
1425
1426                 std::vector<RandomizedTree> trees_;
1427
1428         private:    
1429                 int classes_;
1430                 int num_quant_bits_;
1431                 uchar **posteriors_;
1432                 ushort *ptemp_;
1433                 int original_num_classes_;  
1434                 bool keep_floats_;
1435         };
1436     
1437 CV_EXPORTS bool find4QuadCornerSubpix(const Mat& img, std::vector<Point2f>& corners, Size region_size);
1438
1439     
1440 class CV_EXPORTS BackgroundSubtractor
1441 {
1442 public:
1443     virtual ~BackgroundSubtractor();
1444     virtual void operator()(const Mat& image, Mat& fgmask, double learningRate=0);
1445 };
1446     
1447     
1448 class CV_EXPORTS BackgroundSubtractorMOG : public BackgroundSubtractor
1449 {
1450 public:
1451     BackgroundSubtractorMOG();
1452     BackgroundSubtractorMOG(int history, int nmixtures, double backgroundRatio);
1453     virtual ~BackgroundSubtractorMOG();
1454     virtual void operator()(const Mat& image, Mat& fgmask, double learningRate=0);
1455     
1456     virtual void initialize(Size frameSize, int frameType);
1457     
1458     Size frameSize;
1459     int frameType;
1460     Mat bgmodel;
1461     int nframes;
1462     int history;
1463     int nmixtures;
1464     double varThreshold;
1465     double backgroundRatio;
1466 };
1467  
1468
1469     // CvAffinePose: defines a parameterized affine transformation of an image patch.
1470     // An image patch is rotated on angle phi (in degrees), then scaled lambda1 times
1471     // along horizontal and lambda2 times along vertical direction, and then rotated again
1472     // on angle (theta - phi).
1473     class CvAffinePose
1474         {
1475         public:
1476             float phi;
1477             float theta;
1478             float lambda1;
1479             float lambda2;
1480         };
1481     
1482     
1483     class CV_EXPORTS OneWayDescriptor
1484         {
1485         public:
1486             OneWayDescriptor();
1487             ~OneWayDescriptor();
1488             
1489             // allocates memory for given descriptor parameters
1490             void Allocate(int pose_count, CvSize size, int nChannels);
1491             
1492             // GenerateSamples: generates affine transformed patches with averaging them over small transformation variations.
1493             // If external poses and transforms were specified, uses them instead of generating random ones
1494             // - pose_count: the number of poses to be generated
1495             // - frontal: the input patch (can be a roi in a larger image)
1496             // - norm: if nonzero, normalizes the output patch so that the sum of pixel intensities is 1
1497             void GenerateSamples(int pose_count, IplImage* frontal, int norm = 0);
1498             
1499             // GenerateSamplesFast: generates affine transformed patches with averaging them over small transformation variations.
1500             // Uses precalculated transformed pca components.
1501             // - frontal: the input patch (can be a roi in a larger image)
1502             // - pca_hr_avg: pca average vector
1503             // - pca_hr_eigenvectors: pca eigenvectors
1504             // - pca_descriptors: an array of precomputed descriptors of pca components containing their affine transformations
1505             //   pca_descriptors[0] corresponds to the average, pca_descriptors[1]-pca_descriptors[pca_dim] correspond to eigenvectors
1506             void GenerateSamplesFast(IplImage* frontal, CvMat* pca_hr_avg,
1507                                      CvMat* pca_hr_eigenvectors, OneWayDescriptor* pca_descriptors);
1508             
1509             // sets the poses and corresponding transforms
1510             void SetTransforms(CvAffinePose* poses, CvMat** transforms);
1511             
1512             // Initialize: builds a descriptor.
1513             // - pose_count: the number of poses to build. If poses were set externally, uses them rather than generating random ones
1514             // - frontal: input patch. Can be a roi in a larger image
1515             // - feature_name: the feature name to be associated with the descriptor
1516             // - norm: if 1, the affine transformed patches are normalized so that their sum is 1
1517             void Initialize(int pose_count, IplImage* frontal, const char* feature_name = 0, int norm = 0);
1518             
1519             // InitializeFast: builds a descriptor using precomputed descriptors of pca components
1520             // - pose_count: the number of poses to build
1521             // - frontal: input patch. Can be a roi in a larger image
1522             // - feature_name: the feature name to be associated with the descriptor
1523             // - pca_hr_avg: average vector for PCA
1524             // - pca_hr_eigenvectors: PCA eigenvectors (one vector per row)
1525             // - pca_descriptors: precomputed descriptors of PCA components, the first descriptor for the average vector
1526             // followed by the descriptors for eigenvectors
1527             void InitializeFast(int pose_count, IplImage* frontal, const char* feature_name,
1528                                 CvMat* pca_hr_avg, CvMat* pca_hr_eigenvectors, OneWayDescriptor* pca_descriptors);
1529             
1530             // ProjectPCASample: unwarps an image patch into a vector and projects it into PCA space
1531             // - patch: input image patch
1532             // - avg: PCA average vector
1533             // - eigenvectors: PCA eigenvectors, one per row
1534             // - pca_coeffs: output PCA coefficients
1535             void ProjectPCASample(IplImage* patch, CvMat* avg, CvMat* eigenvectors, CvMat* pca_coeffs) const;
1536             
1537             // InitializePCACoeffs: projects all warped patches into PCA space
1538             // - avg: PCA average vector
1539             // - eigenvectors: PCA eigenvectors, one per row
1540             void InitializePCACoeffs(CvMat* avg, CvMat* eigenvectors);
1541             
1542             // EstimatePose: finds the closest match between an input patch and a set of patches with different poses
1543             // - patch: input image patch
1544             // - pose_idx: the output index of the closest pose
1545             // - distance: the distance to the closest pose (L2 distance)
1546             void EstimatePose(IplImage* patch, int& pose_idx, float& distance) const;
1547             
1548             // EstimatePosePCA: finds the closest match between an input patch and a set of patches with different poses.
1549             // The distance between patches is computed in PCA space
1550             // - patch: input image patch
1551             // - pose_idx: the output index of the closest pose
1552             // - distance: distance to the closest pose (L2 distance in PCA space)
1553             // - avg: PCA average vector. If 0, matching without PCA is used
1554             // - eigenvectors: PCA eigenvectors, one per row
1555             void EstimatePosePCA(CvArr* patch, int& pose_idx, float& distance, CvMat* avg, CvMat* eigenvalues) const;
1556             
1557             // GetPatchSize: returns the size of each image patch after warping (2 times smaller than the input patch)
1558             CvSize GetPatchSize() const
1559             {
1560                 return m_patch_size;
1561             }
1562             
1563             // GetInputPatchSize: returns the required size of the patch that the descriptor is built from
1564             // (2 time larger than the patch after warping)
1565             CvSize GetInputPatchSize() const
1566             {
1567                 return cvSize(m_patch_size.width*2, m_patch_size.height*2);
1568             }
1569             
1570             // GetPatch: returns a patch corresponding to specified pose index
1571             // - index: pose index
1572             // - return value: the patch corresponding to specified pose index
1573             IplImage* GetPatch(int index);
1574             
1575             // GetPose: returns a pose corresponding to specified pose index
1576             // - index: pose index
1577             // - return value: the pose corresponding to specified pose index
1578             CvAffinePose GetPose(int index) const;
1579             
1580             // Save: saves all patches with different poses to a specified path
1581             void Save(const char* path);
1582             
1583             // ReadByName: reads a descriptor from a file storage
1584             // - fs: file storage
1585             // - parent: parent node
1586             // - name: node name
1587             // - return value: 1 if succeeded, 0 otherwise
1588             int ReadByName(CvFileStorage* fs, CvFileNode* parent, const char* name);
1589             
1590             // Write: writes a descriptor into a file storage
1591             // - fs: file storage
1592             // - name: node name
1593             void Write(CvFileStorage* fs, const char* name);
1594             
1595             // GetFeatureName: returns a name corresponding to a feature
1596             const char* GetFeatureName() const;
1597             
1598             // GetCenter: returns the center of the feature
1599             CvPoint GetCenter() const;
1600             
1601             void SetPCADimHigh(int pca_dim_high) {m_pca_dim_high = pca_dim_high;};
1602             void SetPCADimLow(int pca_dim_low) {m_pca_dim_low = pca_dim_low;};
1603             
1604             int GetPCADimLow() const;
1605             int GetPCADimHigh() const;
1606             
1607             CvMat** GetPCACoeffs() const {return m_pca_coeffs;}
1608             
1609         protected:
1610             int m_pose_count; // the number of poses
1611             CvSize m_patch_size; // size of each image
1612             IplImage** m_samples; // an array of length m_pose_count containing the patch in different poses
1613             IplImage* m_input_patch;
1614             IplImage* m_train_patch;
1615             CvMat** m_pca_coeffs; // an array of length m_pose_count containing pca decomposition of the patch in different poses
1616             CvAffinePose* m_affine_poses; // an array of poses
1617             CvMat** m_transforms; // an array of affine transforms corresponding to poses
1618             
1619             std::string m_feature_name; // the name of the feature associated with the descriptor
1620             CvPoint m_center; // the coordinates of the feature (the center of the input image ROI)
1621             
1622             int m_pca_dim_high; // the number of descriptor pca components to use for generating affine poses
1623             int m_pca_dim_low; // the number of pca components to use for comparison
1624         };
1625     
1626     
1627     // OneWayDescriptorBase: encapsulates functionality for training/loading a set of one way descriptors
1628     // and finding the nearest closest descriptor to an input feature
1629     class CV_EXPORTS OneWayDescriptorBase
1630         {
1631         public:
1632             
1633             // creates an instance of OneWayDescriptor from a set of training files
1634             // - patch_size: size of the input (large) patch
1635             // - pose_count: the number of poses to generate for each descriptor
1636             // - train_path: path to training files
1637             // - pca_config: the name of the file that contains PCA for small patches (2 times smaller
1638             // than patch_size each dimension
1639             // - pca_hr_config: the name of the file that contains PCA for large patches (of patch_size size)
1640             // - pca_desc_config: the name of the file that contains descriptors of PCA components
1641             OneWayDescriptorBase(CvSize patch_size, int pose_count, const char* train_path = 0, const char* pca_config = 0,
1642                                  const char* pca_hr_config = 0, const char* pca_desc_config = 0, int pyr_levels = 1,
1643                                  int pca_dim_high = 100, int pca_dim_low = 100);
1644             
1645             ~OneWayDescriptorBase();
1646             
1647             // Allocate: allocates memory for a given number of descriptors
1648             void Allocate(int train_feature_count);
1649             
1650             // AllocatePCADescriptors: allocates memory for pca descriptors
1651             void AllocatePCADescriptors();
1652             
1653             // returns patch size
1654             CvSize GetPatchSize() const {return m_patch_size;};
1655             // returns the number of poses for each descriptor
1656             int GetPoseCount() const {return m_pose_count;};
1657             
1658             // returns the number of pyramid levels
1659             int GetPyrLevels() const {return m_pyr_levels;};
1660             
1661             // returns the number of descriptors
1662             int GetDescriptorCount() const {return m_train_feature_count;};
1663             
1664             // CreateDescriptorsFromImage: creates descriptors for each of the input features
1665             // - src: input image
1666             // - features: input features
1667             // - pyr_levels: the number of pyramid levels
1668             void CreateDescriptorsFromImage(IplImage* src, const std::vector<cv::KeyPoint>& features);
1669             
1670             // CreatePCADescriptors: generates descriptors for PCA components, needed for fast generation of feature descriptors
1671             void CreatePCADescriptors();
1672             
1673             // returns a feature descriptor by feature index
1674             const OneWayDescriptor* GetDescriptor(int desc_idx) const {return &m_descriptors[desc_idx];};
1675             
1676             // FindDescriptor: finds the closest descriptor
1677             // - patch: input image patch
1678             // - desc_idx: output index of the closest descriptor to the input patch
1679             // - pose_idx: output index of the closest pose of the closest descriptor to the input patch
1680             // - distance: distance from the input patch to the closest feature pose
1681             // - _scales: scales of the input patch for each descriptor
1682             // - scale_ranges: input scales variation (float[2])
1683             void FindDescriptor(IplImage* patch, int& desc_idx, int& pose_idx, float& distance, float* _scale = 0, float* scale_ranges = 0) const;
1684             
1685             // - patch: input image patch
1686             // - n: number of the closest indexes
1687             // - desc_idxs: output indexes of the closest descriptor to the input patch (n)
1688             // - pose_idx: output indexes of the closest pose of the closest descriptor to the input patch (n)
1689             // - distances: distance from the input patch to the closest feature pose (n)
1690             // - _scales: scales of the input patch
1691             // - scale_ranges: input scales variation (float[2])
1692             void FindDescriptor(IplImage* patch, int n, std::vector<int>& desc_idxs, std::vector<int>& pose_idxs,
1693                                 std::vector<float>& distances, std::vector<float>& _scales, float* scale_ranges = 0) const;
1694             
1695             // FindDescriptor: finds the closest descriptor
1696             // - src: input image
1697             // - pt: center of the feature
1698             // - desc_idx: output index of the closest descriptor to the input patch
1699             // - pose_idx: output index of the closest pose of the closest descriptor to the input patch
1700             // - distance: distance from the input patch to the closest feature pose
1701             void FindDescriptor(IplImage* src, cv::Point2f pt, int& desc_idx, int& pose_idx, float& distance) const;
1702             
1703             // InitializePoses: generates random poses
1704             void InitializePoses();
1705             
1706             // InitializeTransformsFromPoses: generates 2x3 affine matrices from poses (initializes m_transforms)
1707             void InitializeTransformsFromPoses();
1708             
1709             // InitializePoseTransforms: subsequently calls InitializePoses and InitializeTransformsFromPoses
1710             void InitializePoseTransforms();
1711             
1712             // InitializeDescriptor: initializes a descriptor
1713             // - desc_idx: descriptor index
1714             // - train_image: image patch (ROI is supported)
1715             // - feature_label: feature textual label
1716             void InitializeDescriptor(int desc_idx, IplImage* train_image, const char* feature_label);
1717             
1718             void InitializeDescriptor(int desc_idx, IplImage* train_image, const cv::KeyPoint& keypoint, const char* feature_label);
1719             
1720             // InitializeDescriptors: load features from an image and create descriptors for each of them
1721             void InitializeDescriptors(IplImage* train_image, const vector<cv::KeyPoint>& features,
1722                                        const char* feature_label = "", int desc_start_idx = 0);
1723             
1724             // LoadPCADescriptors: loads PCA descriptors from a file
1725             // - filename: input filename
1726             int LoadPCADescriptors(const char* filename);
1727             
1728             // SavePCADescriptors: saves PCA descriptors to a file
1729             // - filename: output filename
1730             void SavePCADescriptors(const char* filename);
1731             
1732             // SetPCAHigh: sets the high resolution pca matrices (copied to internal structures)
1733             void SetPCAHigh(CvMat* avg, CvMat* eigenvectors);
1734             
1735             // SetPCALow: sets the low resolution pca matrices (copied to internal structures)
1736             void SetPCALow(CvMat* avg, CvMat* eigenvectors);
1737             
1738             int GetLowPCA(CvMat** avg, CvMat** eigenvectors)
1739             {
1740                 *avg = m_pca_avg;
1741                 *eigenvectors = m_pca_eigenvectors;
1742                 return m_pca_dim_low;
1743             };
1744             
1745             void ConvertDescriptorsArrayToTree(); // Converting pca_descriptors array to KD tree
1746             
1747             
1748         protected:
1749             CvSize m_patch_size; // patch size
1750             int m_pose_count; // the number of poses for each descriptor
1751             int m_train_feature_count; // the number of the training features
1752             OneWayDescriptor* m_descriptors; // array of train feature descriptors
1753             CvMat* m_pca_avg; // PCA average Vector for small patches
1754             CvMat* m_pca_eigenvectors; // PCA eigenvectors for small patches
1755             CvMat* m_pca_hr_avg; // PCA average Vector for large patches
1756             CvMat* m_pca_hr_eigenvectors; // PCA eigenvectors for large patches
1757             OneWayDescriptor* m_pca_descriptors; // an array of PCA descriptors
1758             
1759             cv::flann::Index* m_pca_descriptors_tree;
1760             CvMat* m_pca_descriptors_matrix;
1761             
1762             CvAffinePose* m_poses; // array of poses
1763             CvMat** m_transforms; // array of affine transformations corresponding to poses
1764             
1765             int m_pca_dim_high;
1766             int m_pca_dim_low;
1767             
1768             int m_pyr_levels;
1769             
1770         };
1771     
1772     class OneWayDescriptorObject : public OneWayDescriptorBase
1773         {
1774         public:
1775             // creates an instance of OneWayDescriptorObject from a set of training files
1776             // - patch_size: size of the input (large) patch
1777             // - pose_count: the number of poses to generate for each descriptor
1778             // - train_path: path to training files
1779             // - pca_config: the name of the file that contains PCA for small patches (2 times smaller
1780             // than patch_size each dimension
1781             // - pca_hr_config: the name of the file that contains PCA for large patches (of patch_size size)
1782             // - pca_desc_config: the name of the file that contains descriptors of PCA components
1783             OneWayDescriptorObject(CvSize patch_size, int pose_count, const char* train_path, const char* pca_config,
1784                                    const char* pca_hr_config = 0, const char* pca_desc_config = 0, int pyr_levels = 1);
1785             
1786             ~OneWayDescriptorObject();
1787             
1788             // Allocate: allocates memory for a given number of features
1789             // - train_feature_count: the total number of features
1790             // - object_feature_count: the number of features extracted from the object
1791             void Allocate(int train_feature_count, int object_feature_count);
1792             
1793             
1794             void SetLabeledFeatures(const vector<cv::KeyPoint>& features) {m_train_features = features;};
1795             vector<cv::KeyPoint>& GetLabeledFeatures() {return m_train_features;};
1796             const vector<cv::KeyPoint>& GetLabeledFeatures() const {return m_train_features;};
1797             vector<cv::KeyPoint> _GetLabeledFeatures() const;
1798             
1799             // IsDescriptorObject: returns 1 if descriptor with specified index is positive, otherwise 0
1800             int IsDescriptorObject(int desc_idx) const;
1801             
1802             // MatchPointToPart: returns the part number of a feature if it matches one of the object parts, otherwise -1
1803             int MatchPointToPart(CvPoint pt) const;
1804             
1805             // GetDescriptorPart: returns the part number of the feature corresponding to a specified descriptor
1806             // - desc_idx: descriptor index
1807             int GetDescriptorPart(int desc_idx) const;
1808             
1809             
1810             void InitializeObjectDescriptors(IplImage* train_image, const vector<cv::KeyPoint>& features,
1811                                              const char* feature_label, int desc_start_idx = 0, float scale = 1.0f,
1812                                              int is_background = 0);
1813             
1814             // GetObjectFeatureCount: returns the number of object features
1815             int GetObjectFeatureCount() const {return m_object_feature_count;};
1816             
1817         protected:
1818             int* m_part_id; // contains part id for each of object descriptors
1819             vector<cv::KeyPoint> m_train_features; // train features
1820             int m_object_feature_count; // the number of the positive features
1821             
1822         };
1823     
1824
1825 }
1826
1827 #endif /* __cplusplus */
1828
1829 #endif /* __CVAUX_HPP__ */
1830
1831 /* End of file. */