Cinder

  • Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

include/OpenCV/cvaux.hpp

Go to the documentation of this file.
00001 /*M///////////////////////////////////////////////////////////////////////////////////////
00002 //
00003 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
00004 //
00005 //  By downloading, copying, installing or using the software you agree to this license.
00006 //  If you do not agree to this license, do not download, install,
00007 //  copy or use the software.
00008 //
00009 //
00010 //                        Intel License Agreement
00011 //                For Open Source Computer Vision Library
00012 //
00013 // Copyright (C) 2000, Intel Corporation, all rights reserved.
00014 // Third party copyrights are property of their respective owners.
00015 //
00016 // Redistribution and use in source and binary forms, with or without modification,
00017 // are permitted provided that the following conditions are met:
00018 //
00019 //   * Redistribution's of source code must retain the above copyright notice,
00020 //     this list of conditions and the following disclaimer.
00021 //
00022 //   * Redistribution's in binary form must reproduce the above copyright notice,
00023 //     this list of conditions and the following disclaimer in the documentation
00024 //     and/or other materials provided with the distribution.
00025 //
00026 //   * The name of Intel Corporation may not be used to endorse or promote products
00027 //     derived from this software without specific prior written permission.
00028 //
00029 // This software is provided by the copyright holders and contributors "as is" and
00030 // any express or implied warranties, including, but not limited to, the implied
00031 // warranties of merchantability and fitness for a particular purpose are disclaimed.
00032 // In no event shall the Intel Corporation or contributors be liable for any direct,
00033 // indirect, incidental, special, exemplary, or consequential damages
00034 // (including, but not limited to, procurement of substitute goods or services;
00035 // loss of use, data, or profits; or business interruption) however caused
00036 // and on any theory of liability, whether in contract, strict liability,
00037 // or tort (including negligence or otherwise) arising in any way out of
00038 // the use of this software, even if advised of the possibility of such damage.
00039 //
00040 //M*/
00041 
00042 #ifndef __OPENCV_AUX_HPP__
00043 #define __OPENCV_AUX_HPP__
00044 
00045 #ifdef __cplusplus
00046 
00047 #include <iosfwd>
00048 
00049 class CV_EXPORTS CvImage
00050 {
00051 public:
00052     CvImage() : image(0), refcount(0) {}
00053     CvImage( CvSize size, int depth, int channels )
00054     {
00055         image = cvCreateImage( size, depth, channels );
00056         refcount = image ? new int(1) : 0;
00057     }
00058 
00059     CvImage( IplImage* img ) : image(img)
00060     {
00061         refcount = image ? new int(1) : 0;
00062     }
00063 
00064     CvImage( const CvImage& img ) : image(img.image), refcount(img.refcount)
00065     {
00066         if( refcount ) ++(*refcount);
00067     }
00068 
00069     CvImage( const char* filename, const char* imgname=0, int color=-1 ) : image(0), refcount(0)
00070     { load( filename, imgname, color ); }
00071 
00072     CvImage( CvFileStorage* fs, const char* mapname, const char* imgname ) : image(0), refcount(0)
00073     { read( fs, mapname, imgname ); }
00074 
00075     CvImage( CvFileStorage* fs, const char* seqname, int idx ) : image(0), refcount(0)
00076     { read( fs, seqname, idx ); }
00077 
00078     ~CvImage()
00079     {
00080         if( refcount && !(--*refcount) )
00081         {
00082             cvReleaseImage( &image );
00083             delete refcount;
00084         }
00085     }
00086 
00087     CvImage clone() { return CvImage(image ? cvCloneImage(image) : 0); }
00088 
00089     void create( CvSize size, int depth, int channels )
00090     {
00091         if( !image || !refcount ||
00092             image->width != size.width || image->height != size.height ||
00093             image->depth != depth || image->nChannels != channels )
00094             attach( cvCreateImage( size, depth, channels ));
00095     }
00096 
00097     void release() { detach(); }
00098     void clear() { detach(); }
00099 
00100     void attach( IplImage* img, bool use_refcount=true )
00101     {
00102         if( refcount && --*refcount == 0 )
00103         {
00104             cvReleaseImage( &image );
00105             delete refcount;
00106         }
00107         image = img;
00108         refcount = use_refcount && image ? new int(1) : 0;
00109     }
00110 
00111     void detach()
00112     {
00113         if( refcount && --*refcount == 0 )
00114         {
00115             cvReleaseImage( &image );
00116             delete refcount;
00117         }
00118         image = 0;
00119         refcount = 0;
00120     }
00121 
00122     bool load( const char* filename, const char* imgname=0, int color=-1 );
00123     bool read( CvFileStorage* fs, const char* mapname, const char* imgname );
00124     bool read( CvFileStorage* fs, const char* seqname, int idx );
00125     void save( const char* filename, const char* imgname, const int* params=0 );
00126     void write( CvFileStorage* fs, const char* imgname );
00127 
00128     void show( const char* window_name );
00129     bool is_valid() { return image != 0; }
00130 
00131     int width() const { return image ? image->width : 0; }
00132     int height() const { return image ? image->height : 0; }
00133 
00134     CvSize size() const { return image ? cvSize(image->width, image->height) : cvSize(0,0); }
00135 
00136     CvSize roi_size() const
00137     {
00138         return !image ? cvSize(0,0) :
00139             !image->roi ? cvSize(image->width,image->height) :
00140             cvSize(image->roi->width, image->roi->height);
00141     }
00142 
00143     CvRect roi() const
00144     {
00145         return !image ? cvRect(0,0,0,0) :
00146             !image->roi ? cvRect(0,0,image->width,image->height) :
00147             cvRect(image->roi->xOffset,image->roi->yOffset,
00148                    image->roi->width,image->roi->height);
00149     }
00150 
00151     int coi() const { return !image || !image->roi ? 0 : image->roi->coi; }
00152 
00153     void set_roi(CvRect roi) { cvSetImageROI(image,roi); }
00154     void reset_roi() { cvResetImageROI(image); }
00155     void set_coi(int coi) { cvSetImageCOI(image,coi); }
00156     int depth() const { return image ? image->depth : 0; }
00157     int channels() const { return image ? image->nChannels : 0; }
00158     int pix_size() const { return image ? ((image->depth & 255)>>3)*image->nChannels : 0; }
00159 
00160     uchar* data() { return image ? (uchar*)image->imageData : 0; }
00161     const uchar* data() const { return image ? (const uchar*)image->imageData : 0; }
00162     int step() const { return image ? image->widthStep : 0; }
00163     int origin() const { return image ? image->origin : 0; }
00164 
00165     uchar* roi_row(int y)
00166     {
00167         assert(0<=y);
00168         assert(!image ?
00169                 1 : image->roi ?
00170                 y<image->roi->height : y<image->height);
00171         
00172         return !image ? 0 :
00173             !image->roi ?
00174                 (uchar*)(image->imageData + y*image->widthStep) :
00175                 (uchar*)(image->imageData + (y+image->roi->yOffset)*image->widthStep +
00176                 image->roi->xOffset*((image->depth & 255)>>3)*image->nChannels);
00177     }
00178 
00179     const uchar* roi_row(int y) const
00180     {
00181         assert(0<=y);
00182         assert(!image ?
00183                 1 : image->roi ?
00184                 y<image->roi->height : y<image->height); 
00185 
00186         return !image ? 0 :
00187             !image->roi ?
00188                 (const uchar*)(image->imageData + y*image->widthStep) :
00189                 (const uchar*)(image->imageData + (y+image->roi->yOffset)*image->widthStep +
00190                 image->roi->xOffset*((image->depth & 255)>>3)*image->nChannels);
00191     }
00192 
00193     operator const IplImage* () const { return image; }
00194     operator IplImage* () { return image; }
00195 
00196     CvImage& operator = (const CvImage& img)
00197     {
00198         if( img.refcount )
00199             ++*img.refcount;
00200         if( refcount && !(--*refcount) )
00201             cvReleaseImage( &image );
00202         image=img.image;
00203         refcount=img.refcount;
00204         return *this;
00205     }
00206 
00207 protected:
00208     IplImage* image;
00209     int* refcount;
00210 };
00211 
00212 
00213 class CV_EXPORTS CvMatrix
00214 {
00215 public:
00216     CvMatrix() : matrix(0) {}
00217     CvMatrix( int rows, int cols, int type )
00218     { matrix = cvCreateMat( rows, cols, type ); }
00219 
00220     CvMatrix( int rows, int cols, int type, CvMat* hdr,
00221               void* data=0, int step=CV_AUTOSTEP )
00222     { matrix = cvInitMatHeader( hdr, rows, cols, type, data, step ); }
00223 
00224     CvMatrix( int rows, int cols, int type, CvMemStorage* storage, bool alloc_data=true );
00225 
00226     CvMatrix( int rows, int cols, int type, void* data, int step=CV_AUTOSTEP )
00227     { matrix = cvCreateMatHeader( rows, cols, type );
00228       cvSetData( matrix, data, step ); }
00229 
00230     CvMatrix( CvMat* m )
00231     { matrix = m; }
00232 
00233     CvMatrix( const CvMatrix& m )
00234     {
00235         matrix = m.matrix;
00236         addref();
00237     }
00238 
00239     CvMatrix( const char* filename, const char* matname=0, int color=-1 ) : matrix(0)
00240     {  load( filename, matname, color ); }
00241 
00242     CvMatrix( CvFileStorage* fs, const char* mapname, const char* matname ) : matrix(0)
00243     {  read( fs, mapname, matname ); }
00244 
00245     CvMatrix( CvFileStorage* fs, const char* seqname, int idx ) : matrix(0)
00246     {  read( fs, seqname, idx ); }
00247 
00248     ~CvMatrix()
00249     {
00250         release();
00251     }
00252 
00253     CvMatrix clone() { return CvMatrix(matrix ? cvCloneMat(matrix) : 0); }
00254 
00255     void set( CvMat* m, bool add_ref )
00256     {
00257         release();
00258         matrix = m;
00259         if( add_ref )
00260             addref();
00261     }
00262 
00263     void create( int rows, int cols, int type )
00264     {
00265         if( !matrix || !matrix->refcount ||
00266             matrix->rows != rows || matrix->cols != cols ||
00267             CV_MAT_TYPE(matrix->type) != type )
00268             set( cvCreateMat( rows, cols, type ), false );
00269     }
00270 
00271     void addref() const
00272     {
00273         if( matrix )
00274         {
00275             if( matrix->hdr_refcount )
00276                 ++matrix->hdr_refcount;
00277             else if( matrix->refcount )
00278                 ++*matrix->refcount;
00279         }
00280     }
00281 
00282     void release()
00283     {
00284         if( matrix )
00285         {
00286             if( matrix->hdr_refcount )
00287             {
00288                 if( --matrix->hdr_refcount == 0 )
00289                     cvReleaseMat( &matrix );
00290             }
00291             else if( matrix->refcount )
00292             {
00293                 if( --*matrix->refcount == 0 )
00294                     cvFree( &matrix->refcount );
00295             }
00296             matrix = 0;
00297         }
00298     }
00299 
00300     void clear()
00301     {
00302         release();
00303     }
00304 
00305     bool load( const char* filename, const char* matname=0, int color=-1 );
00306     bool read( CvFileStorage* fs, const char* mapname, const char* matname );
00307     bool read( CvFileStorage* fs, const char* seqname, int idx );
00308     void save( const char* filename, const char* matname, const int* params=0 );
00309     void write( CvFileStorage* fs, const char* matname );
00310 
00311     void show( const char* window_name );
00312 
00313     bool is_valid() { return matrix != 0; }
00314 
00315     int rows() const { return matrix ? matrix->rows : 0; }
00316     int cols() const { return matrix ? matrix->cols : 0; }
00317 
00318     CvSize size() const
00319     {
00320         return !matrix ? cvSize(0,0) : cvSize(matrix->rows,matrix->cols);
00321     }
00322 
00323     int type() const { return matrix ? CV_MAT_TYPE(matrix->type) : 0; }
00324     int depth() const { return matrix ? CV_MAT_DEPTH(matrix->type) : 0; }
00325     int channels() const { return matrix ? CV_MAT_CN(matrix->type) : 0; }
00326     int pix_size() const { return matrix ? CV_ELEM_SIZE(matrix->type) : 0; }
00327 
00328     uchar* data() { return matrix ? matrix->data.ptr : 0; }
00329     const uchar* data() const { return matrix ? matrix->data.ptr : 0; }
00330     int step() const { return matrix ? matrix->step : 0; }
00331 
00332     void set_data( void* data, int step=CV_AUTOSTEP )
00333     { cvSetData( matrix, data, step ); }
00334 
00335     uchar* row(int i) { return !matrix ? 0 : matrix->data.ptr + i*matrix->step; }
00336     const uchar* row(int i) const
00337     { return !matrix ? 0 : matrix->data.ptr + i*matrix->step; }
00338 
00339     operator const CvMat* () const { return matrix; }
00340     operator CvMat* () { return matrix; }
00341 
00342     CvMatrix& operator = (const CvMatrix& _m)
00343     {
00344         _m.addref();
00345         release();
00346         matrix = _m.matrix;
00347         return *this;
00348     }
00349 
00350 protected:
00351     CvMat* matrix;
00352 };
00353 
00354 /****************************************************************************************\
00355 *                                       CamShiftTracker                                  *
00356 \****************************************************************************************/
00357 
00358 class CV_EXPORTS CvCamShiftTracker
00359 {
00360 public:
00361 
00362     CvCamShiftTracker();
00363     virtual ~CvCamShiftTracker();
00364 
00365     /**** Characteristics of the object that are calculated by track_object method *****/
00366     float   get_orientation() const // orientation of the object in degrees
00367     { return m_box.angle; }
00368     float   get_length() const // the larger linear size of the object
00369     { return m_box.size.height; }
00370     float   get_width() const // the smaller linear size of the object
00371     { return m_box.size.width; }
00372     CvPoint2D32f get_center() const // center of the object
00373     { return m_box.center; }
00374     CvRect get_window() const // bounding rectangle for the object
00375     { return m_comp.rect; }
00376 
00377     /*********************** Tracking parameters ************************/
00378     int     get_threshold() const // thresholding value that applied to back project
00379     { return m_threshold; }
00380 
00381     int     get_hist_dims( int* dims = 0 ) const // returns number of histogram dimensions and sets
00382     { return m_hist ? cvGetDims( m_hist->bins, dims ) : 0; }
00383 
00384     int     get_min_ch_val( int channel ) const // get the minimum allowed value of the specified channel
00385     { return m_min_ch_val[channel]; }
00386 
00387     int     get_max_ch_val( int channel ) const // get the maximum allowed value of the specified channel
00388     { return m_max_ch_val[channel]; }
00389 
00390     // set initial object rectangle (must be called before initial calculation of the histogram)
00391     bool    set_window( CvRect window)
00392     { m_comp.rect = window; return true; }
00393 
00394     bool    set_threshold( int threshold ) // threshold applied to the histogram bins
00395     { m_threshold = threshold; return true; }
00396 
00397     bool    set_hist_bin_range( int dim, int min_val, int max_val );
00398 
00399     bool    set_hist_dims( int c_dims, int* dims );// set the histogram parameters
00400 
00401     bool    set_min_ch_val( int channel, int val ) // set the minimum allowed value of the specified channel
00402     { m_min_ch_val[channel] = val; return true; }
00403     bool    set_max_ch_val( int channel, int val ) // set the maximum allowed value of the specified channel
00404     { m_max_ch_val[channel] = val; return true; }
00405 
00406     /************************ The processing methods *********************************/
00407     // update object position
00408     virtual bool  track_object( const IplImage* cur_frame );
00409 
00410     // update object histogram
00411     virtual bool  update_histogram( const IplImage* cur_frame );
00412 
00413     // reset histogram
00414     virtual void  reset_histogram();
00415 
00416     /************************ Retrieving internal data *******************************/
00417     // get back project image
00418     virtual IplImage* get_back_project()
00419     { return m_back_project; }
00420 
00421     float query( int* bin ) const
00422     { return m_hist ? (float)cvGetRealND(m_hist->bins, bin) : 0.f; }
00423 
00424 protected:
00425 
00426     // internal method for color conversion: fills m_color_planes group
00427     virtual void color_transform( const IplImage* img );
00428 
00429     CvHistogram* m_hist;
00430 
00431     CvBox2D    m_box;
00432     CvConnectedComp m_comp;
00433 
00434     float      m_hist_ranges_data[CV_MAX_DIM][2];
00435     float*     m_hist_ranges[CV_MAX_DIM];
00436 
00437     int        m_min_ch_val[CV_MAX_DIM];
00438     int        m_max_ch_val[CV_MAX_DIM];
00439     int        m_threshold;
00440 
00441     IplImage*  m_color_planes[CV_MAX_DIM];
00442     IplImage*  m_back_project;
00443     IplImage*  m_temp;
00444     IplImage*  m_mask;
00445 };
00446 
00447 /****************************************************************************************\
00448 *                                   Adaptive Skin Detector                               *
00449 \****************************************************************************************/
00450 
00451 class CV_EXPORTS CvAdaptiveSkinDetector
00452 {
00453 private:
00454     enum {
00455         GSD_HUE_LT = 3,
00456         GSD_HUE_UT = 33,
00457         GSD_INTENSITY_LT = 15,
00458         GSD_INTENSITY_UT = 250
00459     };
00460 
00461     class CV_EXPORTS Histogram
00462     {
00463     private:
00464         enum {
00465             HistogramSize = (GSD_HUE_UT - GSD_HUE_LT + 1)
00466         };
00467 
00468     protected:
00469         int findCoverageIndex(double surfaceToCover, int defaultValue = 0);
00470 
00471     public:
00472         CvHistogram *fHistogram;
00473         Histogram();
00474         virtual ~Histogram();
00475 
00476         void findCurveThresholds(int &x1, int &x2, double percent = 0.05);
00477         void mergeWith(Histogram *source, double weight);
00478     };
00479 
00480     int nStartCounter, nFrameCount, nSkinHueLowerBound, nSkinHueUpperBound, nMorphingMethod, nSamplingDivider;
00481     double fHistogramMergeFactor, fHuePercentCovered;
00482     Histogram histogramHueMotion, skinHueHistogram;
00483     IplImage *imgHueFrame, *imgSaturationFrame, *imgLastGrayFrame, *imgMotionFrame, *imgFilteredFrame;
00484     IplImage *imgShrinked, *imgTemp, *imgGrayFrame, *imgHSVFrame;
00485 
00486 protected:
00487     void initData(IplImage *src, int widthDivider, int heightDivider);
00488     void adaptiveFilter();
00489 
00490 public:
00491 
00492     enum {
00493         MORPHING_METHOD_NONE = 0,
00494         MORPHING_METHOD_ERODE = 1,
00495         MORPHING_METHOD_ERODE_ERODE = 2,
00496         MORPHING_METHOD_ERODE_DILATE = 3
00497     };
00498 
00499     CvAdaptiveSkinDetector(int samplingDivider = 1, int morphingMethod = MORPHING_METHOD_NONE);
00500     virtual ~CvAdaptiveSkinDetector();
00501 
00502     virtual void process(IplImage *inputBGRImage, IplImage *outputHueMask);
00503 };
00504 
00505 
00506 /****************************************************************************************\
00507 *                                  Fuzzy MeanShift Tracker                               *
00508 \****************************************************************************************/
00509 
00510 class CV_EXPORTS CvFuzzyPoint {
00511 public:
00512     double x, y, value;
00513 
00514     CvFuzzyPoint(double _x, double _y);
00515 };
00516 
00517 class CV_EXPORTS CvFuzzyCurve {
00518 private:
00519     std::vector<CvFuzzyPoint> points;
00520     double value, centre;
00521 
00522     bool between(double x, double x1, double x2);
00523 
00524 public:
00525     CvFuzzyCurve();
00526     ~CvFuzzyCurve();
00527 
00528     void setCentre(double _centre);
00529     double getCentre();
00530     void clear();
00531     void addPoint(double x, double y);
00532     double calcValue(double param);
00533     double getValue();
00534     void setValue(double _value);
00535 };
00536 
00537 class CV_EXPORTS CvFuzzyFunction {
00538 public:
00539     std::vector<CvFuzzyCurve> curves;
00540 
00541     CvFuzzyFunction();
00542     ~CvFuzzyFunction();
00543     void addCurve(CvFuzzyCurve *curve, double value = 0);
00544     void resetValues();
00545     double calcValue();
00546     CvFuzzyCurve *newCurve();
00547 };
00548 
00549 class CV_EXPORTS CvFuzzyRule {
00550 private:
00551     CvFuzzyCurve *fuzzyInput1, *fuzzyInput2;
00552     CvFuzzyCurve *fuzzyOutput;
00553 public:
00554     CvFuzzyRule();
00555     ~CvFuzzyRule();
00556     void setRule(CvFuzzyCurve *c1, CvFuzzyCurve *c2, CvFuzzyCurve *o1);
00557     double calcValue(double param1, double param2);
00558     CvFuzzyCurve *getOutputCurve();
00559 };
00560 
00561 class CV_EXPORTS CvFuzzyController {
00562 private:
00563     std::vector<CvFuzzyRule*> rules;
00564 public:
00565     CvFuzzyController();
00566     ~CvFuzzyController();
00567     void addRule(CvFuzzyCurve *c1, CvFuzzyCurve *c2, CvFuzzyCurve *o1);
00568     double calcOutput(double param1, double param2);
00569 };
00570 
00571 class CV_EXPORTS CvFuzzyMeanShiftTracker
00572 {
00573 private:
00574     class FuzzyResizer
00575     {
00576     private:
00577         CvFuzzyFunction iInput, iOutput;
00578         CvFuzzyController fuzzyController;
00579     public:
00580         FuzzyResizer();
00581         int calcOutput(double edgeDensity, double density);
00582     };
00583 
00584     class SearchWindow
00585     {
00586     public:
00587         FuzzyResizer *fuzzyResizer;
00588         int x, y;
00589         int width, height, maxWidth, maxHeight, ellipseHeight, ellipseWidth;
00590         int ldx, ldy, ldw, ldh, numShifts, numIters;
00591         int xGc, yGc;
00592         long m00, m01, m10, m11, m02, m20;
00593         double ellipseAngle;
00594         double density;
00595         unsigned int depthLow, depthHigh;
00596         int verticalEdgeLeft, verticalEdgeRight, horizontalEdgeTop, horizontalEdgeBottom;
00597 
00598         SearchWindow();
00599         ~SearchWindow();
00600         void setSize(int _x, int _y, int _width, int _height);
00601         void initDepthValues(IplImage *maskImage, IplImage *depthMap);
00602         bool shift();
00603         void extractInfo(IplImage *maskImage, IplImage *depthMap, bool initDepth);
00604         void getResizeAttribsEdgeDensityLinear(int &resizeDx, int &resizeDy, int &resizeDw, int &resizeDh);
00605         void getResizeAttribsInnerDensity(int &resizeDx, int &resizeDy, int &resizeDw, int &resizeDh);
00606         void getResizeAttribsEdgeDensityFuzzy(int &resizeDx, int &resizeDy, int &resizeDw, int &resizeDh);
00607         bool meanShift(IplImage *maskImage, IplImage *depthMap, int maxIteration, bool initDepth);
00608     };
00609 
00610 public:
00611     enum TrackingState
00612     {
00613         tsNone          = 0,
00614         tsSearching     = 1,
00615         tsTracking      = 2,
00616         tsSetWindow     = 3,
00617         tsDisabled      = 10
00618     };
00619 
00620     enum ResizeMethod {
00621         rmEdgeDensityLinear     = 0,
00622         rmEdgeDensityFuzzy      = 1,
00623         rmInnerDensity          = 2
00624     };
00625 
00626     enum {
00627         MinKernelMass           = 1000
00628     };
00629 
00630     SearchWindow kernel;
00631     int searchMode;
00632 
00633 private:
00634     enum
00635     {
00636         MaxMeanShiftIteration   = 5,
00637         MaxSetSizeIteration     = 5
00638     };
00639 
00640     void findOptimumSearchWindow(SearchWindow &searchWindow, IplImage *maskImage, IplImage *depthMap, int maxIteration, int resizeMethod, bool initDepth);
00641 
00642 public:
00643     CvFuzzyMeanShiftTracker();
00644     ~CvFuzzyMeanShiftTracker();
00645 
00646     void track(IplImage *maskImage, IplImage *depthMap, int resizeMethod, bool resetSearch, int minKernelMass = MinKernelMass);
00647 };
00648 
00649 
00650 namespace cv
00651 {
00652 
00653 class CV_EXPORTS Octree
00654 {
00655 public:    
00656     struct Node
00657     {
00658         Node() {}
00659         int begin, end;
00660         float x_min, x_max, y_min, y_max, z_min, z_max;     
00661         int maxLevels;
00662         bool isLeaf;
00663         int children[8];
00664     };
00665 
00666     Octree();
00667     Octree( const vector<Point3f>& points, int maxLevels = 10, int minPoints = 20 );
00668     virtual ~Octree();
00669 
00670     virtual void buildTree( const vector<Point3f>& points, int maxLevels = 10, int minPoints = 20 );
00671     virtual void getPointsWithinSphere( const Point3f& center, float radius,
00672                                         vector<Point3f>& points ) const;
00673     const vector<Node>& getNodes() const { return nodes; }
00674 private:
00675     int minPoints;
00676     vector<Point3f> points;
00677     vector<Node> nodes;
00678     
00679     virtual void buildNext(size_t node_ind);
00680 };
00681 
00682 
00683 class CV_EXPORTS Mesh3D
00684 {
00685 public:
00686     struct EmptyMeshException {};
00687 
00688     Mesh3D();
00689     Mesh3D(const vector<Point3f>& vtx);
00690     ~Mesh3D();
00691 
00692     void buildOctree();
00693     void clearOctree();
00694     float estimateResolution(float tryRatio = 0.1f);        
00695     void computeNormals(float normalRadius, int minNeighbors = 20);
00696     void computeNormals(const vector<int>& subset, float normalRadius, int minNeighbors = 20);
00697     
00698     void writeAsVrml(const String& file, const vector<Scalar>& colors = vector<Scalar>()) const;
00699     
00700     vector<Point3f> vtx;
00701     vector<Point3f> normals;
00702     float resolution;    
00703     Octree octree;
00704 
00705     const static Point3f allzero;
00706 };
00707 
00708 class CV_EXPORTS SpinImageModel
00709 {
00710 public:
00711     
00712     /* model parameters, leave unset for default or auto estimate */
00713     float normalRadius;
00714     int minNeighbors;
00715 
00716     float binSize;
00717     int imageWidth;
00718 
00719     float lambda;                        
00720     float gamma;
00721 
00722     float T_GeometriccConsistency;
00723     float T_GroupingCorespondances;
00724 
00725     /* public interface */
00726     SpinImageModel();
00727     explicit SpinImageModel(const Mesh3D& mesh);
00728     ~SpinImageModel();
00729 
00730     void setLogger(std::ostream* log);
00731     void selectRandomSubset(float ratio);         
00732     void setSubset(const vector<int>& subset);         
00733     void compute();
00734 
00735     void match(const SpinImageModel& scene, vector< vector<Vec2i> >& result);    
00736 
00737     Mat packRandomScaledSpins(bool separateScale = false, size_t xCount = 10, size_t yCount = 10) const;
00738     
00739     size_t getSpinCount() const { return spinImages.rows; }
00740     Mat getSpinImage(size_t index) const { return spinImages.row(index); }
00741     const Point3f& getSpinVertex(size_t index) const { return mesh.vtx[subset[index]]; }
00742     const Point3f& getSpinNormal(size_t index) const { return mesh.normals[subset[index]]; }
00743 
00744     const Mesh3D& getMesh() const { return mesh; }
00745     Mesh3D& getMesh() { return mesh; }
00746 
00747     /* static utility functions */
00748     static bool spinCorrelation(const Mat& spin1, const Mat& spin2, float lambda, float& result);
00749 
00750     static Point2f calcSpinMapCoo(const Point3f& point, const Point3f& vertex, const Point3f& normal);
00751 
00752     static float geometricConsistency(const Point3f& pointScene1, const Point3f& normalScene1,
00753                                       const Point3f& pointModel1, const Point3f& normalModel1,   
00754                                       const Point3f& pointScene2, const Point3f& normalScene2,                               
00755                                       const Point3f& pointModel2, const Point3f& normalModel2);
00756 
00757     static float groupingCreteria(const Point3f& pointScene1, const Point3f& normalScene1,
00758                                   const Point3f& pointModel1, const Point3f& normalModel1,
00759                                   const Point3f& pointScene2, const Point3f& normalScene2,                               
00760                                   const Point3f& pointModel2, const Point3f& normalModel2, 
00761                                   float gamma);
00762 protected:       
00763     void defaultParams();
00764 
00765     void matchSpinToModel(const Mat& spin, vector<int>& indeces, 
00766         vector<float>& corrCoeffs, bool useExtremeOutliers = true) const; 
00767 
00768     void repackSpinImages(const vector<uchar>& mask, Mat& spinImages, bool reAlloc = true) const;
00769              
00770     vector<int> subset;
00771     Mesh3D mesh;
00772     Mat spinImages;
00773     std::ostream* out;
00774 };
00775 
00776 class CV_EXPORTS TickMeter
00777 {
00778 public:
00779     TickMeter();
00780     void start();    
00781     void stop();
00782 
00783     int64 getTimeTicks() const;
00784     double getTimeMicro() const;
00785     double getTimeMilli() const;
00786     double getTimeSec()   const;
00787     int64 getCounter() const;
00788 
00789     void reset();
00790 private:
00791     int64 counter;
00792     int64 sumTime;
00793     int64 startTime;
00794 };
00795 
00796 CV_EXPORTS std::ostream& operator<<(std::ostream& out, const TickMeter& tm);
00797 
00798 /****************************************************************************************\
00799 *            HOG (Histogram-of-Oriented-Gradients) Descriptor and Object Detector        *
00800 \****************************************************************************************/
00801 
00802 struct CV_EXPORTS HOGDescriptor
00803 {
00804 public:
00805     enum { L2Hys=0 };
00806 
00807     HOGDescriptor() : winSize(64,128), blockSize(16,16), blockStride(8,8),
00808         cellSize(8,8), nbins(9), derivAperture(1), winSigma(-1),
00809         histogramNormType(L2Hys), L2HysThreshold(0.2), gammaCorrection(true)
00810     {}
00811 
00812     HOGDescriptor(Size _winSize, Size _blockSize, Size _blockStride,
00813         Size _cellSize, int _nbins, int _derivAperture=1, double _winSigma=-1,
00814         int _histogramNormType=L2Hys, double _L2HysThreshold=0.2, bool _gammaCorrection=false)
00815         : winSize(_winSize), blockSize(_blockSize), blockStride(_blockStride), cellSize(_cellSize),
00816         nbins(_nbins), derivAperture(_derivAperture), winSigma(_winSigma),
00817         histogramNormType(_histogramNormType), L2HysThreshold(_L2HysThreshold),
00818         gammaCorrection(_gammaCorrection)
00819     {}
00820 
00821     HOGDescriptor(const String& filename)
00822     {
00823         load(filename);
00824     }
00825 
00826     virtual ~HOGDescriptor() {}
00827 
00828     size_t getDescriptorSize() const;
00829     bool checkDetectorSize() const;
00830     double getWinSigma() const;
00831 
00832     virtual void setSVMDetector(const vector<float>& _svmdetector);
00833 
00834     virtual bool load(const String& filename, const String& objname=String());
00835     virtual void save(const String& filename, const String& objname=String()) const;
00836 
00837     virtual void compute(const Mat& img,
00838                          vector<float>& descriptors,
00839                          Size winStride=Size(), Size padding=Size(),
00840                          const vector<Point>& locations=vector<Point>()) const;
00841     virtual void detect(const Mat& img, vector<Point>& foundLocations,
00842                         double hitThreshold=0, Size winStride=Size(),
00843                         Size padding=Size(),
00844                         const vector<Point>& searchLocations=vector<Point>()) const;
00845     virtual void detectMultiScale(const Mat& img, vector<Rect>& foundLocations,
00846                                   double hitThreshold=0, Size winStride=Size(),
00847                                   Size padding=Size(), double scale=1.05,
00848                                   int groupThreshold=2) const;
00849     virtual void computeGradient(const Mat& img, Mat& grad, Mat& angleOfs,
00850                                  Size paddingTL=Size(), Size paddingBR=Size()) const;
00851 
00852     static vector<float> getDefaultPeopleDetector();
00853 
00854     Size winSize;
00855     Size blockSize;
00856     Size blockStride;
00857     Size cellSize;
00858     int nbins;
00859     int derivAperture;
00860     double winSigma;
00861     int histogramNormType;
00862     double L2HysThreshold;
00863     bool gammaCorrection;
00864     vector<float> svmDetector;
00865 };
00866 
00867 
00868 class CV_EXPORTS SelfSimDescriptor
00869 {
00870 public:
00871     SelfSimDescriptor();
00872     SelfSimDescriptor(int _ssize, int _lsize,
00873         int _startDistanceBucket=DEFAULT_START_DISTANCE_BUCKET,
00874         int _numberOfDistanceBuckets=DEFAULT_NUM_DISTANCE_BUCKETS,
00875         int _nangles=DEFAULT_NUM_ANGLES);
00876     SelfSimDescriptor(const SelfSimDescriptor& ss);
00877     virtual ~SelfSimDescriptor();
00878     SelfSimDescriptor& operator = (const SelfSimDescriptor& ss);
00879 
00880     size_t getDescriptorSize() const;
00881     Size getGridSize( Size imgsize, Size winStride ) const;
00882 
00883     virtual void compute(const Mat& img, vector<float>& descriptors, Size winStride=Size(),
00884                          const vector<Point>& locations=vector<Point>()) const;
00885     virtual void computeLogPolarMapping(Mat& mappingMask) const;
00886     virtual void SSD(const Mat& img, Point pt, Mat& ssd) const;
00887 
00888     int smallSize;
00889     int largeSize;
00890     int startDistanceBucket;
00891     int numberOfDistanceBuckets;
00892     int numberOfAngles;
00893 
00894     enum { DEFAULT_SMALL_SIZE = 5, DEFAULT_LARGE_SIZE = 41,
00895         DEFAULT_NUM_ANGLES = 20, DEFAULT_START_DISTANCE_BUCKET = 3,
00896         DEFAULT_NUM_DISTANCE_BUCKETS = 7 };
00897 };
00898 
00899     
00900 class CV_EXPORTS PatchGenerator
00901 {
00902 public:
00903     PatchGenerator();
00904     PatchGenerator(double _backgroundMin, double _backgroundMax,
00905                    double _noiseRange, bool _randomBlur=true,
00906                    double _lambdaMin=0.6, double _lambdaMax=1.5,
00907                    double _thetaMin=-CV_PI, double _thetaMax=CV_PI,
00908                    double _phiMin=-CV_PI, double _phiMax=CV_PI );
00909     void operator()(const Mat& image, Point2f pt, Mat& patch, Size patchSize, RNG& rng) const;
00910     void operator()(const Mat& image, const Mat& transform, Mat& patch,
00911                     Size patchSize, RNG& rng) const;
00912     void warpWholeImage(const Mat& image, Mat& matT, Mat& buf,
00913                         Mat& warped, int border, RNG& rng) const;
00914     void generateRandomTransform(Point2f srcCenter, Point2f dstCenter,
00915                                  Mat& transform, RNG& rng, bool inverse=false) const;
00916     double backgroundMin, backgroundMax;
00917     double noiseRange;
00918     bool randomBlur;
00919     double lambdaMin, lambdaMax;
00920     double thetaMin, thetaMax;
00921     double phiMin, phiMax;
00922 };
00923 
00924     
00925 class CV_EXPORTS LDetector
00926 {
00927 public:    
00928     LDetector();
00929     LDetector(int _radius, int _threshold, int _nOctaves,
00930               int _nViews, double _baseFeatureSize, double _clusteringDistance);
00931     void operator()(const Mat& image, vector<KeyPoint>& keypoints, int maxCount=0, bool scaleCoords=true) const;
00932     void operator()(const vector<Mat>& pyr, vector<KeyPoint>& keypoints, int maxCount=0, bool scaleCoords=true) const;
00933     void getMostStable2D(const Mat& image, vector<KeyPoint>& keypoints,
00934                          int maxCount, const PatchGenerator& patchGenerator) const;
00935     void setVerbose(bool verbose);
00936     
00937     void read(const FileNode& node);
00938     void write(FileStorage& fs, const String& name=String()) const;
00939     
00940     int radius;
00941     int threshold;
00942     int nOctaves;
00943     int nViews;
00944     bool verbose;
00945     
00946     double baseFeatureSize;
00947     double clusteringDistance;
00948 };
00949 
00950 typedef LDetector YAPE;
00951 
00952 class CV_EXPORTS FernClassifier
00953 {
00954 public:
00955     FernClassifier();
00956     FernClassifier(const FileNode& node);
00957     FernClassifier(const vector<Point2f>& points,
00958                    const vector<Ptr<Mat> >& refimgs,
00959                    const vector<int>& labels=vector<int>(),
00960                    int _nclasses=0, int _patchSize=PATCH_SIZE,
00961                    int _signatureSize=DEFAULT_SIGNATURE_SIZE,
00962                    int _nstructs=DEFAULT_STRUCTS,
00963                    int _structSize=DEFAULT_STRUCT_SIZE,
00964                    int _nviews=DEFAULT_VIEWS,
00965                    int _compressionMethod=COMPRESSION_NONE,
00966                    const PatchGenerator& patchGenerator=PatchGenerator());
00967     virtual ~FernClassifier();
00968     virtual void read(const FileNode& n);
00969     virtual void write(FileStorage& fs, const String& name=String()) const;
00970     virtual void trainFromSingleView(const Mat& image,
00971                                      const vector<KeyPoint>& keypoints,
00972                                      int _patchSize=PATCH_SIZE,
00973                                      int _signatureSize=DEFAULT_SIGNATURE_SIZE,
00974                                      int _nstructs=DEFAULT_STRUCTS,
00975                                      int _structSize=DEFAULT_STRUCT_SIZE,
00976                                      int _nviews=DEFAULT_VIEWS,
00977                                      int _compressionMethod=COMPRESSION_NONE,
00978                                      const PatchGenerator& patchGenerator=PatchGenerator());
00979     virtual void train(const vector<Point2f>& points,
00980                        const vector<Ptr<Mat> >& refimgs,
00981                        const vector<int>& labels=vector<int>(),
00982                        int _nclasses=0, int _patchSize=PATCH_SIZE,
00983                        int _signatureSize=DEFAULT_SIGNATURE_SIZE,
00984                        int _nstructs=DEFAULT_STRUCTS,
00985                        int _structSize=DEFAULT_STRUCT_SIZE,
00986                        int _nviews=DEFAULT_VIEWS,
00987                        int _compressionMethod=COMPRESSION_NONE,
00988                        const PatchGenerator& patchGenerator=PatchGenerator());
00989     virtual int operator()(const Mat& img, Point2f kpt, vector<float>& signature) const;
00990     virtual int operator()(const Mat& patch, vector<float>& signature) const;
00991     virtual void clear();
00992     void setVerbose(bool verbose);
00993     
00994     int getClassCount() const;
00995     int getStructCount() const;
00996     int getStructSize() const;
00997     int getSignatureSize() const;
00998     int getCompressionMethod() const;
00999     Size getPatchSize() const;    
01000     
01001     struct Feature
01002     {
01003         uchar x1, y1, x2, y2;
01004         Feature() : x1(0), y1(0), x2(0), y2(0) {}
01005         Feature(int _x1, int _y1, int _x2, int _y2)
01006         : x1((uchar)_x1), y1((uchar)_y1), x2((uchar)_x2), y2((uchar)_y2)
01007         {}
01008         template<typename _Tp> bool operator ()(const Mat_<_Tp>& patch) const
01009         { return patch(y1,x1) > patch(y2, x2); }
01010     };
01011     
01012     enum
01013     {
01014         PATCH_SIZE = 31,
01015         DEFAULT_STRUCTS = 50,
01016         DEFAULT_STRUCT_SIZE = 9,
01017         DEFAULT_VIEWS = 5000,
01018         DEFAULT_SIGNATURE_SIZE = 176,
01019         COMPRESSION_NONE = 0,
01020         COMPRESSION_RANDOM_PROJ = 1,
01021         COMPRESSION_PCA = 2,
01022         DEFAULT_COMPRESSION_METHOD = COMPRESSION_NONE
01023     };
01024     
01025 protected:
01026     virtual void prepare(int _nclasses, int _patchSize, int _signatureSize,
01027                          int _nstructs, int _structSize,
01028                          int _nviews, int _compressionMethod);
01029     virtual void finalize(RNG& rng);
01030     virtual int getLeaf(int fidx, const Mat& patch) const;
01031     
01032     bool verbose;
01033     int nstructs;
01034     int structSize;
01035     int nclasses;
01036     int signatureSize;
01037     int compressionMethod;
01038     int leavesPerStruct;
01039     Size patchSize;
01040     vector<Feature> features;
01041     vector<int> classCounters;
01042     vector<float> posteriors;
01043 };
01044 
01045 class CV_EXPORTS PlanarObjectDetector
01046 {
01047 public:
01048     PlanarObjectDetector();
01049     PlanarObjectDetector(const FileNode& node);
01050     PlanarObjectDetector(const vector<Mat>& pyr, int _npoints=300,
01051                          int _patchSize=FernClassifier::PATCH_SIZE,
01052                          int _nstructs=FernClassifier::DEFAULT_STRUCTS,
01053                          int _structSize=FernClassifier::DEFAULT_STRUCT_SIZE,
01054                          int _nviews=FernClassifier::DEFAULT_VIEWS,
01055                          const LDetector& detector=LDetector(),
01056                          const PatchGenerator& patchGenerator=PatchGenerator()); 
01057     virtual ~PlanarObjectDetector();
01058     virtual void train(const vector<Mat>& pyr, int _npoints=300,
01059                        int _patchSize=FernClassifier::PATCH_SIZE,
01060                        int _nstructs=FernClassifier::DEFAULT_STRUCTS,
01061                        int _structSize=FernClassifier::DEFAULT_STRUCT_SIZE,
01062                        int _nviews=FernClassifier::DEFAULT_VIEWS,
01063                        const LDetector& detector=LDetector(),
01064                        const PatchGenerator& patchGenerator=PatchGenerator());
01065     virtual void train(const vector<Mat>& pyr, const vector<KeyPoint>& keypoints,
01066                        int _patchSize=FernClassifier::PATCH_SIZE,
01067                        int _nstructs=FernClassifier::DEFAULT_STRUCTS,
01068                        int _structSize=FernClassifier::DEFAULT_STRUCT_SIZE,
01069                        int _nviews=FernClassifier::DEFAULT_VIEWS,
01070                        const LDetector& detector=LDetector(),
01071                        const PatchGenerator& patchGenerator=PatchGenerator());
01072     Rect getModelROI() const;
01073     vector<KeyPoint> getModelPoints() const;
01074     const LDetector& getDetector() const;
01075     const FernClassifier& getClassifier() const;
01076     void setVerbose(bool verbose);
01077     
01078     void read(const FileNode& node);
01079     void write(FileStorage& fs, const String& name=String()) const;
01080     bool operator()(const Mat& image, Mat& H, vector<Point2f>& corners) const;
01081     bool operator()(const vector<Mat>& pyr, const vector<KeyPoint>& keypoints,
01082                     Mat& H, vector<Point2f>& corners, vector<int>* pairs=0) const;
01083     
01084 protected:
01085     bool verbose;
01086     Rect modelROI;
01087     vector<KeyPoint> modelPoints;
01088     LDetector ldetector;
01089     FernClassifier fernClassifier;
01090 };
01091 
01092 
01093 
01094 
01095 // detect corners using FAST algorithm
01096 CV_EXPORTS void FAST( const Mat& image, vector<KeyPoint>& keypoints, int threshold, bool nonmax_supression=true );
01097 
01098 
01099 class CV_EXPORTS LevMarqSparse
01100 {
01101 public:
01102     LevMarqSparse();
01103     LevMarqSparse(int npoints, // number of points
01104             int ncameras, // number of cameras
01105             int nPointParams, // number of params per one point  (3 in case of 3D points)
01106             int nCameraParams, // number of parameters per one camera
01107             int nErrParams, // number of parameters in measurement vector
01108                             // for 1 point at one camera (2 in case of 2D projections)
01109             Mat& visibility, // visibility matrix. rows correspond to points, columns correspond to cameras
01110                              // 1 - point is visible for the camera, 0 - invisible
01111             Mat& P0, // starting vector of parameters, first cameras then points
01112             Mat& X, // measurements, in order of visibility. non visible cases are skipped 
01113             TermCriteria criteria, // termination criteria
01114             
01115             // callback for estimation of Jacobian matrices
01116             void (CV_CDECL * fjac)(int i, int j, Mat& point_params,
01117                                    Mat& cam_params, Mat& A, Mat& B, void* data),
01118             // callback for estimation of backprojection errors
01119             void (CV_CDECL * func)(int i, int j, Mat& point_params,
01120                                    Mat& cam_params, Mat& estim, void* data),
01121             void* data // user-specific data passed to the callbacks
01122             );
01123     virtual ~LevMarqSparse();
01124     
01125     virtual void run( int npoints, // number of points
01126             int ncameras, // number of cameras
01127             int nPointParams, // number of params per one point  (3 in case of 3D points)
01128             int nCameraParams, // number of parameters per one camera
01129             int nErrParams, // number of parameters in measurement vector
01130                             // for 1 point at one camera (2 in case of 2D projections)
01131             Mat& visibility, // visibility matrix. rows correspond to points, columns correspond to cameras
01132                              // 1 - point is visible for the camera, 0 - invisible
01133             Mat& P0, // starting vector of parameters, first cameras then points
01134             Mat& X, // measurements, in order of visibility. non visible cases are skipped 
01135             TermCriteria criteria, // termination criteria
01136             
01137             // callback for estimation of Jacobian matrices
01138             void (CV_CDECL * fjac)(int i, int j, Mat& point_params,
01139                                    Mat& cam_params, Mat& A, Mat& B, void* data),
01140             // callback for estimation of backprojection errors
01141             void (CV_CDECL * func)(int i, int j, Mat& point_params,
01142                                    Mat& cam_params, Mat& estim, void* data),
01143             void* data // user-specific data passed to the callbacks
01144             );
01145 
01146     virtual void clear();
01147     
01148     // useful function to do simple bundle adjastment tasks
01149     static void bundleAdjust(vector<Point3d>& points, //positions of points in global coordinate system (input and output)
01150                              const vector<vector<Point2d> >& imagePoints, //projections of 3d points for every camera 
01151                              const vector<vector<int> >& visibility, //visibility of 3d points for every camera 
01152                              vector<Mat>& cameraMatrix, //intrinsic matrices of all cameras (input and output)
01153                              vector<Mat>& R, //rotation matrices of all cameras (input and output)
01154                              vector<Mat>& T, //translation vector of all cameras (input and output)
01155                              vector<Mat>& distCoeffs, //distortion coefficients of all cameras (input and output)
01156                              const TermCriteria& criteria=
01157                              TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, DBL_EPSILON));
01158     
01159 protected:
01160     virtual void optimize(); //main function that runs minimization
01161     
01162     //iteratively asks for measurement for visible camera-point pairs
01163     void ask_for_proj();                                        
01164     //iteratively asks for Jacobians for every camera_point pair
01165     void ask_for_projac();    
01166         
01167     CvMat* err; //error X-hX
01168     double prevErrNorm, errNorm;
01169     double lambda;
01170     CvTermCriteria criteria;
01171     int iters;
01172     
01173     CvMat** U; //size of array is equal to number of cameras
01174     CvMat** V; //size of array is equal to number of points
01175     CvMat** inv_V_star; //inverse of V*
01176 
01177     CvMat* A;
01178     CvMat* B;
01179     CvMat* W; 
01180 
01181     CvMat* X; //measurement 
01182     CvMat* hX; //current measurement extimation given new parameter vector 
01183     
01184     CvMat* prevP; //current already accepted parameter. 
01185     CvMat* P; // parameters used to evaluate function with new params
01186               // this parameters may be rejected 
01187     
01188     CvMat* deltaP; //computed increase of parameters (result of normal system solution )
01189 
01190     CvMat** ea; // sum_i  AijT * e_ij , used as right part of normal equation
01191                 // length of array is j = number of cameras  
01192     CvMat** eb; // sum_j  BijT * e_ij , used as right part of normal equation
01193                 // length of array is i = number of points
01194 
01195     CvMat** Yj; //length of array is i = num_points
01196 
01197     CvMat* S; //big matrix of block Sjk  , each block has size num_cam_params x num_cam_params 
01198 
01199     CvMat* JtJ_diag; //diagonal of JtJ,  used to backup diagonal elements before augmentation
01200 
01201     CvMat* Vis_index; // matrix which element is index of measurement for point i and camera j
01202                
01203     int num_cams;
01204     int num_points;
01205     int num_err_param;
01206     int num_cam_param;
01207     int num_point_param;
01208 
01209     //target function and jacobian pointers, which needs to be initialized 
01210     void (*fjac)(int i, int j, Mat& point_params, Mat& cam_params, Mat& A, Mat& B, void* data);
01211     void (*func)(int i, int j, Mat& point_params, Mat& cam_params, Mat& estim, void* data );
01212 
01213     void* data;
01214 };
01215 
01216 struct DefaultRngAuto
01217 {
01218     const static uint64 def_state = (uint64)-1;
01219     const uint64 old_state;
01220 
01221     DefaultRngAuto() : old_state(theRNG().state) { theRNG().state = def_state; }
01222     ~DefaultRngAuto() { theRNG().state = old_state; }   
01223 
01224     DefaultRngAuto& operator=(const DefaultRngAuto&);
01225 };
01226 
01227     /****************************************************************************************\
01228     *            Calonder Descriptor                                                         *
01229     \****************************************************************************************/
01233     typedef cv::RNG CalonderRng;
01234     typedef unsigned int int_type;
01235 
01236     //----------------------------
01237     //randomized_tree.h
01238 
01239     //class RTTester;
01240 
01241     //namespace features {
01242     static const size_t DEFAULT_REDUCED_NUM_DIM = 176;  
01243     static const float LOWER_QUANT_PERC = .03f;
01244     static const float UPPER_QUANT_PERC = .92f;
01245     static const int PATCH_SIZE = 32;
01246     static const int DEFAULT_DEPTH = 9;
01247     static const int DEFAULT_VIEWS = 5000;
01248     struct RTreeNode;
01249 
01250     struct BaseKeypoint
01251     {
01252         int x;
01253         int y;
01254         IplImage* image;
01255 
01256         BaseKeypoint()
01257             : x(0), y(0), image(NULL)
01258         {}
01259 
01260         BaseKeypoint(int x, int y, IplImage* image)
01261             : x(x), y(y), image(image)
01262         {}
01263     };
01264 
01265     class CSMatrixGenerator {
01266     public:
01267         typedef enum { PDT_GAUSS=1, PDT_BERNOULLI, PDT_DBFRIENDLY } PHI_DISTR_TYPE;
01268         ~CSMatrixGenerator();
01269         static float* getCSMatrix(int m, int n, PHI_DISTR_TYPE dt);     // do NOT free returned pointer   
01270 
01271 
01272     private:
01273         static float *cs_phi_;    // matrix for compressive sensing
01274         static int cs_phi_m_, cs_phi_n_;
01275     };
01276 
01277     class CV_EXPORTS RandomizedTree
01278     {  
01279     public:
01280         friend class RTreeClassifier;  
01281         //friend class ::RTTester;
01282 
01283 
01284         RandomizedTree();
01285         ~RandomizedTree();
01286 
01287         void train(std::vector<BaseKeypoint> const& base_set, cv::RNG &rng,
01288             int depth, int views, size_t reduced_num_dim, int num_quant_bits);
01289         void train(std::vector<BaseKeypoint> const& base_set, cv::RNG &rng,
01290             PatchGenerator &make_patch, int depth, int views, size_t reduced_num_dim,
01291             int num_quant_bits);
01292 
01293         // following two funcs are EXPERIMENTAL (do not use unless you know exactly what you do)
01294         static void quantizeVector(float *vec, int dim, int N, float bnds[2], int clamp_mode=0);
01295         static void quantizeVector(float *src, int dim, int N, float bnds[2], uchar *dst);  
01296 
01297         // patch_data must be a 32x32 array (no row padding)
01298         float* getPosterior(uchar* patch_data);
01299         const float* getPosterior(uchar* patch_data) const;
01300         uchar* getPosterior2(uchar* patch_data);
01301 
01302         void read(const char* file_name, int num_quant_bits);
01303         void read(std::istream &is, int num_quant_bits);
01304         void write(const char* file_name) const;
01305         void write(std::ostream &os) const;
01306 
01307         int classes() { return classes_; }
01308         int depth() { return depth_; }
01309 
01310         //void setKeepFloatPosteriors(bool b) { keep_float_posteriors_ = b; }
01311         void discardFloatPosteriors() { freePosteriors(1); }
01312 
01313         inline void applyQuantization(int num_quant_bits) { makePosteriors2(num_quant_bits); }
01314 
01315         // debug
01316         void savePosteriors(std::string url, bool append=false);
01317         void savePosteriors2(std::string url, bool append=false);
01318 
01319     private:
01320         int classes_;
01321         int depth_;
01322         int num_leaves_;  
01323         std::vector<RTreeNode> nodes_;  
01324         float **posteriors_;        // 16-bytes aligned posteriors
01325         uchar **posteriors2_;     // 16-bytes aligned posteriors
01326         std::vector<int> leaf_counts_;
01327 
01328         void createNodes(int num_nodes, cv::RNG &rng);
01329         void allocPosteriorsAligned(int num_leaves, int num_classes);
01330         void freePosteriors(int which);    // which: 1=posteriors_, 2=posteriors2_, 3=both
01331         void init(int classes, int depth, cv::RNG &rng);
01332         void addExample(int class_id, uchar* patch_data);
01333         void finalize(size_t reduced_num_dim, int num_quant_bits);  
01334         int getIndex(uchar* patch_data) const;
01335         inline float* getPosteriorByIndex(int index);
01336         inline uchar* getPosteriorByIndex2(int index);
01337         inline const float* getPosteriorByIndex(int index) const;
01338         //void makeRandomMeasMatrix(float *cs_phi, PHI_DISTR_TYPE dt, size_t reduced_num_dim);  
01339         void convertPosteriorsToChar();
01340         void makePosteriors2(int num_quant_bits);
01341         void compressLeaves(size_t reduced_num_dim);  
01342         void estimateQuantPercForPosteriors(float perc[2]);
01343     };
01344 
01345     struct RTreeNode
01346     {
01347         short offset1, offset2;
01348 
01349         RTreeNode() {}
01350 
01351         RTreeNode(uchar x1, uchar y1, uchar x2, uchar y2)
01352             : offset1(y1*PATCH_SIZE + x1),
01353             offset2(y2*PATCH_SIZE + x2)
01354         {}
01355 
01357         inline bool operator() (uchar* patch_data) const
01358         {
01359             return patch_data[offset1] > patch_data[offset2];
01360         }
01361     };
01362 
01363 
01364 
01365     //} // namespace features
01366     //----------------------------
01367     //rtree_classifier.h
01368     //class RTTester;
01369 
01370     //namespace features {
01371 
01372     class CV_EXPORTS RTreeClassifier
01373     {   
01374     public:
01375         //friend class ::RTTester;
01376         static const int DEFAULT_TREES = 48;
01377         static const size_t DEFAULT_NUM_QUANT_BITS = 4;  
01378 
01379         RTreeClassifier();
01380 
01381         //modified
01382         void train(std::vector<BaseKeypoint> const& base_set, 
01383             cv::RNG &rng,
01384             int num_trees = RTreeClassifier::DEFAULT_TREES,
01385             int depth = DEFAULT_DEPTH,
01386             int views = DEFAULT_VIEWS,
01387             size_t reduced_num_dim = DEFAULT_REDUCED_NUM_DIM,
01388             int num_quant_bits = DEFAULT_NUM_QUANT_BITS, bool print_status = true);
01389         void train(std::vector<BaseKeypoint> const& base_set,
01390             cv::RNG &rng, 
01391             PatchGenerator &make_patch,
01392             int num_trees = RTreeClassifier::DEFAULT_TREES,
01393             int depth = DEFAULT_DEPTH,
01394             int views = DEFAULT_VIEWS,
01395             size_t reduced_num_dim = DEFAULT_REDUCED_NUM_DIM,
01396             int num_quant_bits = DEFAULT_NUM_QUANT_BITS, bool print_status = true);
01397 
01398         // sig must point to a memory block of at least classes()*sizeof(float|uchar) bytes
01399         void getSignature(IplImage *patch, uchar *sig);
01400         void getSignature(IplImage *patch, float *sig);
01401         void getSparseSignature(IplImage *patch, float *sig, float thresh);
01402         // TODO: deprecated in favor of getSignature overload, remove
01403         void getFloatSignature(IplImage *patch, float *sig) { getSignature(patch, sig); }
01404 
01405         static int countNonZeroElements(float *vec, int n, double tol=1e-10);
01406         static inline void safeSignatureAlloc(uchar **sig, int num_sig=1, int sig_len=176);
01407         static inline uchar* safeSignatureAlloc(int num_sig=1, int sig_len=176);  
01408 
01409         inline int classes() { return classes_; }
01410         inline int original_num_classes() { return original_num_classes_; }
01411 
01412         void setQuantization(int num_quant_bits);
01413         void discardFloatPosteriors();
01414 
01415         void read(const char* file_name);
01416         void read(std::istream &is);
01417         void write(const char* file_name) const;
01418         void write(std::ostream &os) const;
01419 
01420         // experimental and debug
01421         void saveAllFloatPosteriors(std::string file_url);
01422         void saveAllBytePosteriors(std::string file_url);
01423         void setFloatPosteriorsFromTextfile_176(std::string url);
01424         float countZeroElements();
01425 
01426         std::vector<RandomizedTree> trees_;
01427 
01428     private:    
01429         int classes_;
01430         int num_quant_bits_;
01431         uchar **posteriors_;
01432         ushort *ptemp_;
01433         int original_num_classes_;  
01434         bool keep_floats_;
01435     };
01436     
01437 CV_EXPORTS bool find4QuadCornerSubpix(const Mat& img, std::vector<Point2f>& corners, Size region_size);
01438 
01439     
01440 class CV_EXPORTS BackgroundSubtractor
01441 {
01442 public:
01443     virtual ~BackgroundSubtractor();
01444     virtual void operator()(const Mat& image, Mat& fgmask, double learningRate=0);
01445 };
01446     
01447     
01448 class CV_EXPORTS BackgroundSubtractorMOG : public BackgroundSubtractor
01449 {
01450 public:
01451     BackgroundSubtractorMOG();
01452     BackgroundSubtractorMOG(int history, int nmixtures, double backgroundRatio, double noiseSigma=0);
01453     virtual ~BackgroundSubtractorMOG();
01454     virtual void operator()(const Mat& image, Mat& fgmask, double learningRate=0);
01455     
01456     virtual void initialize(Size frameSize, int frameType);
01457     
01458     Size frameSize;
01459     int frameType;
01460     Mat bgmodel;
01461     int nframes;
01462     int history;
01463     int nmixtures;
01464     double varThreshold;
01465     double backgroundRatio;
01466     double noiseSigma;
01467 };
01468  
01469 
01470 // CvAffinePose: defines a parameterized affine transformation of an image patch.
01471 // An image patch is rotated on angle phi (in degrees), then scaled lambda1 times
01472 // along horizontal and lambda2 times along vertical direction, and then rotated again
01473 // on angle (theta - phi).
01474 class CV_EXPORTS CvAffinePose
01475 {
01476 public:
01477     float phi;
01478     float theta;
01479     float lambda1;
01480     float lambda2;
01481 };
01482 
01483 
01484 class CV_EXPORTS OneWayDescriptor
01485 {
01486 public:
01487     OneWayDescriptor();
01488     ~OneWayDescriptor();
01489     
01490     // allocates memory for given descriptor parameters
01491     void Allocate(int pose_count, CvSize size, int nChannels);
01492     
01493     // GenerateSamples: generates affine transformed patches with averaging them over small transformation variations.
01494     // If external poses and transforms were specified, uses them instead of generating random ones
01495     // - pose_count: the number of poses to be generated
01496     // - frontal: the input patch (can be a roi in a larger image)
01497     // - norm: if nonzero, normalizes the output patch so that the sum of pixel intensities is 1
01498     void GenerateSamples(int pose_count, IplImage* frontal, int norm = 0);
01499     
01500     // GenerateSamplesFast: generates affine transformed patches with averaging them over small transformation variations.
01501     // Uses precalculated transformed pca components.
01502     // - frontal: the input patch (can be a roi in a larger image)
01503     // - pca_hr_avg: pca average vector
01504     // - pca_hr_eigenvectors: pca eigenvectors
01505     // - pca_descriptors: an array of precomputed descriptors of pca components containing their affine transformations
01506     //   pca_descriptors[0] corresponds to the average, pca_descriptors[1]-pca_descriptors[pca_dim] correspond to eigenvectors
01507     void GenerateSamplesFast(IplImage* frontal, CvMat* pca_hr_avg,
01508                              CvMat* pca_hr_eigenvectors, OneWayDescriptor* pca_descriptors);
01509     
01510     // sets the poses and corresponding transforms
01511     void SetTransforms(CvAffinePose* poses, CvMat** transforms);
01512     
01513     // Initialize: builds a descriptor.
01514     // - pose_count: the number of poses to build. If poses were set externally, uses them rather than generating random ones
01515     // - frontal: input patch. Can be a roi in a larger image
01516     // - feature_name: the feature name to be associated with the descriptor
01517     // - norm: if 1, the affine transformed patches are normalized so that their sum is 1
01518     void Initialize(int pose_count, IplImage* frontal, const char* feature_name = 0, int norm = 0);
01519     
01520     // InitializeFast: builds a descriptor using precomputed descriptors of pca components
01521     // - pose_count: the number of poses to build
01522     // - frontal: input patch. Can be a roi in a larger image
01523     // - feature_name: the feature name to be associated with the descriptor
01524     // - pca_hr_avg: average vector for PCA
01525     // - pca_hr_eigenvectors: PCA eigenvectors (one vector per row)
01526     // - pca_descriptors: precomputed descriptors of PCA components, the first descriptor for the average vector
01527     // followed by the descriptors for eigenvectors
01528     void InitializeFast(int pose_count, IplImage* frontal, const char* feature_name,
01529                         CvMat* pca_hr_avg, CvMat* pca_hr_eigenvectors, OneWayDescriptor* pca_descriptors);
01530     
01531     // ProjectPCASample: unwarps an image patch into a vector and projects it into PCA space
01532     // - patch: input image patch
01533     // - avg: PCA average vector
01534     // - eigenvectors: PCA eigenvectors, one per row
01535     // - pca_coeffs: output PCA coefficients
01536     void ProjectPCASample(IplImage* patch, CvMat* avg, CvMat* eigenvectors, CvMat* pca_coeffs) const;
01537     
01538     // InitializePCACoeffs: projects all warped patches into PCA space
01539     // - avg: PCA average vector
01540     // - eigenvectors: PCA eigenvectors, one per row
01541     void InitializePCACoeffs(CvMat* avg, CvMat* eigenvectors);
01542     
01543     // EstimatePose: finds the closest match between an input patch and a set of patches with different poses
01544     // - patch: input image patch
01545     // - pose_idx: the output index of the closest pose
01546     // - distance: the distance to the closest pose (L2 distance)
01547     void EstimatePose(IplImage* patch, int& pose_idx, float& distance) const;
01548     
01549     // EstimatePosePCA: finds the closest match between an input patch and a set of patches with different poses.
01550     // The distance between patches is computed in PCA space
01551     // - patch: input image patch
01552     // - pose_idx: the output index of the closest pose
01553     // - distance: distance to the closest pose (L2 distance in PCA space)
01554     // - avg: PCA average vector. If 0, matching without PCA is used
01555     // - eigenvectors: PCA eigenvectors, one per row
01556     void EstimatePosePCA(CvArr* patch, int& pose_idx, float& distance, CvMat* avg, CvMat* eigenvalues) const;
01557     
01558     // GetPatchSize: returns the size of each image patch after warping (2 times smaller than the input patch)
01559     CvSize GetPatchSize() const
01560     {
01561         return m_patch_size;
01562     }
01563     
01564     // GetInputPatchSize: returns the required size of the patch that the descriptor is built from
01565     // (2 time larger than the patch after warping)
01566     CvSize GetInputPatchSize() const
01567     {
01568         return cvSize(m_patch_size.width*2, m_patch_size.height*2);
01569     }
01570     
01571     // GetPatch: returns a patch corresponding to specified pose index
01572     // - index: pose index
01573     // - return value: the patch corresponding to specified pose index
01574     IplImage* GetPatch(int index);
01575     
01576     // GetPose: returns a pose corresponding to specified pose index
01577     // - index: pose index
01578     // - return value: the pose corresponding to specified pose index
01579     CvAffinePose GetPose(int index) const;
01580     
01581     // Save: saves all patches with different poses to a specified path
01582     void Save(const char* path);
01583     
01584     // ReadByName: reads a descriptor from a file storage
01585     // - fs: file storage
01586     // - parent: parent node
01587     // - name: node name
01588     // - return value: 1 if succeeded, 0 otherwise
01589     int ReadByName(CvFileStorage* fs, CvFileNode* parent, const char* name);
01590     
01591     // Write: writes a descriptor into a file storage
01592     // - fs: file storage
01593     // - name: node name
01594     void Write(CvFileStorage* fs, const char* name);
01595     
01596     // GetFeatureName: returns a name corresponding to a feature
01597     const char* GetFeatureName() const;
01598     
01599     // GetCenter: returns the center of the feature
01600     CvPoint GetCenter() const;
01601     
01602     void SetPCADimHigh(int pca_dim_high) {m_pca_dim_high = pca_dim_high;};
01603     void SetPCADimLow(int pca_dim_low) {m_pca_dim_low = pca_dim_low;};
01604     
01605     int GetPCADimLow() const;
01606     int GetPCADimHigh() const;
01607     
01608     CvMat** GetPCACoeffs() const {return m_pca_coeffs;}
01609     
01610 protected:
01611     int m_pose_count; // the number of poses
01612     CvSize m_patch_size; // size of each image
01613     IplImage** m_samples; // an array of length m_pose_count containing the patch in different poses
01614     IplImage* m_input_patch;
01615     IplImage* m_train_patch;
01616     CvMat** m_pca_coeffs; // an array of length m_pose_count containing pca decomposition of the patch in different poses
01617     CvAffinePose* m_affine_poses; // an array of poses
01618     CvMat** m_transforms; // an array of affine transforms corresponding to poses
01619     
01620     std::string m_feature_name; // the name of the feature associated with the descriptor
01621     CvPoint m_center; // the coordinates of the feature (the center of the input image ROI)
01622     
01623     int m_pca_dim_high; // the number of descriptor pca components to use for generating affine poses
01624     int m_pca_dim_low; // the number of pca components to use for comparison
01625 };
01626 
01627 
01628 // OneWayDescriptorBase: encapsulates functionality for training/loading a set of one way descriptors
01629 // and finding the nearest closest descriptor to an input feature
01630 class CV_EXPORTS OneWayDescriptorBase
01631 {
01632 public:
01633     
01634     // creates an instance of OneWayDescriptor from a set of training files
01635     // - patch_size: size of the input (large) patch
01636     // - pose_count: the number of poses to generate for each descriptor
01637     // - train_path: path to training files
01638     // - pca_config: the name of the file that contains PCA for small patches (2 times smaller
01639     // than patch_size each dimension
01640     // - pca_hr_config: the name of the file that contains PCA for large patches (of patch_size size)
01641     // - pca_desc_config: the name of the file that contains descriptors of PCA components
01642     OneWayDescriptorBase(CvSize patch_size, int pose_count, const char* train_path = 0, const char* pca_config = 0,
01643                          const char* pca_hr_config = 0, const char* pca_desc_config = 0, int pyr_levels = 1,
01644                          int pca_dim_high = 100, int pca_dim_low = 100);
01645     
01646     ~OneWayDescriptorBase();
01647     
01648     // Allocate: allocates memory for a given number of descriptors
01649     void Allocate(int train_feature_count);
01650     
01651     // AllocatePCADescriptors: allocates memory for pca descriptors
01652     void AllocatePCADescriptors();
01653     
01654     // returns patch size
01655     CvSize GetPatchSize() const {return m_patch_size;};
01656     // returns the number of poses for each descriptor
01657     int GetPoseCount() const {return m_pose_count;};
01658     
01659     // returns the number of pyramid levels
01660     int GetPyrLevels() const {return m_pyr_levels;};
01661     
01662     // returns the number of descriptors
01663     int GetDescriptorCount() const {return m_train_feature_count;};
01664     
01665     // CreateDescriptorsFromImage: creates descriptors for each of the input features
01666     // - src: input image
01667     // - features: input features
01668     // - pyr_levels: the number of pyramid levels
01669     void CreateDescriptorsFromImage(IplImage* src, const std::vector<cv::KeyPoint>& features);
01670     
01671     // CreatePCADescriptors: generates descriptors for PCA components, needed for fast generation of feature descriptors
01672     void CreatePCADescriptors();
01673     
01674     // returns a feature descriptor by feature index
01675     const OneWayDescriptor* GetDescriptor(int desc_idx) const {return &m_descriptors[desc_idx];};
01676     
01677     // FindDescriptor: finds the closest descriptor
01678     // - patch: input image patch
01679     // - desc_idx: output index of the closest descriptor to the input patch
01680     // - pose_idx: output index of the closest pose of the closest descriptor to the input patch
01681     // - distance: distance from the input patch to the closest feature pose
01682     // - _scales: scales of the input patch for each descriptor
01683     // - scale_ranges: input scales variation (float[2])
01684     void FindDescriptor(IplImage* patch, int& desc_idx, int& pose_idx, float& distance, float* _scale = 0, float* scale_ranges = 0) const;
01685     
01686     // - patch: input image patch
01687     // - n: number of the closest indexes
01688     // - desc_idxs: output indexes of the closest descriptor to the input patch (n)
01689     // - pose_idx: output indexes of the closest pose of the closest descriptor to the input patch (n)
01690     // - distances: distance from the input patch to the closest feature pose (n)
01691     // - _scales: scales of the input patch
01692     // - scale_ranges: input scales variation (float[2])
01693     void FindDescriptor(IplImage* patch, int n, std::vector<int>& desc_idxs, std::vector<int>& pose_idxs,
01694                         std::vector<float>& distances, std::vector<float>& _scales, float* scale_ranges = 0) const;
01695     
01696     // FindDescriptor: finds the closest descriptor
01697     // - src: input image
01698     // - pt: center of the feature
01699     // - desc_idx: output index of the closest descriptor to the input patch
01700     // - pose_idx: output index of the closest pose of the closest descriptor to the input patch
01701     // - distance: distance from the input patch to the closest feature pose
01702     void FindDescriptor(IplImage* src, cv::Point2f pt, int& desc_idx, int& pose_idx, float& distance) const;
01703     
01704     // InitializePoses: generates random poses
01705     void InitializePoses();
01706     
01707     // InitializeTransformsFromPoses: generates 2x3 affine matrices from poses (initializes m_transforms)
01708     void InitializeTransformsFromPoses();
01709     
01710     // InitializePoseTransforms: subsequently calls InitializePoses and InitializeTransformsFromPoses
01711     void InitializePoseTransforms();
01712     
01713     // InitializeDescriptor: initializes a descriptor
01714     // - desc_idx: descriptor index
01715     // - train_image: image patch (ROI is supported)
01716     // - feature_label: feature textual label
01717     void InitializeDescriptor(int desc_idx, IplImage* train_image, const char* feature_label);
01718     
01719     void InitializeDescriptor(int desc_idx, IplImage* train_image, const cv::KeyPoint& keypoint, const char* feature_label);
01720     
01721     // InitializeDescriptors: load features from an image and create descriptors for each of them
01722     void InitializeDescriptors(IplImage* train_image, const vector<cv::KeyPoint>& features,
01723                                const char* feature_label = "", int desc_start_idx = 0);
01724     
01725     // LoadPCADescriptors: loads PCA descriptors from a file
01726     // - filename: input filename
01727     int LoadPCADescriptors(const char* filename);
01728     
01729     // SavePCADescriptors: saves PCA descriptors to a file
01730     // - filename: output filename
01731     void SavePCADescriptors(const char* filename);
01732     
01733     // SetPCAHigh: sets the high resolution pca matrices (copied to internal structures)
01734     void SetPCAHigh(CvMat* avg, CvMat* eigenvectors);
01735     
01736     // SetPCALow: sets the low resolution pca matrices (copied to internal structures)
01737     void SetPCALow(CvMat* avg, CvMat* eigenvectors);
01738     
01739     int GetLowPCA(CvMat** avg, CvMat** eigenvectors)
01740     {
01741         *avg = m_pca_avg;
01742         *eigenvectors = m_pca_eigenvectors;
01743         return m_pca_dim_low;
01744     };
01745     
01746     void ConvertDescriptorsArrayToTree(); // Converting pca_descriptors array to KD tree
01747     
01748     
01749 protected:
01750     CvSize m_patch_size; // patch size
01751     int m_pose_count; // the number of poses for each descriptor
01752     int m_train_feature_count; // the number of the training features
01753     OneWayDescriptor* m_descriptors; // array of train feature descriptors
01754     CvMat* m_pca_avg; // PCA average Vector for small patches
01755     CvMat* m_pca_eigenvectors; // PCA eigenvectors for small patches
01756     CvMat* m_pca_hr_avg; // PCA average Vector for large patches
01757     CvMat* m_pca_hr_eigenvectors; // PCA eigenvectors for large patches
01758     OneWayDescriptor* m_pca_descriptors; // an array of PCA descriptors
01759     
01760     cv::flann::Index* m_pca_descriptors_tree;
01761     CvMat* m_pca_descriptors_matrix;
01762     
01763     CvAffinePose* m_poses; // array of poses
01764     CvMat** m_transforms; // array of affine transformations corresponding to poses
01765     
01766     int m_pca_dim_high;
01767     int m_pca_dim_low;
01768     
01769     int m_pyr_levels;
01770     
01771 };
01772 
01773 class OneWayDescriptorObject : public OneWayDescriptorBase
01774 {
01775 public:
01776     // creates an instance of OneWayDescriptorObject from a set of training files
01777     // - patch_size: size of the input (large) patch
01778     // - pose_count: the number of poses to generate for each descriptor
01779     // - train_path: path to training files
01780     // - pca_config: the name of the file that contains PCA for small patches (2 times smaller
01781     // than patch_size each dimension
01782     // - pca_hr_config: the name of the file that contains PCA for large patches (of patch_size size)
01783     // - pca_desc_config: the name of the file that contains descriptors of PCA components
01784     OneWayDescriptorObject(CvSize patch_size, int pose_count, const char* train_path, const char* pca_config,
01785                            const char* pca_hr_config = 0, const char* pca_desc_config = 0, int pyr_levels = 1);
01786     
01787     ~OneWayDescriptorObject();
01788     
01789     // Allocate: allocates memory for a given number of features
01790     // - train_feature_count: the total number of features
01791     // - object_feature_count: the number of features extracted from the object
01792     void Allocate(int train_feature_count, int object_feature_count);
01793     
01794     
01795     void SetLabeledFeatures(const vector<cv::KeyPoint>& features) {m_train_features = features;};
01796     vector<cv::KeyPoint>& GetLabeledFeatures() {return m_train_features;};
01797     const vector<cv::KeyPoint>& GetLabeledFeatures() const {return m_train_features;};
01798     vector<cv::KeyPoint> _GetLabeledFeatures() const;
01799     
01800     // IsDescriptorObject: returns 1 if descriptor with specified index is positive, otherwise 0
01801     int IsDescriptorObject(int desc_idx) const;
01802     
01803     // MatchPointToPart: returns the part number of a feature if it matches one of the object parts, otherwise -1
01804     int MatchPointToPart(CvPoint pt) const;
01805     
01806     // GetDescriptorPart: returns the part number of the feature corresponding to a specified descriptor
01807     // - desc_idx: descriptor index
01808     int GetDescriptorPart(int desc_idx) const;
01809     
01810     
01811     void InitializeObjectDescriptors(IplImage* train_image, const vector<cv::KeyPoint>& features,
01812                                      const char* feature_label, int desc_start_idx = 0, float scale = 1.0f,
01813                                      int is_background = 0);
01814     
01815     // GetObjectFeatureCount: returns the number of object features
01816     int GetObjectFeatureCount() const {return m_object_feature_count;};
01817     
01818 protected:
01819     int* m_part_id; // contains part id for each of object descriptors
01820     vector<cv::KeyPoint> m_train_features; // train features
01821     int m_object_feature_count; // the number of the positive features
01822     
01823 };
01824     
01825 
01826 }
01827 
01828 #endif /* __cplusplus */
01829 
01830 #endif /* __CVAUX_HPP__ */
01831 
01832 /* End of file. */