1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
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.
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
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.
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.
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.
42 #ifndef __OPENCV_AUX_HPP__
43 #define __OPENCV_AUX_HPP__
49 class CV_EXPORTS CvImage
52 CvImage() : image(0), refcount(0) {}
53 CvImage( CvSize size, int depth, int channels )
55 image = cvCreateImage( size, depth, channels );
56 refcount = image ? new int(1) : 0;
59 CvImage( IplImage* img ) : image(img)
61 refcount = image ? new int(1) : 0;
64 CvImage( const CvImage& img ) : image(img.image), refcount(img.refcount)
66 if( refcount ) ++(*refcount);
69 CvImage( const char* filename, const char* imgname=0, int color=-1 ) : image(0), refcount(0)
70 { load( filename, imgname, color ); }
72 CvImage( CvFileStorage* fs, const char* mapname, const char* imgname ) : image(0), refcount(0)
73 { read( fs, mapname, imgname ); }
75 CvImage( CvFileStorage* fs, const char* seqname, int idx ) : image(0), refcount(0)
76 { read( fs, seqname, idx ); }
80 if( refcount && !(--*refcount) )
82 cvReleaseImage( &image );
87 CvImage clone() { return CvImage(image ? cvCloneImage(image) : 0); }
89 void create( CvSize size, int depth, int channels )
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 ));
97 void release() { detach(); }
98 void clear() { detach(); }
100 void attach( IplImage* img, bool use_refcount=true )
102 if( refcount && --*refcount == 0 )
104 cvReleaseImage( &image );
108 refcount = use_refcount && image ? new int(1) : 0;
113 if( refcount && --*refcount == 0 )
115 cvReleaseImage( &image );
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 );
128 void show( const char* window_name );
129 bool is_valid() { return image != 0; }
131 int width() const { return image ? image->width : 0; }
132 int height() const { return image ? image->height : 0; }
134 CvSize size() const { return image ? cvSize(image->width, image->height) : cvSize(0,0); }
136 CvSize roi_size() const
138 return !image ? cvSize(0,0) :
139 !image->roi ? cvSize(image->width,image->height) :
140 cvSize(image->roi->width, image->roi->height);
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);
151 int coi() const { return !image || !image->roi ? 0 : image->roi->coi; }
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; }
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; }
165 uchar* roi_row(int y)
170 y<image->roi->height : y<image->height);
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);
179 const uchar* roi_row(int y) const
184 y<image->roi->height : y<image->height);
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);
193 operator const IplImage* () const { return image; }
194 operator IplImage* () { return image; }
196 CvImage& operator = (const CvImage& img)
200 if( refcount && !(--*refcount) )
201 cvReleaseImage( &image );
203 refcount=img.refcount;
213 class CV_EXPORTS CvMatrix
216 CvMatrix() : matrix(0) {}
217 CvMatrix( int rows, int cols, int type )
218 { matrix = cvCreateMat( rows, cols, type ); }
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 ); }
224 CvMatrix( int rows, int cols, int type, CvMemStorage* storage, bool alloc_data=true );
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 ); }
233 CvMatrix( const CvMatrix& m )
239 CvMatrix( const char* filename, const char* matname=0, int color=-1 ) : matrix(0)
240 { load( filename, matname, color ); }
242 CvMatrix( CvFileStorage* fs, const char* mapname, const char* matname ) : matrix(0)
243 { read( fs, mapname, matname ); }
245 CvMatrix( CvFileStorage* fs, const char* seqname, int idx ) : matrix(0)
246 { read( fs, seqname, idx ); }
253 CvMatrix clone() { return CvMatrix(matrix ? cvCloneMat(matrix) : 0); }
255 void set( CvMat* m, bool add_ref )
263 void create( int rows, int cols, int type )
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 );
275 if( matrix->hdr_refcount )
276 ++matrix->hdr_refcount;
277 else if( matrix->refcount )
286 if( matrix->hdr_refcount )
288 if( --matrix->hdr_refcount == 0 )
289 cvReleaseMat( &matrix );
291 else if( matrix->refcount )
293 if( --*matrix->refcount == 0 )
294 cvFree( &matrix->refcount );
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 );
311 void show( const char* window_name );
313 bool is_valid() { return matrix != 0; }
315 int rows() const { return matrix ? matrix->rows : 0; }
316 int cols() const { return matrix ? matrix->cols : 0; }
320 return !matrix ? cvSize(0,0) : cvSize(matrix->rows,matrix->cols);
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; }
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; }
332 void set_data( void* data, int step=CV_AUTOSTEP )
333 { cvSetData( matrix, data, step ); }
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; }
339 operator const CvMat* () const { return matrix; }
340 operator CvMat* () { return matrix; }
342 CvMatrix& operator = (const CvMatrix& _m)
354 /****************************************************************************************\
356 \****************************************************************************************/
358 class CV_EXPORTS CvCamShiftTracker
363 virtual ~CvCamShiftTracker();
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; }
377 /*********************** Tracking parameters ************************/
378 int get_threshold() const // thresholding value that applied to back project
379 { return m_threshold; }
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; }
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]; }
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]; }
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; }
394 bool set_threshold( int threshold ) // threshold applied to the histogram bins
395 { m_threshold = threshold; return true; }
397 bool set_hist_bin_range( int dim, int min_val, int max_val );
399 bool set_hist_dims( int c_dims, int* dims );// set the histogram parameters
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; }
406 /************************ The processing methods *********************************/
407 // update object position
408 virtual bool track_object( const IplImage* cur_frame );
410 // update object histogram
411 virtual bool update_histogram( const IplImage* cur_frame );
414 virtual void reset_histogram();
416 /************************ Retrieving internal data *******************************/
417 // get back project image
418 virtual IplImage* get_back_project()
419 { return m_back_project; }
421 float query( int* bin ) const
422 { return m_hist ? (float)cvGetRealND(m_hist->bins, bin) : 0.f; }
426 // internal method for color conversion: fills m_color_planes group
427 virtual void color_transform( const IplImage* img );
432 CvConnectedComp m_comp;
434 float m_hist_ranges_data[CV_MAX_DIM][2];
435 float* m_hist_ranges[CV_MAX_DIM];
437 int m_min_ch_val[CV_MAX_DIM];
438 int m_max_ch_val[CV_MAX_DIM];
441 IplImage* m_color_planes[CV_MAX_DIM];
442 IplImage* m_back_project;
447 /****************************************************************************************\
448 * Adaptive Skin Detector *
449 \****************************************************************************************/
451 class CV_EXPORTS CvAdaptiveSkinDetector
457 GSD_INTENSITY_LT = 15,
458 GSD_INTENSITY_UT = 250
461 class CV_EXPORTS Histogram
465 HistogramSize = (GSD_HUE_UT - GSD_HUE_LT + 1)
469 int findCoverageIndex(double surfaceToCover, int defaultValue = 0);
472 CvHistogram *fHistogram;
474 virtual ~Histogram();
476 void findCurveThresholds(int &x1, int &x2, double percent = 0.05);
477 void mergeWith(Histogram *source, double weight);
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;
487 void initData(IplImage *src, int widthDivider, int heightDivider);
488 void adaptiveFilter();
493 MORPHING_METHOD_NONE = 0,
494 MORPHING_METHOD_ERODE = 1,
495 MORPHING_METHOD_ERODE_ERODE = 2,
496 MORPHING_METHOD_ERODE_DILATE = 3
499 CvAdaptiveSkinDetector(int samplingDivider = 1, int morphingMethod = MORPHING_METHOD_NONE);
500 virtual ~CvAdaptiveSkinDetector();
502 virtual void process(IplImage *inputBGRImage, IplImage *outputHueMask);
506 /****************************************************************************************\
507 * Fuzzy MeanShift Tracker *
508 \****************************************************************************************/
510 class CV_EXPORTS CvFuzzyPoint {
514 CvFuzzyPoint(double _x, double _y);
517 class CV_EXPORTS CvFuzzyCurve {
519 std::vector<CvFuzzyPoint> points;
520 double value, centre;
522 bool between(double x, double x1, double x2);
528 void setCentre(double _centre);
531 void addPoint(double x, double y);
532 double calcValue(double param);
534 void setValue(double _value);
537 class CV_EXPORTS CvFuzzyFunction {
539 std::vector<CvFuzzyCurve> curves;
543 void addCurve(CvFuzzyCurve *curve, double value = 0);
546 CvFuzzyCurve *newCurve();
549 class CV_EXPORTS CvFuzzyRule {
551 CvFuzzyCurve *fuzzyInput1, *fuzzyInput2;
552 CvFuzzyCurve *fuzzyOutput;
556 void setRule(CvFuzzyCurve *c1, CvFuzzyCurve *c2, CvFuzzyCurve *o1);
557 double calcValue(double param1, double param2);
558 CvFuzzyCurve *getOutputCurve();
561 class CV_EXPORTS CvFuzzyController {
563 std::vector<CvFuzzyRule*> rules;
566 ~CvFuzzyController();
567 void addRule(CvFuzzyCurve *c1, CvFuzzyCurve *c2, CvFuzzyCurve *o1);
568 double calcOutput(double param1, double param2);
571 class CV_EXPORTS CvFuzzyMeanShiftTracker
577 CvFuzzyFunction iInput, iOutput;
578 CvFuzzyController fuzzyController;
581 int calcOutput(double edgeDensity, double density);
587 FuzzyResizer *fuzzyResizer;
589 int width, height, maxWidth, maxHeight, ellipseHeight, ellipseWidth;
590 int ldx, ldy, ldw, ldh, numShifts, numIters;
592 long m00, m01, m10, m11, m02, m20;
595 unsigned int depthLow, depthHigh;
596 int verticalEdgeLeft, verticalEdgeRight, horizontalEdgeTop, horizontalEdgeBottom;
600 void setSize(int _x, int _y, int _width, int _height);
601 void initDepthValues(IplImage *maskImage, IplImage *depthMap);
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);
621 rmEdgeDensityLinear = 0,
622 rmEdgeDensityFuzzy = 1,
636 MaxMeanShiftIteration = 5,
637 MaxSetSizeIteration = 5
640 void findOptimumSearchWindow(SearchWindow &searchWindow, IplImage *maskImage, IplImage *depthMap, int maxIteration, int resizeMethod, bool initDepth);
643 CvFuzzyMeanShiftTracker();
644 ~CvFuzzyMeanShiftTracker();
646 void track(IplImage *maskImage, IplImage *depthMap, int resizeMethod, bool resetSearch, int minKernelMass = MinKernelMass);
653 class CV_EXPORTS Octree
660 float x_min, x_max, y_min, y_max, z_min, z_max;
667 Octree( const vector<Point3f>& points, int maxLevels = 10, int minPoints = 20 );
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; }
676 vector<Point3f> points;
679 virtual void buildNext(size_t node_ind);
683 class CV_EXPORTS Mesh3D
686 struct EmptyMeshException {};
689 Mesh3D(const vector<Point3f>& vtx);
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);
698 void writeAsVrml(const String& file, const vector<Scalar>& colors = vector<Scalar>()) const;
701 vector<Point3f> normals;
705 const static Point3f allzero;
708 class CV_EXPORTS SpinImageModel
712 /* model parameters, leave unset for default or auto estimate */
722 float T_GeometriccConsistency;
723 float T_GroupingCorespondances;
725 /* public interface */
727 explicit SpinImageModel(const Mesh3D& mesh);
730 void setLogger(std::ostream* log);
731 void selectRandomSubset(float ratio);
732 void setSubset(const vector<int>& subset);
735 void match(const SpinImageModel& scene, vector< vector<Vec2i> >& result);
737 Mat packRandomScaledSpins(bool separateScale = false, size_t xCount = 10, size_t yCount = 10) const;
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]]; }
744 const Mesh3D& getMesh() const { return mesh; }
745 Mesh3D& getMesh() { return mesh; }
747 /* static utility functions */
748 static bool spinCorrelation(const Mat& spin1, const Mat& spin2, float lambda, float& result);
750 static Point2f calcSpinMapCoo(const Point3f& point, const Point3f& vertex, const Point3f& normal);
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);
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,
763 void defaultParams();
765 void matchSpinToModel(const Mat& spin, vector<int>& indeces,
766 vector<float>& corrCoeffs, bool useExtremeOutliers = true) const;
768 void repackSpinImages(const vector<uchar>& mask, Mat& spinImages, bool reAlloc = true) const;
776 class CV_EXPORTS TickMeter
783 int64 getTimeTicks() const;
784 double getTimeMicro() const;
785 double getTimeMilli() const;
786 double getTimeSec() const;
787 int64 getCounter() const;
796 CV_EXPORTS std::ostream& operator<<(std::ostream& out, const TickMeter& tm);
798 /****************************************************************************************\
799 * HOG (Histogram-of-Oriented-Gradients) Descriptor and Object Detector *
800 \****************************************************************************************/
802 struct CV_EXPORTS HOGDescriptor
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)
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)
821 HOGDescriptor(const String& filename)
826 virtual ~HOGDescriptor() {}
828 size_t getDescriptorSize() const;
829 bool checkDetectorSize() const;
830 double getWinSigma() const;
832 virtual void setSVMDetector(const vector<float>& _svmdetector);
834 virtual bool load(const String& filename, const String& objname=String());
835 virtual void save(const String& filename, const String& objname=String()) const;
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(),
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;
852 static vector<float> getDefaultPeopleDetector();
861 int histogramNormType;
862 double L2HysThreshold;
863 bool gammaCorrection;
864 vector<float> svmDetector;
868 class CV_EXPORTS 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);
880 size_t getDescriptorSize() const;
881 Size getGridSize( Size imgsize, Size winStride ) const;
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;
890 int startDistanceBucket;
891 int numberOfDistanceBuckets;
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 };
900 class CV_EXPORTS 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;
919 double lambdaMin, lambdaMax;
920 double thetaMin, thetaMax;
921 double phiMin, phiMax;
925 class CV_EXPORTS 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);
937 void read(const FileNode& node);
938 void write(FileStorage& fs, const String& name=String()) const;
946 double baseFeatureSize;
947 double clusteringDistance;
950 typedef LDetector YAPE;
952 class CV_EXPORTS 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);
994 int getClassCount() const;
995 int getStructCount() const;
996 int getStructSize() const;
997 int getSignatureSize() const;
998 int getCompressionMethod() const;
999 Size getPatchSize() const;
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)
1008 template<typename _Tp> bool operator ()(const Mat_<_Tp>& patch) const
1009 { return patch(y1,x1) > patch(y2, x2); }
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
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;
1037 int compressionMethod;
1038 int leavesPerStruct;
1040 vector<Feature> features;
1041 vector<int> classCounters;
1042 vector<float> posteriors;
1045 class CV_EXPORTS PlanarObjectDetector
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);
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;
1087 vector<KeyPoint> modelPoints;
1088 LDetector ldetector;
1089 FernClassifier fernClassifier;
1095 // detect corners using FAST algorithm
1096 CV_EXPORTS void FAST( const Mat& image, vector<KeyPoint>& keypoints, int threshold, bool nonmax_supression=true );
1099 class CV_EXPORTS 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
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
1123 virtual ~LevMarqSparse();
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
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
1146 virtual void clear();
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));
1160 virtual void optimize(); //main function that runs minimization
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();
1167 CvMat* err; //error X-hX
1168 double prevErrNorm, errNorm;
1170 CvTermCriteria criteria;
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*
1181 CvMat* X; //measurement
1182 CvMat* hX; //current measurement extimation given new parameter vector
1184 CvMat* prevP; //current already accepted parameter.
1185 CvMat* P; // parameters used to evaluate function with new params
1186 // this parameters may be rejected
1188 CvMat* deltaP; //computed increase of parameters (result of normal system solution )
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
1195 CvMat** Yj; //length of array is i = num_points
1197 CvMat* S; //big matrix of block Sjk , each block has size num_cam_params x num_cam_params
1199 CvMat* JtJ_diag; //diagonal of JtJ, used to backup diagonal elements before augmentation
1201 CvMat* Vis_index; // matrix which element is index of measurement for point i and camera j
1207 int num_point_param;
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 );
1216 struct DefaultRngAuto
1218 const static uint64 def_state = (uint64)-1;
1219 const uint64 old_state;
1221 DefaultRngAuto() : old_state(theRNG().state) { theRNG().state = def_state; }
1222 ~DefaultRngAuto() { theRNG().state = old_state; }
1224 DefaultRngAuto& operator=(const DefaultRngAuto&);
1227 /****************************************************************************************\
1228 * Calonder Descriptor *
1229 \****************************************************************************************/
1231 A pseudo-random number generator usable with std::random_shuffle.
1233 typedef cv::RNG CalonderRng;
1234 typedef unsigned int int_type;
1236 //----------------------------
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;
1257 : x(0), y(0), image(NULL)
1260 BaseKeypoint(int x, int y, IplImage* image)
1261 : x(x), y(y), image(image)
1265 class CSMatrixGenerator {
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
1273 static float *cs_phi_; // matrix for compressive sensing
1274 static int cs_phi_m_, cs_phi_n_;
1277 class CV_EXPORTS RandomizedTree
1280 friend class RTreeClassifier;
1281 //friend class ::RTTester;
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);
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);
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);
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;
1307 int classes() { return classes_; }
1308 int depth() { return depth_; }
1310 //void setKeepFloatPosteriors(bool b) { keep_float_posteriors_ = b; }
1311 void discardFloatPosteriors() { freePosteriors(1); }
1313 inline void applyQuantization(int num_quant_bits) { makePosteriors2(num_quant_bits); }
1316 void savePosteriors(std::string url, bool append=false);
1317 void savePosteriors2(std::string url, bool append=false);
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_;
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]);
1347 short offset1, offset2;
1351 RTreeNode(uchar x1, uchar y1, uchar x2, uchar y2)
1352 : offset1(y1*PATCH_SIZE + x1),
1353 offset2(y2*PATCH_SIZE + x2)
1356 //! Left child on 0, right child on 1
1357 inline bool operator() (uchar* patch_data) const
1359 return patch_data[offset1] > patch_data[offset2];
1365 //} // namespace features
1366 //----------------------------
1367 //rtree_classifier.h
1370 //namespace features {
1372 class CV_EXPORTS RTreeClassifier
1375 //friend class ::RTTester;
1376 static const int DEFAULT_TREES = 48;
1377 static const size_t DEFAULT_NUM_QUANT_BITS = 4;
1382 void train(std::vector<BaseKeypoint> const& base_set,
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,
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);
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); }
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);
1409 inline int classes() { return classes_; }
1410 inline int original_num_classes() { return original_num_classes_; }
1412 void setQuantization(int num_quant_bits);
1413 void discardFloatPosteriors();
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;
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();
1426 std::vector<RandomizedTree> trees_;
1430 int num_quant_bits_;
1431 uchar **posteriors_;
1433 int original_num_classes_;
1437 CV_EXPORTS bool find4QuadCornerSubpix(const Mat& img, std::vector<Point2f>& corners, Size region_size);
1440 class CV_EXPORTS BackgroundSubtractor
1443 virtual ~BackgroundSubtractor();
1444 virtual void operator()(const Mat& image, Mat& fgmask, double learningRate=0);
1448 class CV_EXPORTS BackgroundSubtractorMOG : public BackgroundSubtractor
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);
1456 virtual void initialize(Size frameSize, int frameType);
1464 double varThreshold;
1465 double backgroundRatio;
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).
1483 class CV_EXPORTS OneWayDescriptor
1487 ~OneWayDescriptor();
1489 // allocates memory for given descriptor parameters
1490 void Allocate(int pose_count, CvSize size, int nChannels);
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);
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);
1509 // sets the poses and corresponding transforms
1510 void SetTransforms(CvAffinePose* poses, CvMat** transforms);
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);
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);
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;
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);
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;
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;
1557 // GetPatchSize: returns the size of each image patch after warping (2 times smaller than the input patch)
1558 CvSize GetPatchSize() const
1560 return m_patch_size;
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
1567 return cvSize(m_patch_size.width*2, m_patch_size.height*2);
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);
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;
1580 // Save: saves all patches with different poses to a specified path
1581 void Save(const char* path);
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);
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);
1595 // GetFeatureName: returns a name corresponding to a feature
1596 const char* GetFeatureName() const;
1598 // GetCenter: returns the center of the feature
1599 CvPoint GetCenter() const;
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;};
1604 int GetPCADimLow() const;
1605 int GetPCADimHigh() const;
1607 CvMat** GetPCACoeffs() const {return m_pca_coeffs;}
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
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)
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
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
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);
1645 ~OneWayDescriptorBase();
1647 // Allocate: allocates memory for a given number of descriptors
1648 void Allocate(int train_feature_count);
1650 // AllocatePCADescriptors: allocates memory for pca descriptors
1651 void AllocatePCADescriptors();
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;};
1658 // returns the number of pyramid levels
1659 int GetPyrLevels() const {return m_pyr_levels;};
1661 // returns the number of descriptors
1662 int GetDescriptorCount() const {return m_train_feature_count;};
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);
1670 // CreatePCADescriptors: generates descriptors for PCA components, needed for fast generation of feature descriptors
1671 void CreatePCADescriptors();
1673 // returns a feature descriptor by feature index
1674 const OneWayDescriptor* GetDescriptor(int desc_idx) const {return &m_descriptors[desc_idx];};
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;
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;
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;
1703 // InitializePoses: generates random poses
1704 void InitializePoses();
1706 // InitializeTransformsFromPoses: generates 2x3 affine matrices from poses (initializes m_transforms)
1707 void InitializeTransformsFromPoses();
1709 // InitializePoseTransforms: subsequently calls InitializePoses and InitializeTransformsFromPoses
1710 void InitializePoseTransforms();
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);
1718 void InitializeDescriptor(int desc_idx, IplImage* train_image, const cv::KeyPoint& keypoint, const char* feature_label);
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);
1724 // LoadPCADescriptors: loads PCA descriptors from a file
1725 // - filename: input filename
1726 int LoadPCADescriptors(const char* filename);
1728 // SavePCADescriptors: saves PCA descriptors to a file
1729 // - filename: output filename
1730 void SavePCADescriptors(const char* filename);
1732 // SetPCAHigh: sets the high resolution pca matrices (copied to internal structures)
1733 void SetPCAHigh(CvMat* avg, CvMat* eigenvectors);
1735 // SetPCALow: sets the low resolution pca matrices (copied to internal structures)
1736 void SetPCALow(CvMat* avg, CvMat* eigenvectors);
1738 int GetLowPCA(CvMat** avg, CvMat** eigenvectors)
1741 *eigenvectors = m_pca_eigenvectors;
1742 return m_pca_dim_low;
1745 void ConvertDescriptorsArrayToTree(); // Converting pca_descriptors array to KD tree
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
1759 cv::flann::Index* m_pca_descriptors_tree;
1760 CvMat* m_pca_descriptors_matrix;
1762 CvAffinePose* m_poses; // array of poses
1763 CvMat** m_transforms; // array of affine transformations corresponding to poses
1772 class OneWayDescriptorObject : public OneWayDescriptorBase
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);
1786 ~OneWayDescriptorObject();
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);
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;
1799 // IsDescriptorObject: returns 1 if descriptor with specified index is positive, otherwise 0
1800 int IsDescriptorObject(int desc_idx) const;
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;
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;
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);
1814 // GetObjectFeatureCount: returns the number of object features
1815 int GetObjectFeatureCount() const {return m_object_feature_count;};
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
1827 #endif /* __cplusplus */
1829 #endif /* __CVAUX_HPP__ */