-/*M///////////////////////////////////////////////////////////////////////////////////////\r
-//\r
-// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.\r
-//\r
-// By downloading, copying, installing or using the software you agree to this license.\r
-// If you do not agree to this license, do not download, install,\r
-// copy or use the software.\r
-//\r
-//\r
-// Intel License Agreement\r
-// For Open Source Computer Vision Library\r
-//\r
-// Copyright (C) 2000, Intel Corporation, all rights reserved.\r
-// Third party copyrights are property of their respective owners.\r
-//\r
-// Redistribution and use in source and binary forms, with or without modification,\r
-// are permitted provided that the following conditions are met:\r
-//\r
-// * Redistribution's of source code must retain the above copyright notice,\r
-// this list of conditions and the following disclaimer.\r
-//\r
-// * Redistribution's in binary form must reproduce the above copyright notice,\r
-// this list of conditions and the following disclaimer in the documentation\r
-// and/or other materials provided with the distribution.\r
-//\r
-// * The name of Intel Corporation may not be used to endorse or promote products\r
-// derived from this software without specific prior written permission.\r
-//\r
-// This software is provided by the copyright holders and contributors "as is" and\r
-// any express or implied warranties, including, but not limited to, the implied\r
-// warranties of merchantability and fitness for a particular purpose are disclaimed.\r
-// In no event shall the Intel Corporation or contributors be liable for any direct,\r
-// indirect, incidental, special, exemplary, or consequential damages\r
-// (including, but not limited to, procurement of substitute goods or services;\r
-// loss of use, data, or profits; or business interruption) however caused\r
-// and on any theory of liability, whether in contract, strict liability,\r
-// or tort (including negligence or otherwise) arising in any way out of\r
-// the use of this software, even if advised of the possibility of such damage.\r
-//\r
-//M*/\r
-\r
-#ifndef __CVAUX_HPP__\r
-#define __CVAUX_HPP__\r
-\r
-#ifdef __cplusplus\r
-\r
-#include <iosfwd>\r
-\r
-/****************************************************************************************\\r
-* CamShiftTracker *\r
-\****************************************************************************************/\r
-\r
-class CV_EXPORTS CvCamShiftTracker\r
-{\r
-public:\r
-\r
- CvCamShiftTracker();\r
- virtual ~CvCamShiftTracker();\r
-\r
- /**** Characteristics of the object that are calculated by track_object method *****/\r
- float get_orientation() const // orientation of the object in degrees\r
- { return m_box.angle; }\r
- float get_length() const // the larger linear size of the object\r
- { return m_box.size.height; }\r
- float get_width() const // the smaller linear size of the object\r
- { return m_box.size.width; }\r
- CvPoint2D32f get_center() const // center of the object\r
- { return m_box.center; }\r
- CvRect get_window() const // bounding rectangle for the object\r
- { return m_comp.rect; }\r
-\r
- /*********************** Tracking parameters ************************/\r
- int get_threshold() const // thresholding value that applied to back project\r
- { return m_threshold; }\r
-\r
- int get_hist_dims( int* dims = 0 ) const // returns number of histogram dimensions and sets\r
- { return m_hist ? cvGetDims( m_hist->bins, dims ) : 0; }\r
-\r
- int get_min_ch_val( int channel ) const // get the minimum allowed value of the specified channel\r
- { return m_min_ch_val[channel]; }\r
-\r
- int get_max_ch_val( int channel ) const // get the maximum allowed value of the specified channel\r
- { return m_max_ch_val[channel]; }\r
-\r
- // set initial object rectangle (must be called before initial calculation of the histogram)\r
- bool set_window( CvRect window)\r
- { m_comp.rect = window; return true; }\r
-\r
- bool set_threshold( int threshold ) // threshold applied to the histogram bins\r
- { m_threshold = threshold; return true; }\r
-\r
- bool set_hist_bin_range( int dim, int min_val, int max_val );\r
-\r
- bool set_hist_dims( int c_dims, int* dims );// set the histogram parameters\r
-\r
- bool set_min_ch_val( int channel, int val ) // set the minimum allowed value of the specified channel\r
- { m_min_ch_val[channel] = val; return true; }\r
- bool set_max_ch_val( int channel, int val ) // set the maximum allowed value of the specified channel\r
- { m_max_ch_val[channel] = val; return true; }\r
-\r
- /************************ The processing methods *********************************/\r
- // update object position\r
- virtual bool track_object( const IplImage* cur_frame );\r
-\r
- // update object histogram\r
- virtual bool update_histogram( const IplImage* cur_frame );\r
-\r
- // reset histogram\r
- virtual void reset_histogram();\r
-\r
- /************************ Retrieving internal data *******************************/\r
- // get back project image\r
- virtual IplImage* get_back_project()\r
- { return m_back_project; }\r
-\r
- float query( int* bin ) const\r
- { return m_hist ? (float)cvGetRealND(m_hist->bins, bin) : 0.f; }\r
-\r
-protected:\r
-\r
- // internal method for color conversion: fills m_color_planes group\r
- virtual void color_transform( const IplImage* img );\r
-\r
- CvHistogram* m_hist;\r
-\r
- CvBox2D m_box;\r
- CvConnectedComp m_comp;\r
-\r
- float m_hist_ranges_data[CV_MAX_DIM][2];\r
- float* m_hist_ranges[CV_MAX_DIM];\r
-\r
- int m_min_ch_val[CV_MAX_DIM];\r
- int m_max_ch_val[CV_MAX_DIM];\r
- int m_threshold;\r
-\r
- IplImage* m_color_planes[CV_MAX_DIM];\r
- IplImage* m_back_project;\r
- IplImage* m_temp;\r
- IplImage* m_mask;\r
-};\r
-\r
-/****************************************************************************************\\r
-* Adaptive Skin Detector *\r
-\****************************************************************************************/\r
-\r
-class CV_EXPORTS CvAdaptiveSkinDetector\r
-{\r
-private:\r
- enum {\r
- GSD_HUE_LT = 3,\r
- GSD_HUE_UT = 33,\r
- GSD_INTENSITY_LT = 15,\r
- GSD_INTENSITY_UT = 250\r
- };\r
-\r
- class CV_EXPORTS Histogram\r
- {\r
- private:\r
- enum {\r
- HistogramSize = (GSD_HUE_UT - GSD_HUE_LT + 1)\r
- };\r
-\r
- protected:\r
- int findCoverageIndex(double surfaceToCover, int defaultValue = 0);\r
-\r
- public:\r
- CvHistogram *fHistogram;\r
- Histogram();\r
- virtual ~Histogram();\r
-\r
- void findCurveThresholds(int &x1, int &x2, double percent = 0.05);\r
- void mergeWith(Histogram *source, double weight);\r
- };\r
-\r
- int nStartCounter, nFrameCount, nSkinHueLowerBound, nSkinHueUpperBound, nMorphingMethod, nSamplingDivider;\r
- double fHistogramMergeFactor, fHuePercentCovered;\r
- Histogram histogramHueMotion, skinHueHistogram;\r
- IplImage *imgHueFrame, *imgSaturationFrame, *imgLastGrayFrame, *imgMotionFrame, *imgFilteredFrame;\r
- IplImage *imgShrinked, *imgTemp, *imgGrayFrame, *imgHSVFrame;\r
-\r
-protected:\r
- void initData(IplImage *src, int widthDivider, int heightDivider);\r
- void adaptiveFilter();\r
-\r
-public:\r
-\r
- enum {\r
- MORPHING_METHOD_NONE = 0,\r
- MORPHING_METHOD_ERODE = 1,\r
- MORPHING_METHOD_ERODE_ERODE = 2,\r
- MORPHING_METHOD_ERODE_DILATE = 3\r
- };\r
-\r
- CvAdaptiveSkinDetector(int samplingDivider = 1, int morphingMethod = MORPHING_METHOD_NONE);\r
- virtual ~CvAdaptiveSkinDetector();\r
-\r
- virtual void process(IplImage *inputBGRImage, IplImage *outputHueMask);\r
-};\r
-\r
-\r
-/****************************************************************************************\\r
-* Fuzzy MeanShift Tracker *\r
-\****************************************************************************************/\r
-\r
-class CV_EXPORTS CvFuzzyPoint {\r
-public:\r
- double x, y, value;\r
-\r
- CvFuzzyPoint(double _x, double _y);\r
-};\r
-\r
-class CV_EXPORTS CvFuzzyCurve {\r
-private:\r
- std::vector<CvFuzzyPoint> points;\r
- double value, centre;\r
-\r
- bool between(double x, double x1, double x2);\r
-\r
-public:\r
- CvFuzzyCurve();\r
- ~CvFuzzyCurve();\r
-\r
- void setCentre(double _centre);\r
- double getCentre();\r
- void clear();\r
- void addPoint(double x, double y);\r
- double calcValue(double param);\r
- double getValue();\r
- void setValue(double _value);\r
-};\r
-\r
-class CV_EXPORTS CvFuzzyFunction {\r
-public:\r
- std::vector<CvFuzzyCurve> curves;\r
-\r
- CvFuzzyFunction();\r
- ~CvFuzzyFunction();\r
- void addCurve(CvFuzzyCurve *curve, double value = 0);\r
- void resetValues();\r
- double calcValue();\r
- CvFuzzyCurve *newCurve();\r
-};\r
-\r
-class CV_EXPORTS CvFuzzyRule {\r
-private:\r
- CvFuzzyCurve *fuzzyInput1, *fuzzyInput2;\r
- CvFuzzyCurve *fuzzyOutput;\r
-public:\r
- CvFuzzyRule();\r
- ~CvFuzzyRule();\r
- void setRule(CvFuzzyCurve *c1, CvFuzzyCurve *c2, CvFuzzyCurve *o1);\r
- double calcValue(double param1, double param2);\r
- CvFuzzyCurve *getOutputCurve();\r
-};\r
-\r
-class CV_EXPORTS CvFuzzyController {\r
-private:\r
- std::vector<CvFuzzyRule*> rules;\r
-public:\r
- CvFuzzyController();\r
- ~CvFuzzyController();\r
- void addRule(CvFuzzyCurve *c1, CvFuzzyCurve *c2, CvFuzzyCurve *o1);\r
- double calcOutput(double param1, double param2);\r
-};\r
-\r
-class CV_EXPORTS CvFuzzyMeanShiftTracker\r
-{\r
-private:\r
- class FuzzyResizer\r
- {\r
- private:\r
- CvFuzzyFunction iInput, iOutput;\r
- CvFuzzyController fuzzyController;\r
- public:\r
- FuzzyResizer();\r
- int calcOutput(double edgeDensity, double density);\r
- };\r
-\r
- class SearchWindow\r
- {\r
- public:\r
- FuzzyResizer *fuzzyResizer;\r
- int x, y;\r
- int width, height, maxWidth, maxHeight, ellipseHeight, ellipseWidth;\r
- int ldx, ldy, ldw, ldh, numShifts, numIters;\r
- int xGc, yGc;\r
- long m00, m01, m10, m11, m02, m20;\r
- double ellipseAngle;\r
- double density;\r
- unsigned int depthLow, depthHigh;\r
- int verticalEdgeLeft, verticalEdgeRight, horizontalEdgeTop, horizontalEdgeBottom;\r
-\r
- SearchWindow();\r
- ~SearchWindow();\r
- void setSize(int _x, int _y, int _width, int _height);\r
- void initDepthValues(IplImage *maskImage, IplImage *depthMap);\r
- bool shift();\r
- void extractInfo(IplImage *maskImage, IplImage *depthMap, bool initDepth);\r
- void getResizeAttribsEdgeDensityLinear(int &resizeDx, int &resizeDy, int &resizeDw, int &resizeDh);\r
- void getResizeAttribsInnerDensity(int &resizeDx, int &resizeDy, int &resizeDw, int &resizeDh);\r
- void getResizeAttribsEdgeDensityFuzzy(int &resizeDx, int &resizeDy, int &resizeDw, int &resizeDh);\r
- bool meanShift(IplImage *maskImage, IplImage *depthMap, int maxIteration, bool initDepth);\r
- };\r
-\r
-public:\r
- enum TrackingState\r
- {\r
- tsNone = 0,\r
- tsSearching = 1,\r
- tsTracking = 2,\r
- tsSetWindow = 3,\r
- tsDisabled = 10\r
- };\r
-\r
- enum ResizeMethod {\r
- rmEdgeDensityLinear = 0,\r
- rmEdgeDensityFuzzy = 1,\r
- rmInnerDensity = 2\r
- };\r
-\r
- enum {\r
- MinKernelMass = 1000\r
- };\r
-\r
- SearchWindow kernel;\r
- int searchMode;\r
-\r
-private:\r
- enum\r
- {\r
- MaxMeanShiftIteration = 5,\r
- MaxSetSizeIteration = 5\r
- };\r
-\r
- void findOptimumSearchWindow(SearchWindow &searchWindow, IplImage *maskImage, IplImage *depthMap, int maxIteration, int resizeMethod, bool initDepth);\r
-\r
-public:\r
- CvFuzzyMeanShiftTracker();\r
- ~CvFuzzyMeanShiftTracker();\r
-\r
- void track(IplImage *maskImage, IplImage *depthMap, int resizeMethod, bool resetSearch, int minKernelMass = MinKernelMass);\r
-};\r
-\r
-\r
-namespace cv\r
-{\r
-\r
-class CV_EXPORTS Octree\r
-{\r
-public: \r
- struct Node\r
- {\r
- Node() {}\r
- int begin, end;\r
- float x_min, x_max, y_min, y_max, z_min, z_max; \r
- int maxLevels;\r
- bool isLeaf;\r
- int children[8];\r
- };\r
-\r
- Octree();\r
- Octree( const vector<Point3f>& points, int maxLevels = 10, int minPoints = 20 );\r
- virtual ~Octree();\r
-\r
- virtual void buildTree( const vector<Point3f>& points, int maxLevels = 10, int minPoints = 20 );\r
- virtual void getPointsWithinSphere( const Point3f& center, float radius,\r
- vector<Point3f>& points ) const;\r
- const vector<Node>& getNodes() const { return nodes; }\r
-private:\r
- int minPoints;\r
- vector<Point3f> points;\r
- vector<Node> nodes;\r
- \r
- virtual void buildNext(size_t node_ind);\r
-};\r
-\r
-\r
-class CV_EXPORTS Mesh3D\r
-{\r
-public:\r
- struct EmptyMeshException {};\r
-\r
- Mesh3D();\r
- Mesh3D(const vector<Point3f>& vtx);\r
- ~Mesh3D();\r
-\r
- void buildOctree();\r
- void clearOctree();\r
- float estimateResolution(float tryRatio = 0.1f); \r
- void computeNormals(float normalRadius, int minNeighbors = 20);\r
- void computeNormals(const vector<int>& subset, float normalRadius, int minNeighbors = 20);\r
- \r
- void writeAsVrml(const String& file, const vector<Scalar>& colors = vector<Scalar>()) const;\r
- \r
- vector<Point3f> vtx;\r
- vector<Point3f> normals;\r
- float resolution; \r
- Octree octree;\r
-\r
- const static Point3f allzero;\r
-};\r
-\r
-class CV_EXPORTS SpinImageModel\r
-{\r
-public:\r
- \r
- /* model parameters, leave unset for default or auto estimate */\r
- float normalRadius;\r
- int minNeighbors;\r
-\r
- float binSize;\r
- int imageWidth;\r
-\r
- float lambda; \r
- float gamma;\r
-\r
- float T_GeometriccConsistency;\r
- float T_GroupingCorespondances;\r
-\r
- /* public interface */\r
- SpinImageModel();\r
- explicit SpinImageModel(const Mesh3D& mesh);\r
- ~SpinImageModel();\r
-\r
- void setLogger(std::ostream* log);\r
- void selectRandomSubset(float ratio); \r
- void setSubset(const vector<int>& subset); \r
- void compute();\r
-\r
- void match(const SpinImageModel& scene, vector< vector<Vec2i> >& result); \r
-\r
- Mat packRandomScaledSpins(bool separateScale = false, size_t xCount = 10, size_t yCount = 10) const;\r
- \r
- size_t getSpinCount() const { return spinImages.rows; }\r
- Mat getSpinImage(size_t index) const { return spinImages.row(index); }\r
- const Point3f& getSpinVertex(size_t index) const { return mesh.vtx[subset[index]]; }\r
- const Point3f& getSpinNormal(size_t index) const { return mesh.normals[subset[index]]; }\r
-\r
- const Mesh3D& getMesh() const { return mesh; }\r
- Mesh3D& getMesh() { return mesh; }\r
-\r
- /* static utility functions */\r
- static bool spinCorrelation(const Mat& spin1, const Mat& spin2, float lambda, float& result);\r
-\r
- static Point2f calcSpinMapCoo(const Point3f& point, const Point3f& vertex, const Point3f& normal);\r
-\r
- static float geometricConsistency(const Point3f& pointScene1, const Point3f& normalScene1,\r
- const Point3f& pointModel1, const Point3f& normalModel1, \r
- const Point3f& pointScene2, const Point3f& normalScene2, \r
- const Point3f& pointModel2, const Point3f& normalModel2);\r
-\r
- static float groupingCreteria(const Point3f& pointScene1, const Point3f& normalScene1,\r
- const Point3f& pointModel1, const Point3f& normalModel1,\r
- const Point3f& pointScene2, const Point3f& normalScene2, \r
- const Point3f& pointModel2, const Point3f& normalModel2, \r
- float gamma);\r
-protected: \r
- void defaultParams();\r
-\r
- void matchSpinToModel(const Mat& spin, vector<int>& indeces, \r
- vector<float>& corrCoeffs, bool useExtremeOutliers = true) const; \r
-\r
- void repackSpinImages(const vector<uchar>& mask, Mat& spinImages, bool reAlloc = true) const;\r
- \r
- vector<int> subset;\r
- Mesh3D mesh;\r
- Mat spinImages;\r
- std::ostream* out;\r
-};\r
-\r
-class CV_EXPORTS TickMeter\r
-{\r
-public:\r
- TickMeter();\r
- void start(); \r
- void stop();\r
-\r
- int64 getTimeTicks() const;\r
- double getTimeMicro() const;\r
- double getTimeMilli() const;\r
- double getTimeSec() const;\r
- int64 getCounter() const;\r
-\r
- void reset();\r
-private:\r
- int64 counter;\r
- int64 sumTime;\r
- int64 startTime;\r
-};\r
-\r
-CV_EXPORTS std::ostream& operator<<(std::ostream& out, const TickMeter& tm);\r
-\r
-/****************************************************************************************\\r
-* HOG (Histogram-of-Oriented-Gradients) Descriptor and Object Detector *\r
-\****************************************************************************************/\r
-\r
-struct CV_EXPORTS HOGDescriptor\r
-{\r
-public:\r
- enum { L2Hys=0 };\r
-\r
- HOGDescriptor() : winSize(64,128), blockSize(16,16), blockStride(8,8),\r
- cellSize(8,8), nbins(9), derivAperture(1), winSigma(-1),\r
- histogramNormType(L2Hys), L2HysThreshold(0.2), gammaCorrection(true)\r
- {}\r
-\r
- HOGDescriptor(Size _winSize, Size _blockSize, Size _blockStride,\r
- Size _cellSize, int _nbins, int _derivAperture=1, double _winSigma=-1,\r
- int _histogramNormType=L2Hys, double _L2HysThreshold=0.2, bool _gammaCorrection=false)\r
- : winSize(_winSize), blockSize(_blockSize), blockStride(_blockStride), cellSize(_cellSize),\r
- nbins(_nbins), derivAperture(_derivAperture), winSigma(_winSigma),\r
- histogramNormType(_histogramNormType), L2HysThreshold(_L2HysThreshold),\r
- gammaCorrection(_gammaCorrection)\r
- {}\r
-\r
- HOGDescriptor(const String& filename)\r
- {\r
- load(filename);\r
- }\r
-\r
- virtual ~HOGDescriptor() {}\r
-\r
- size_t getDescriptorSize() const;\r
- bool checkDetectorSize() const;\r
- double getWinSigma() const;\r
-\r
- virtual void setSVMDetector(const vector<float>& _svmdetector);\r
-\r
- virtual bool load(const String& filename, const String& objname=String());\r
- virtual void save(const String& filename, const String& objname=String()) const;\r
-\r
- virtual void compute(const Mat& img,\r
- vector<float>& descriptors,\r
- Size winStride=Size(), Size padding=Size(),\r
- const vector<Point>& locations=vector<Point>()) const;\r
- virtual void detect(const Mat& img, vector<Point>& foundLocations,\r
- double hitThreshold=0, Size winStride=Size(),\r
- Size padding=Size(),\r
- const vector<Point>& searchLocations=vector<Point>()) const;\r
- virtual void detectMultiScale(const Mat& img, vector<Rect>& foundLocations,\r
- double hitThreshold=0, Size winStride=Size(),\r
- Size padding=Size(), double scale=1.05,\r
- int groupThreshold=2) const;\r
- virtual void computeGradient(const Mat& img, Mat& grad, Mat& angleOfs,\r
- Size paddingTL=Size(), Size paddingBR=Size()) const;\r
-\r
- static vector<float> getDefaultPeopleDetector();\r
-\r
- Size winSize;\r
- Size blockSize;\r
- Size blockStride;\r
- Size cellSize;\r
- int nbins;\r
- int derivAperture;\r
- double winSigma;\r
- int histogramNormType;\r
- double L2HysThreshold;\r
- bool gammaCorrection;\r
- vector<float> svmDetector;\r
-};\r
-\r
-\r
-class CV_EXPORTS SelfSimDescriptor\r
-{\r
-public:\r
- SelfSimDescriptor();\r
- SelfSimDescriptor(int _ssize, int _lsize,\r
- int _startDistanceBucket=DEFAULT_START_DISTANCE_BUCKET,\r
- int _numberOfDistanceBuckets=DEFAULT_NUM_DISTANCE_BUCKETS,\r
- int _nangles=DEFAULT_NUM_ANGLES);\r
- SelfSimDescriptor(const SelfSimDescriptor& ss);\r
- virtual ~SelfSimDescriptor();\r
- SelfSimDescriptor& operator = (const SelfSimDescriptor& ss);\r
-\r
- size_t getDescriptorSize() const;\r
- Size getGridSize( Size imgsize, Size winStride ) const;\r
-\r
- virtual void compute(const Mat& img, vector<float>& descriptors, Size winStride=Size(),\r
- const vector<Point>& locations=vector<Point>()) const;\r
- virtual void computeLogPolarMapping(Mat& mappingMask) const;\r
- virtual void SSD(const Mat& img, Point pt, Mat& ssd) const;\r
-\r
- int smallSize;\r
- int largeSize;\r
- int startDistanceBucket;\r
- int numberOfDistanceBuckets;\r
- int numberOfAngles;\r
-\r
- enum { DEFAULT_SMALL_SIZE = 5, DEFAULT_LARGE_SIZE = 41,\r
- DEFAULT_NUM_ANGLES = 20, DEFAULT_START_DISTANCE_BUCKET = 3,\r
- DEFAULT_NUM_DISTANCE_BUCKETS = 7 };\r
-};\r
-\r
- \r
-class CV_EXPORTS PatchGenerator\r
-{\r
-public:\r
- PatchGenerator();\r
- PatchGenerator(double _backgroundMin, double _backgroundMax,\r
- double _noiseRange, bool _randomBlur=true,\r
- double _lambdaMin=0.6, double _lambdaMax=1.5,\r
- double _thetaMin=-CV_PI, double _thetaMax=CV_PI,\r
- double _phiMin=-CV_PI, double _phiMax=CV_PI );\r
- void operator()(const Mat& image, Point2f pt, Mat& patch, Size patchSize, RNG& rng) const;\r
- void operator()(const Mat& image, const Mat& transform, Mat& patch,\r
- Size patchSize, RNG& rng) const;\r
- void warpWholeImage(const Mat& image, Mat& _T, Mat& buf,\r
- Mat& warped, int border, RNG& rng) const;\r
- void generateRandomTransform(Point2f srcCenter, Point2f dstCenter,\r
- Mat& transform, RNG& rng, bool inverse=false) const;\r
- double backgroundMin, backgroundMax;\r
- double noiseRange;\r
- bool randomBlur;\r
- double lambdaMin, lambdaMax;\r
- double thetaMin, thetaMax;\r
- double phiMin, phiMax;\r
-};\r
-\r
-\r
-class CV_EXPORTS LDetector\r
-{\r
-public: \r
- LDetector();\r
- LDetector(int _radius, int _threshold, int _nOctaves,\r
- int _nViews, double _baseFeatureSize, double _clusteringDistance);\r
- void operator()(const Mat& image, vector<KeyPoint>& keypoints, int maxCount=0, bool scaleCoords=true) const;\r
- void operator()(const vector<Mat>& pyr, vector<KeyPoint>& keypoints, int maxCount=0, bool scaleCoords=true) const;\r
- void getMostStable2D(const Mat& image, vector<KeyPoint>& keypoints,\r
- int maxCount, const PatchGenerator& patchGenerator) const;\r
- void setVerbose(bool verbose);\r
- \r
- void read(const FileNode& node);\r
- void write(FileStorage& fs, const String& name=String()) const;\r
- \r
- int radius;\r
- int threshold;\r
- int nOctaves;\r
- int nViews;\r
- bool verbose;\r
- \r
- double baseFeatureSize;\r
- double clusteringDistance;\r
-};\r
-\r
-\r
-class CV_EXPORTS FernClassifier\r
-{\r
-public:\r
- FernClassifier();\r
- FernClassifier(const FileNode& node);\r
- FernClassifier(const vector<Point2f>& points,\r
- const vector<Ptr<Mat> >& refimgs,\r
- const vector<int>& labels=vector<int>(),\r
- int _nclasses=0, int _patchSize=PATCH_SIZE,\r
- int _signatureSize=DEFAULT_SIGNATURE_SIZE,\r
- int _nstructs=DEFAULT_STRUCTS,\r
- int _structSize=DEFAULT_STRUCT_SIZE,\r
- int _nviews=DEFAULT_VIEWS,\r
- int _compressionMethod=COMPRESSION_NONE,\r
- const PatchGenerator& patchGenerator=PatchGenerator());\r
- virtual ~FernClassifier();\r
- virtual void read(const FileNode& n);\r
- virtual void write(FileStorage& fs, const String& name=String()) const;\r
- virtual void trainFromSingleView(const Mat& image,\r
- const vector<KeyPoint>& keypoints,\r
- int _patchSize=PATCH_SIZE,\r
- int _signatureSize=DEFAULT_SIGNATURE_SIZE,\r
- int _nstructs=DEFAULT_STRUCTS,\r
- int _structSize=DEFAULT_STRUCT_SIZE,\r
- int _nviews=DEFAULT_VIEWS,\r
- int _compressionMethod=COMPRESSION_NONE,\r
- const PatchGenerator& patchGenerator=PatchGenerator());\r
- virtual void train(const vector<Point2f>& points,\r
- const vector<Ptr<Mat> >& refimgs,\r
- const vector<int>& labels=vector<int>(),\r
- int _nclasses=0, int _patchSize=PATCH_SIZE,\r
- int _signatureSize=DEFAULT_SIGNATURE_SIZE,\r
- int _nstructs=DEFAULT_STRUCTS,\r
- int _structSize=DEFAULT_STRUCT_SIZE,\r
- int _nviews=DEFAULT_VIEWS,\r
- int _compressionMethod=COMPRESSION_NONE,\r
- const PatchGenerator& patchGenerator=PatchGenerator());\r
- virtual int operator()(const Mat& img, Point2f kpt, vector<float>& signature) const;\r
- virtual int operator()(const Mat& patch, vector<float>& signature) const;\r
- virtual void clear();\r
- void setVerbose(bool verbose);\r
- \r
- int getClassCount() const;\r
- int getStructCount() const;\r
- int getStructSize() const;\r
- int getSignatureSize() const;\r
- int getCompressionMethod() const;\r
- Size getPatchSize() const; \r
- \r
- struct Feature\r
- {\r
- uchar x1, y1, x2, y2;\r
- Feature() : x1(0), y1(0), x2(0), y2(0) {}\r
- Feature(int _x1, int _y1, int _x2, int _y2)\r
- : x1((uchar)_x1), y1((uchar)_y1), x2((uchar)_x2), y2((uchar)_y2)\r
- {}\r
- template<typename _Tp> bool operator ()(const Mat_<_Tp>& patch) const\r
- { return patch(y1,x1) > patch(y2, x2); }\r
- };\r
- \r
- enum\r
- {\r
- PATCH_SIZE = 31,\r
- DEFAULT_STRUCTS = 50,\r
- DEFAULT_STRUCT_SIZE = 9,\r
- DEFAULT_VIEWS = 5000,\r
- DEFAULT_SIGNATURE_SIZE = 176,\r
- COMPRESSION_NONE = 0,\r
- COMPRESSION_RANDOM_PROJ = 1,\r
- COMPRESSION_PCA = 2,\r
- DEFAULT_COMPRESSION_METHOD = COMPRESSION_NONE\r
- };\r
- \r
-protected:\r
- virtual void prepare(int _nclasses, int _patchSize, int _signatureSize,\r
- int _nstructs, int _structSize,\r
- int _nviews, int _compressionMethod);\r
- virtual void finalize(RNG& rng);\r
- virtual int getLeaf(int fidx, const Mat& patch) const;\r
- \r
- bool verbose;\r
- int nstructs;\r
- int structSize;\r
- int nclasses;\r
- int signatureSize;\r
- int compressionMethod;\r
- int leavesPerStruct;\r
- Size patchSize;\r
- vector<Feature> features;\r
- vector<int> classCounters;\r
- vector<float> posteriors;\r
-};\r
-\r
-class CV_EXPORTS PlanarObjectDetector\r
-{\r
-public:\r
- PlanarObjectDetector();\r
- PlanarObjectDetector(const FileNode& node);\r
- PlanarObjectDetector(const vector<Mat>& pyr, int _npoints=300,\r
- int _patchSize=FernClassifier::PATCH_SIZE,\r
- int _nstructs=FernClassifier::DEFAULT_STRUCTS,\r
- int _structSize=FernClassifier::DEFAULT_STRUCT_SIZE,\r
- int _nviews=FernClassifier::DEFAULT_VIEWS,\r
- const LDetector& detector=LDetector(),\r
- const PatchGenerator& patchGenerator=PatchGenerator()); \r
- virtual ~PlanarObjectDetector();\r
- virtual void train(const vector<Mat>& pyr, int _npoints=300,\r
- int _patchSize=FernClassifier::PATCH_SIZE,\r
- int _nstructs=FernClassifier::DEFAULT_STRUCTS,\r
- int _structSize=FernClassifier::DEFAULT_STRUCT_SIZE,\r
- int _nviews=FernClassifier::DEFAULT_VIEWS,\r
- const LDetector& detector=LDetector(),\r
- const PatchGenerator& patchGenerator=PatchGenerator());\r
- virtual void train(const vector<Mat>& pyr, const vector<KeyPoint>& keypoints,\r
- int _patchSize=FernClassifier::PATCH_SIZE,\r
- int _nstructs=FernClassifier::DEFAULT_STRUCTS,\r
- int _structSize=FernClassifier::DEFAULT_STRUCT_SIZE,\r
- int _nviews=FernClassifier::DEFAULT_VIEWS,\r
- const LDetector& detector=LDetector(),\r
- const PatchGenerator& patchGenerator=PatchGenerator());\r
- Rect getModelROI() const;\r
- vector<KeyPoint> getModelPoints() const;\r
- const LDetector& getDetector() const;\r
- const FernClassifier& getClassifier() const;\r
- void setVerbose(bool verbose);\r
- \r
- void read(const FileNode& node);\r
- void write(FileStorage& fs, const String& name=String()) const;\r
- bool operator()(const Mat& image, Mat& H, vector<Point2f>& corners) const;\r
- bool operator()(const vector<Mat>& pyr, const vector<KeyPoint>& keypoints,\r
- Mat& H, vector<Point2f>& corners, vector<int>* pairs=0) const;\r
- \r
-protected:\r
- bool verbose;\r
- Rect modelROI;\r
- vector<KeyPoint> modelPoints;\r
- LDetector ldetector;\r
- FernClassifier fernClassifier;\r
-};\r
-\r
-\r
-//////////////////////////////////////////////////////////////////////////////////////////////////// \r
-// One-Way Descriptor //\r
-//////////////////////////////////////////////////////////////////////////////////////////////////// \r
-\r
-class AffinePose;\r
- \r
-// OneWayDescriptor: incapsulates a descriptor for a single point \r
-class CV_EXPORTS OneWayDescriptor\r
-{\r
-public:\r
- OneWayDescriptor();\r
- ~OneWayDescriptor();\r
- \r
- // allocates memory for given descriptor parameters\r
- void Allocate(int pose_count, Size size, int nChannels);\r
- \r
- // GenerateSamples: generates affine transformed patches with averaging them over small transformation variations.\r
- // If external poses and transforms were specified, uses them instead of generating random ones\r
- // - pose_count: the number of poses to be generated\r
- // - frontal: the input patch (can be a roi in a larger image)\r
- // - norm: if nonzero, normalizes the output patch so that the sum of pixel intensities is 1\r
- void GenerateSamples(int pose_count, IplImage* frontal, int norm = 0);\r
- \r
- // GenerateSamplesFast: generates affine transformed patches with averaging them over small transformation variations.\r
- // Uses precalculated transformed pca components.\r
- // - frontal: the input patch (can be a roi in a larger image)\r
- // - pca_hr_avg: pca average vector\r
- // - pca_hr_eigenvectors: pca eigenvectors\r
- // - pca_descriptors: an array of precomputed descriptors of pca components containing their affine transformations\r
- // pca_descriptors[0] corresponds to the average, pca_descriptors[1]-pca_descriptors[pca_dim] correspond to eigenvectors\r
- void GenerateSamplesFast(IplImage* frontal, CvMat* pca_hr_avg, \r
- CvMat* pca_hr_eigenvectors, OneWayDescriptor* pca_descriptors);\r
- \r
- // sets the poses and corresponding transforms\r
- void SetTransforms(AffinePose* poses, CvMat** transforms);\r
- \r
- // Initialize: builds a descriptor. \r
- // - pose_count: the number of poses to build. If poses were set externally, uses them rather than generating random ones\r
- // - frontal: input patch. Can be a roi in a larger image\r
- // - feature_name: the feature name to be associated with the descriptor\r
- // - norm: if 1, the affine transformed patches are normalized so that their sum is 1 \r
- void Initialize(int pose_count, IplImage* frontal, const char* feature_name = 0, int norm = 0);\r
- \r
- // InitializeFast: builds a descriptor using precomputed descriptors of pca components\r
- // - pose_count: the number of poses to build\r
- // - frontal: input patch. Can be a roi in a larger image\r
- // - feature_name: the feature name to be associated with the descriptor\r
- // - pca_hr_avg: average vector for PCA\r
- // - pca_hr_eigenvectors: PCA eigenvectors (one vector per row)\r
- // - pca_descriptors: precomputed descriptors of PCA components, the first descriptor for the average vector\r
- // followed by the descriptors for eigenvectors\r
- void InitializeFast(int pose_count, IplImage* frontal, const char* feature_name, \r
- CvMat* pca_hr_avg, CvMat* pca_hr_eigenvectors, OneWayDescriptor* pca_descriptors);\r
- \r
- // ProjectPCASample: unwarps an image patch into a vector and projects it into PCA space\r
- // - patch: input image patch\r
- // - avg: PCA average vector\r
- // - eigenvectors: PCA eigenvectors, one per row\r
- // - pca_coeffs: output PCA coefficients\r
- void ProjectPCASample(IplImage* patch, CvMat* avg, CvMat* eigenvectors, CvMat* pca_coeffs) const;\r
- \r
- // InitializePCACoeffs: projects all warped patches into PCA space\r
- // - avg: PCA average vector\r
- // - eigenvectors: PCA eigenvectors, one per row \r
- void InitializePCACoeffs(CvMat* avg, CvMat* eigenvectors);\r
- \r
- // EstimatePose: finds the closest match between an input patch and a set of patches with different poses\r
- // - patch: input image patch\r
- // - pose_idx: the output index of the closest pose\r
- // - distance: the distance to the closest pose (L2 distance)\r
- void EstimatePose(IplImage* patch, int& pose_idx, float& distance) const;\r
- \r
- // EstimatePosePCA: finds the closest match between an input patch and a set of patches with different poses. \r
- // The distance between patches is computed in PCA space\r
- // - patch: input image patch\r
- // - pose_idx: the output index of the closest pose\r
- // - distance: distance to the closest pose (L2 distance in PCA space)\r
- // - avg: PCA average vector. If 0, matching without PCA is used\r
- // - eigenvectors: PCA eigenvectors, one per row\r
- void EstimatePosePCA(IplImage* patch, int& pose_idx, float& distance, CvMat* avg, CvMat* eigenvalues) const;\r
- \r
- // GetPatchSize: returns the size of each image patch after warping (2 times smaller than the input patch) \r
- Size GetPatchSize() const\r
- {\r
- return m_patch_size;\r
- }\r
- \r
- // GetInputPatchSize: returns the required size of the patch that the descriptor is built from \r
- // (2 time larger than the patch after warping)\r
- Size GetInputPatchSize() const\r
- {\r
- return cvSize(m_patch_size.width*2, m_patch_size.height*2);\r
- }\r
- \r
- // GetPatch: returns a patch corresponding to specified pose index\r
- // - index: pose index\r
- // - return value: the patch corresponding to specified pose index\r
- IplImage* GetPatch(int index);\r
- \r
- // GetPose: returns a pose corresponding to specified pose index\r
- // - index: pose index\r
- // - return value: the pose corresponding to specified pose index\r
- AffinePose GetPose(int index) const;\r
- \r
- // Save: saves all patches with different poses to a specified path\r
- void Save(const char* path);\r
- \r
- // ReadByName: reads a descriptor from a file storage\r
- // - fs: file storage\r
- // - parent: parent node\r
- // - name: node name\r
- // - return value: 1 if succeeded, 0 otherwise\r
- int ReadByName(CvFileStorage* fs, CvFileNode* parent, const char* name);\r
- \r
- // Write: writes a descriptor into a file storage\r
- // - fs: file storage\r
- // - name: node name\r
- void Write(CvFileStorage* fs, const char* name);\r
- \r
- // GetFeatureName: returns a name corresponding to a feature\r
- const char* GetFeatureName() const;\r
- \r
- // GetCenter: returns the center of the feature\r
- Point GetCenter() const;\r
- \r
- void SetPCADimHigh(int pca_dim_high) {m_pca_dim_high = pca_dim_high;};\r
- void SetPCADimLow(int pca_dim_low) {m_pca_dim_low = pca_dim_low;};\r
- \r
-protected:\r
- int m_pose_count; // the number of poses\r
- Size m_patch_size; // size of each image\r
- IplImage** m_samples; // an array of length m_pose_count containing the patch in different poses \r
- CvMat** m_pca_coeffs; // an array of length m_pose_count containing pca decomposition of the patch in different poses\r
- AffinePose* m_affine_poses; // an array of poses\r
- CvMat** m_transforms; // an array of affine transforms corresponding to poses\r
- \r
- String m_feature_name; // the name of the feature associated with the descriptor\r
- Point m_center; // the coordinates of the feature (the center of the input image ROI)\r
- \r
- int m_pca_dim_high; // the number of descriptor pca components to use for generating affine poses\r
- int m_pca_dim_low; // the number of pca components to use for comparison\r
-};\r
-\r
-CV_EXPORTS void findOneWayDescriptor(int desc_count, const OneWayDescriptor* descriptors,\r
- IplImage* patch, int& desc_idx, int& pose_idx, float& distance, \r
- CvMat* avg = 0, CvMat* eigenvalues = 0);\r
-\r
-CV_EXPORTS void findOneWayDescriptor(int desc_count, const OneWayDescriptor* descriptors, IplImage* patch, \r
- float scale_min, float scale_max, float scale_step,\r
- int& desc_idx, int& pose_idx, float& distance, float& scale, \r
- CvMat* avg, CvMat* eigenvectors);\r
- \r
- \r
-// OneWayDescriptorBase: encapsulates functionality for training/loading a set of one way descriptors\r
-// and finding the nearest closest descriptor to an input feature\r
-class CV_EXPORTS OneWayDescriptorBase\r
-{\r
-public:\r
- \r
- // creates an instance of OneWayDescriptor from a set of training files\r
- // - patch_size: size of the input (large) patch\r
- // - pose_count: the number of poses to generate for each descriptor\r
- // - train_path: path to training files\r
- // - pca_config: the name of the file that contains PCA for small patches (2 times smaller\r
- // than patch_size each dimension\r
- // - pca_hr_config: the name of the file that contains PCA for large patches (of patch_size size)\r
- // - pca_desc_config: the name of the file that contains descriptors of PCA components\r
- OneWayDescriptorBase(Size patch_size, int pose_count, const char* train_path = 0, const char* pca_config = 0, \r
- const char* pca_hr_config = 0, const char* pca_desc_config = 0, int pyr_levels = 2, \r
- int pca_dim_high = 100, int pca_dim_low = 100);\r
- \r
- ~OneWayDescriptorBase();\r
- \r
- // Allocate: allocates memory for a given number of descriptors\r
- void Allocate(int train_feature_count);\r
- \r
- // AllocatePCADescriptors: allocates memory for pca descriptors\r
- void AllocatePCADescriptors();\r
- \r
- // returns patch size\r
- Size GetPatchSize() const {return m_patch_size;};\r
- // returns the number of poses for each descriptor\r
- int GetPoseCount() const {return m_pose_count;};\r
- \r
- // returns the number of pyramid levels\r
- int GetPyrLevels() const {return m_pyr_levels;};\r
- \r
- // CreateDescriptorsFromImage: creates descriptors for each of the input features\r
- // - src: input image\r
- // - features: input features\r
- // - pyr_levels: the number of pyramid levels\r
- void CreateDescriptorsFromImage(IplImage* src, const vector<KeyPoint>& features);\r
- \r
- // CreatePCADescriptors: generates descriptors for PCA components, needed for fast generation of feature descriptors\r
- void CreatePCADescriptors();\r
- \r
- // returns a feature descriptor by feature index\r
- const OneWayDescriptor* GetDescriptor(int desc_idx) const;\r
- \r
- // FindDescriptor: finds the closest descriptor\r
- // - patch: input image patch\r
- // - desc_idx: output index of the closest descriptor to the input patch\r
- // - pose_idx: output index of the closest pose of the closest descriptor to the input patch\r
- // - distance: distance from the input patch to the closest feature pose\r
- void FindDescriptor(IplImage* patch, int& desc_idx, int& pose_idx, float& distance) const;\r
- \r
- // FindDescriptor: finds the closest descriptor\r
- // - src: input image \r
- // - pt: center of the feature\r
- // - desc_idx: output index of the closest descriptor to the input patch\r
- // - pose_idx: output index of the closest pose of the closest descriptor to the input patch\r
- // - distance: distance from the input patch to the closest feature pose\r
- void FindDescriptor(IplImage* src, Point2f pt, int& desc_idx, int& pose_idx, float& distance) const;\r
- \r
- // InitializePoses: generates random poses\r
- void InitializePoses();\r
- \r
- // InitializeTransformsFromPoses: generates 2x3 affine matrices from poses (initializes m_transforms)\r
- void InitializeTransformsFromPoses();\r
- \r
- // InitializePoseTransforms: subsequently calls InitializePoses and InitializeTransformsFromPoses\r
- void InitializePoseTransforms();\r
- \r
- // InitializeDescriptor: initializes a descriptor\r
- // - desc_idx: descriptor index\r
- // - train_image: image patch (ROI is supported)\r
- // - feature_label: feature textual label\r
- void InitializeDescriptor(int desc_idx, IplImage* train_image, const char* feature_label);\r
- \r
- // InitializeDescriptors: load features from an image and create descriptors for each of them \r
- void InitializeDescriptors(IplImage* train_image, const vector<KeyPoint>& features, \r
- const char* feature_label = "", int desc_start_idx = 0);\r
- \r
- // LoadPCADescriptors: loads PCA descriptors from a file\r
- // - filename: input filename\r
- int LoadPCADescriptors(const char* filename);\r
- \r
- // SavePCADescriptors: saves PCA descriptors to a file\r
- // - filename: output filename\r
- void SavePCADescriptors(const char* filename);\r
- \r
- // SetPCAHigh: sets the high resolution pca matrices (copied to internal structures)\r
- void SetPCAHigh(CvMat* avg, CvMat* eigenvectors);\r
- \r
- // SetPCALow: sets the low resolution pca matrices (copied to internal structures)\r
- void SetPCALow(CvMat* avg, CvMat* eigenvectors);\r
- \r
- \r
-protected:\r
- Size m_patch_size; // patch size\r
- int m_pose_count; // the number of poses for each descriptor\r
- int m_train_feature_count; // the number of the training features\r
- OneWayDescriptor* m_descriptors; // array of train feature descriptors\r
- CvMat* m_pca_avg; // PCA average vector for small patches\r
- CvMat* m_pca_eigenvectors; // PCA eigenvectors for small patches\r
- CvMat* m_pca_hr_avg; // PCA average vector for large patches\r
- CvMat* m_pca_hr_eigenvectors; // PCA eigenvectors for large patches\r
- OneWayDescriptor* m_pca_descriptors; // an array of PCA descriptors\r
- \r
- AffinePose* m_poses; // array of poses\r
- CvMat** m_transforms; // array of affine transformations corresponding to poses\r
- \r
- int m_pca_dim_high;\r
- int m_pca_dim_low;\r
- \r
- int m_pyr_levels;\r
-};\r
-\r
-class CV_EXPORTS OneWayDescriptorObject : public OneWayDescriptorBase\r
-{\r
-public:\r
- // creates an instance of OneWayDescriptorObject from a set of training files\r
- // - patch_size: size of the input (large) patch\r
- // - pose_count: the number of poses to generate for each descriptor\r
- // - train_path: path to training files\r
- // - pca_config: the name of the file that contains PCA for small patches (2 times smaller\r
- // than patch_size each dimension\r
- // - pca_hr_config: the name of the file that contains PCA for large patches (of patch_size size)\r
- // - pca_desc_config: the name of the file that contains descriptors of PCA components\r
- OneWayDescriptorObject(Size patch_size, int pose_count, const char* train_path, const char* pca_config, \r
- const char* pca_hr_config = 0, const char* pca_desc_config = 0, int pyr_levels = 2);\r
- \r
- ~OneWayDescriptorObject();\r
- \r
- // Allocate: allocates memory for a given number of features\r
- // - train_feature_count: the total number of features\r
- // - object_feature_count: the number of features extracted from the object \r
- void Allocate(int train_feature_count, int object_feature_count);\r
- \r
- \r
- void SetLabeledFeatures(const vector<KeyPoint>& features) {m_train_features = features;};\r
- vector<KeyPoint>& GetLabeledFeatures() {return m_train_features;};\r
- const vector<KeyPoint>& GetLabeledFeatures() const {return m_train_features;};\r
- \r
- // IsDescriptorObject: returns 1 if descriptor with specified index is positive, otherwise 0\r
- int IsDescriptorObject(int desc_idx) const;\r
- \r
- // MatchPointToPart: returns the part number of a feature if it matches one of the object parts, otherwise -1\r
- int MatchPointToPart(Point pt) const;\r
- \r
- // GetDescriptorPart: returns the part number of the feature corresponding to a specified descriptor \r
- // - desc_idx: descriptor index\r
- int GetDescriptorPart(int desc_idx) const;\r
- \r
- // GetTrainFeatures: returns a set of training features\r
- const vector<KeyPoint>& GetTrainFeatures() const {return m_train_features;};\r
- vector<KeyPoint> _GetTrainFeatures() const;\r
- \r
- void InitializeObjectDescriptors(IplImage* train_image, const vector<KeyPoint>& features, \r
- const char* feature_label, int desc_start_idx = 0, float scale = 1.0f);\r
- \r
-protected:\r
- int* m_part_id; // contains part id for each of object descriptors\r
- vector<KeyPoint> m_train_features; // train features\r
- int m_object_feature_count; // the number of the positive features\r
-};\r
-\r
-\r
-// detect corners using FAST algorithm\r
-CV_EXPORTS void FAST( const Mat& image, vector<KeyPoint>& keypoints, int threshold, bool nonmax_supression=true );\r
-\r
-\r
-class CV_EXPORTS LevMarqSparse\r
-{\r
-public:\r
- LevMarqSparse();\r
- LevMarqSparse(int npoints, // number of points\r
- int ncameras, // number of cameras\r
- int nPointParams, // number of params per one point (3 in case of 3D points)\r
- int nCameraParams, // number of parameters per one camera\r
- int nErrParams, // number of parameters in measurement vector\r
- // for 1 point at one camera (2 in case of 2D projections)\r
- Mat& visibility, // visibility matrix. rows correspond to points, columns correspond to cameras\r
- // 1 - point is visible for the camera, 0 - invisible\r
- Mat& P0, // starting vector of parameters, first cameras then points\r
- Mat& X, // measurements, in order of visibility. non visible cases are skipped \r
- TermCriteria criteria, // termination criteria\r
- \r
- // callback for estimation of Jacobian matrices\r
- void (CV_CDECL * fjac)(int i, int j, Mat& point_params,\r
- Mat& cam_params, Mat& A, Mat& B, void* data),\r
- // callback for estimation of backprojection errors\r
- void (CV_CDECL * func)(int i, int j, Mat& point_params,\r
- Mat& cam_params, Mat& estim, void* data),\r
- void* data // user-specific data passed to the callbacks\r
- );\r
- virtual ~LevMarqSparse();\r
- \r
- virtual void run( int npoints, // number of points\r
- int ncameras, // number of cameras\r
- int nPointParams, // number of params per one point (3 in case of 3D points)\r
- int nCameraParams, // number of parameters per one camera\r
- int nErrParams, // number of parameters in measurement vector\r
- // for 1 point at one camera (2 in case of 2D projections)\r
- Mat& visibility, // visibility matrix. rows correspond to points, columns correspond to cameras\r
- // 1 - point is visible for the camera, 0 - invisible\r
- Mat& P0, // starting vector of parameters, first cameras then points\r
- Mat& X, // measurements, in order of visibility. non visible cases are skipped \r
- TermCriteria criteria, // termination criteria\r
- \r
- // callback for estimation of Jacobian matrices\r
- void (CV_CDECL * fjac)(int i, int j, Mat& point_params,\r
- Mat& cam_params, Mat& A, Mat& B, void* data),\r
- // callback for estimation of backprojection errors\r
- void (CV_CDECL * func)(int i, int j, Mat& point_params,\r
- Mat& cam_params, Mat& estim, void* data),\r
- void* data // user-specific data passed to the callbacks\r
- );\r
-\r
- virtual void clear();\r
- \r
- // useful function to do simple bundle adjastment tasks\r
- static void bundleAdjust(vector<Point3d>& points, //positions of points in global coordinate system (input and output)\r
- const vector<vector<Point2d> >& imagePoints, //projections of 3d points for every camera \r
- const vector<vector<int> >& visibility, //visibility of 3d points for every camera \r
- vector<Mat>& cameraMatrix, //intrinsic matrices of all cameras (input and output)\r
- vector<Mat>& R, //rotation matrices of all cameras (input and output)\r
- vector<Mat>& T, //translation vector of all cameras (input and output)\r
- vector<Mat>& distCoeffs, //distortion coefficients of all cameras (input and output)\r
- const TermCriteria& criteria=\r
- TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, DBL_EPSILON));\r
- \r
-protected:\r
- virtual void optimize(); //main function that runs minimization\r
- \r
- //iteratively asks for measurement for visible camera-point pairs\r
- void ask_for_proj(); \r
- //iteratively asks for Jacobians for every camera_point pair\r
- void ask_for_projac(); \r
- \r
- CvMat* err; //error X-hX\r
- double prevErrNorm, errNorm;\r
- double lambda;\r
- CvTermCriteria criteria;\r
- int iters;\r
- \r
- CvMat** U; //size of array is equal to number of cameras\r
- CvMat** V; //size of array is equal to number of points\r
- CvMat** inv_V_star; //inverse of V*\r
-\r
- CvMat* A;\r
- CvMat* B;\r
- CvMat* W; \r
-\r
- CvMat* X; //measurement \r
- CvMat* hX; //current measurement extimation given new parameter vector \r
- \r
- CvMat* prevP; //current already accepted parameter. \r
- CvMat* P; // parameters used to evaluate function with new params\r
- // this parameters may be rejected \r
- \r
- CvMat* deltaP; //computed increase of parameters (result of normal system solution )\r
-\r
- CvMat** ea; // sum_i AijT * e_ij , used as right part of normal equation\r
- // length of array is j = number of cameras \r
- CvMat** eb; // sum_j BijT * e_ij , used as right part of normal equation\r
- // length of array is i = number of points\r
-\r
- CvMat** Yj; //length of array is i = num_points\r
-\r
- CvMat* S; //big matrix of block Sjk , each block has size num_cam_params x num_cam_params \r
-\r
- CvMat* JtJ_diag; //diagonal of JtJ, used to backup diagonal elements before augmentation\r
-\r
- CvMat* Vis_index; // matrix which element is index of measurement for point i and camera j\r
- \r
- int num_cams;\r
- int num_points;\r
- int num_err_param;\r
- int num_cam_param;\r
- int num_point_param;\r
-\r
- //target function and jacobian pointers, which needs to be initialized \r
- void (*fjac)(int i, int j, Mat& point_params, Mat& cam_params, Mat& A, Mat& B, void* data);\r
- void (*func)(int i, int j, Mat& point_params, Mat& cam_params, Mat& estim, void* data );\r
-\r
- void* data;\r
-};\r
-\r
-\r
-}\r
-\r
-#endif /* __cplusplus */\r
-\r
-#endif /* __CVAUX_HPP__ */\r
-\r
-/* End of file. */\r
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// Intel License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000, Intel Corporation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of Intel Corporation may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#ifndef __OPENCV_AUX_HPP__
+#define __OPENCV_AUX_HPP__
+
+#ifdef __cplusplus
+
+#include <iosfwd>
+
+class CV_EXPORTS CvImage
+{
+public:
+ CvImage() : image(0), refcount(0) {}
+ CvImage( CvSize size, int depth, int channels )
+ {
+ image = cvCreateImage( size, depth, channels );
+ refcount = image ? new int(1) : 0;
+ }
+
+ CvImage( IplImage* img ) : image(img)
+ {
+ refcount = image ? new int(1) : 0;
+ }
+
+ CvImage( const CvImage& img ) : image(img.image), refcount(img.refcount)
+ {
+ if( refcount ) ++(*refcount);
+ }
+
+ CvImage( const char* filename, const char* imgname=0, int color=-1 ) : image(0), refcount(0)
+ { load( filename, imgname, color ); }
+
+ CvImage( CvFileStorage* fs, const char* mapname, const char* imgname ) : image(0), refcount(0)
+ { read( fs, mapname, imgname ); }
+
+ CvImage( CvFileStorage* fs, const char* seqname, int idx ) : image(0), refcount(0)
+ { read( fs, seqname, idx ); }
+
+ ~CvImage()
+ {
+ if( refcount && !(--*refcount) )
+ {
+ cvReleaseImage( &image );
+ delete refcount;
+ }
+ }
+
+ CvImage clone() { return CvImage(image ? cvCloneImage(image) : 0); }
+
+ void create( CvSize size, int depth, int channels )
+ {
+ if( !image || !refcount ||
+ image->width != size.width || image->height != size.height ||
+ image->depth != depth || image->nChannels != channels )
+ attach( cvCreateImage( size, depth, channels ));
+ }
+
+ void release() { detach(); }
+ void clear() { detach(); }
+
+ void attach( IplImage* img, bool use_refcount=true )
+ {
+ if( refcount && --*refcount == 0 )
+ {
+ cvReleaseImage( &image );
+ delete refcount;
+ }
+ image = img;
+ refcount = use_refcount && image ? new int(1) : 0;
+ }
+
+ void detach()
+ {
+ if( refcount && --*refcount == 0 )
+ {
+ cvReleaseImage( &image );
+ delete refcount;
+ }
+ image = 0;
+ refcount = 0;
+ }
+
+ bool load( const char* filename, const char* imgname=0, int color=-1 );
+ bool read( CvFileStorage* fs, const char* mapname, const char* imgname );
+ bool read( CvFileStorage* fs, const char* seqname, int idx );
+ void save( const char* filename, const char* imgname, const int* params=0 );
+ void write( CvFileStorage* fs, const char* imgname );
+
+ void show( const char* window_name );
+ bool is_valid() { return image != 0; }
+
+ int width() const { return image ? image->width : 0; }
+ int height() const { return image ? image->height : 0; }
+
+ CvSize size() const { return image ? cvSize(image->width, image->height) : cvSize(0,0); }
+
+ CvSize roi_size() const
+ {
+ return !image ? cvSize(0,0) :
+ !image->roi ? cvSize(image->width,image->height) :
+ cvSize(image->roi->width, image->roi->height);
+ }
+
+ CvRect roi() const
+ {
+ return !image ? cvRect(0,0,0,0) :
+ !image->roi ? cvRect(0,0,image->width,image->height) :
+ cvRect(image->roi->xOffset,image->roi->yOffset,
+ image->roi->width,image->roi->height);
+ }
+
+ int coi() const { return !image || !image->roi ? 0 : image->roi->coi; }
+
+ void set_roi(CvRect roi) { cvSetImageROI(image,roi); }
+ void reset_roi() { cvResetImageROI(image); }
+ void set_coi(int coi) { cvSetImageCOI(image,coi); }
+ int depth() const { return image ? image->depth : 0; }
+ int channels() const { return image ? image->nChannels : 0; }
+ int pix_size() const { return image ? ((image->depth & 255)>>3)*image->nChannels : 0; }
+
+ uchar* data() { return image ? (uchar*)image->imageData : 0; }
+ const uchar* data() const { return image ? (const uchar*)image->imageData : 0; }
+ int step() const { return image ? image->widthStep : 0; }
+ int origin() const { return image ? image->origin : 0; }
+
+ uchar* roi_row(int y)
+ {
+ assert(0<=y);
+ assert(!image ?
+ 1 : image->roi ?
+ y<image->roi->height : y<image->height);
+
+ return !image ? 0 :
+ !image->roi ?
+ (uchar*)(image->imageData + y*image->widthStep) :
+ (uchar*)(image->imageData + (y+image->roi->yOffset)*image->widthStep +
+ image->roi->xOffset*((image->depth & 255)>>3)*image->nChannels);
+ }
+
+ const uchar* roi_row(int y) const
+ {
+ assert(0<=y);
+ assert(!image ?
+ 1 : image->roi ?
+ y<image->roi->height : y<image->height);
+
+ return !image ? 0 :
+ !image->roi ?
+ (const uchar*)(image->imageData + y*image->widthStep) :
+ (const uchar*)(image->imageData + (y+image->roi->yOffset)*image->widthStep +
+ image->roi->xOffset*((image->depth & 255)>>3)*image->nChannels);
+ }
+
+ operator const IplImage* () const { return image; }
+ operator IplImage* () { return image; }
+
+ CvImage& operator = (const CvImage& img)
+ {
+ if( img.refcount )
+ ++*img.refcount;
+ if( refcount && !(--*refcount) )
+ cvReleaseImage( &image );
+ image=img.image;
+ refcount=img.refcount;
+ return *this;
+ }
+
+protected:
+ IplImage* image;
+ int* refcount;
+};
+
+
+class CV_EXPORTS CvMatrix
+{
+public:
+ CvMatrix() : matrix(0) {}
+ CvMatrix( int rows, int cols, int type )
+ { matrix = cvCreateMat( rows, cols, type ); }
+
+ CvMatrix( int rows, int cols, int type, CvMat* hdr,
+ void* data=0, int step=CV_AUTOSTEP )
+ { matrix = cvInitMatHeader( hdr, rows, cols, type, data, step ); }
+
+ CvMatrix( int rows, int cols, int type, CvMemStorage* storage, bool alloc_data=true );
+
+ CvMatrix( int rows, int cols, int type, void* data, int step=CV_AUTOSTEP )
+ { matrix = cvCreateMatHeader( rows, cols, type );
+ cvSetData( matrix, data, step ); }
+
+ CvMatrix( CvMat* m )
+ { matrix = m; }
+
+ CvMatrix( const CvMatrix& m )
+ {
+ matrix = m.matrix;
+ addref();
+ }
+
+ CvMatrix( const char* filename, const char* matname=0, int color=-1 ) : matrix(0)
+ { load( filename, matname, color ); }
+
+ CvMatrix( CvFileStorage* fs, const char* mapname, const char* matname ) : matrix(0)
+ { read( fs, mapname, matname ); }
+
+ CvMatrix( CvFileStorage* fs, const char* seqname, int idx ) : matrix(0)
+ { read( fs, seqname, idx ); }
+
+ ~CvMatrix()
+ {
+ release();
+ }
+
+ CvMatrix clone() { return CvMatrix(matrix ? cvCloneMat(matrix) : 0); }
+
+ void set( CvMat* m, bool add_ref )
+ {
+ release();
+ matrix = m;
+ if( add_ref )
+ addref();
+ }
+
+ void create( int rows, int cols, int type )
+ {
+ if( !matrix || !matrix->refcount ||
+ matrix->rows != rows || matrix->cols != cols ||
+ CV_MAT_TYPE(matrix->type) != type )
+ set( cvCreateMat( rows, cols, type ), false );
+ }
+
+ void addref() const
+ {
+ if( matrix )
+ {
+ if( matrix->hdr_refcount )
+ ++matrix->hdr_refcount;
+ else if( matrix->refcount )
+ ++*matrix->refcount;
+ }
+ }
+
+ void release()
+ {
+ if( matrix )
+ {
+ if( matrix->hdr_refcount )
+ {
+ if( --matrix->hdr_refcount == 0 )
+ cvReleaseMat( &matrix );
+ }
+ else if( matrix->refcount )
+ {
+ if( --*matrix->refcount == 0 )
+ cvFree( &matrix->refcount );
+ }
+ matrix = 0;
+ }
+ }
+
+ void clear()
+ {
+ release();
+ }
+
+ bool load( const char* filename, const char* matname=0, int color=-1 );
+ bool read( CvFileStorage* fs, const char* mapname, const char* matname );
+ bool read( CvFileStorage* fs, const char* seqname, int idx );
+ void save( const char* filename, const char* matname, const int* params=0 );
+ void write( CvFileStorage* fs, const char* matname );
+
+ void show( const char* window_name );
+
+ bool is_valid() { return matrix != 0; }
+
+ int rows() const { return matrix ? matrix->rows : 0; }
+ int cols() const { return matrix ? matrix->cols : 0; }
+
+ CvSize size() const
+ {
+ return !matrix ? cvSize(0,0) : cvSize(matrix->rows,matrix->cols);
+ }
+
+ int type() const { return matrix ? CV_MAT_TYPE(matrix->type) : 0; }
+ int depth() const { return matrix ? CV_MAT_DEPTH(matrix->type) : 0; }
+ int channels() const { return matrix ? CV_MAT_CN(matrix->type) : 0; }
+ int pix_size() const { return matrix ? CV_ELEM_SIZE(matrix->type) : 0; }
+
+ uchar* data() { return matrix ? matrix->data.ptr : 0; }
+ const uchar* data() const { return matrix ? matrix->data.ptr : 0; }
+ int step() const { return matrix ? matrix->step : 0; }
+
+ void set_data( void* data, int step=CV_AUTOSTEP )
+ { cvSetData( matrix, data, step ); }
+
+ uchar* row(int i) { return !matrix ? 0 : matrix->data.ptr + i*matrix->step; }
+ const uchar* row(int i) const
+ { return !matrix ? 0 : matrix->data.ptr + i*matrix->step; }
+
+ operator const CvMat* () const { return matrix; }
+ operator CvMat* () { return matrix; }
+
+ CvMatrix& operator = (const CvMatrix& _m)
+ {
+ _m.addref();
+ release();
+ matrix = _m.matrix;
+ return *this;
+ }
+
+protected:
+ CvMat* matrix;
+};
+
+/****************************************************************************************\
+* CamShiftTracker *
+\****************************************************************************************/
+
+class CV_EXPORTS CvCamShiftTracker
+{
+public:
+
+ CvCamShiftTracker();
+ virtual ~CvCamShiftTracker();
+
+ /**** Characteristics of the object that are calculated by track_object method *****/
+ float get_orientation() const // orientation of the object in degrees
+ { return m_box.angle; }
+ float get_length() const // the larger linear size of the object
+ { return m_box.size.height; }
+ float get_width() const // the smaller linear size of the object
+ { return m_box.size.width; }
+ CvPoint2D32f get_center() const // center of the object
+ { return m_box.center; }
+ CvRect get_window() const // bounding rectangle for the object
+ { return m_comp.rect; }
+
+ /*********************** Tracking parameters ************************/
+ int get_threshold() const // thresholding value that applied to back project
+ { return m_threshold; }
+
+ int get_hist_dims( int* dims = 0 ) const // returns number of histogram dimensions and sets
+ { return m_hist ? cvGetDims( m_hist->bins, dims ) : 0; }
+
+ int get_min_ch_val( int channel ) const // get the minimum allowed value of the specified channel
+ { return m_min_ch_val[channel]; }
+
+ int get_max_ch_val( int channel ) const // get the maximum allowed value of the specified channel
+ { return m_max_ch_val[channel]; }
+
+ // set initial object rectangle (must be called before initial calculation of the histogram)
+ bool set_window( CvRect window)
+ { m_comp.rect = window; return true; }
+
+ bool set_threshold( int threshold ) // threshold applied to the histogram bins
+ { m_threshold = threshold; return true; }
+
+ bool set_hist_bin_range( int dim, int min_val, int max_val );
+
+ bool set_hist_dims( int c_dims, int* dims );// set the histogram parameters
+
+ bool set_min_ch_val( int channel, int val ) // set the minimum allowed value of the specified channel
+ { m_min_ch_val[channel] = val; return true; }
+ bool set_max_ch_val( int channel, int val ) // set the maximum allowed value of the specified channel
+ { m_max_ch_val[channel] = val; return true; }
+
+ /************************ The processing methods *********************************/
+ // update object position
+ virtual bool track_object( const IplImage* cur_frame );
+
+ // update object histogram
+ virtual bool update_histogram( const IplImage* cur_frame );
+
+ // reset histogram
+ virtual void reset_histogram();
+
+ /************************ Retrieving internal data *******************************/
+ // get back project image
+ virtual IplImage* get_back_project()
+ { return m_back_project; }
+
+ float query( int* bin ) const
+ { return m_hist ? (float)cvGetRealND(m_hist->bins, bin) : 0.f; }
+
+protected:
+
+ // internal method for color conversion: fills m_color_planes group
+ virtual void color_transform( const IplImage* img );
+
+ CvHistogram* m_hist;
+
+ CvBox2D m_box;
+ CvConnectedComp m_comp;
+
+ float m_hist_ranges_data[CV_MAX_DIM][2];
+ float* m_hist_ranges[CV_MAX_DIM];
+
+ int m_min_ch_val[CV_MAX_DIM];
+ int m_max_ch_val[CV_MAX_DIM];
+ int m_threshold;
+
+ IplImage* m_color_planes[CV_MAX_DIM];
+ IplImage* m_back_project;
+ IplImage* m_temp;
+ IplImage* m_mask;
+};
+
+/****************************************************************************************\
+* Adaptive Skin Detector *
+\****************************************************************************************/
+
+class CV_EXPORTS CvAdaptiveSkinDetector
+{
+private:
+ enum {
+ GSD_HUE_LT = 3,
+ GSD_HUE_UT = 33,
+ GSD_INTENSITY_LT = 15,
+ GSD_INTENSITY_UT = 250
+ };
+
+ class CV_EXPORTS Histogram
+ {
+ private:
+ enum {
+ HistogramSize = (GSD_HUE_UT - GSD_HUE_LT + 1)
+ };
+
+ protected:
+ int findCoverageIndex(double surfaceToCover, int defaultValue = 0);
+
+ public:
+ CvHistogram *fHistogram;
+ Histogram();
+ virtual ~Histogram();
+
+ void findCurveThresholds(int &x1, int &x2, double percent = 0.05);
+ void mergeWith(Histogram *source, double weight);
+ };
+
+ int nStartCounter, nFrameCount, nSkinHueLowerBound, nSkinHueUpperBound, nMorphingMethod, nSamplingDivider;
+ double fHistogramMergeFactor, fHuePercentCovered;
+ Histogram histogramHueMotion, skinHueHistogram;
+ IplImage *imgHueFrame, *imgSaturationFrame, *imgLastGrayFrame, *imgMotionFrame, *imgFilteredFrame;
+ IplImage *imgShrinked, *imgTemp, *imgGrayFrame, *imgHSVFrame;
+
+protected:
+ void initData(IplImage *src, int widthDivider, int heightDivider);
+ void adaptiveFilter();
+
+public:
+
+ enum {
+ MORPHING_METHOD_NONE = 0,
+ MORPHING_METHOD_ERODE = 1,
+ MORPHING_METHOD_ERODE_ERODE = 2,
+ MORPHING_METHOD_ERODE_DILATE = 3
+ };
+
+ CvAdaptiveSkinDetector(int samplingDivider = 1, int morphingMethod = MORPHING_METHOD_NONE);
+ virtual ~CvAdaptiveSkinDetector();
+
+ virtual void process(IplImage *inputBGRImage, IplImage *outputHueMask);
+};
+
+
+/****************************************************************************************\
+* Fuzzy MeanShift Tracker *
+\****************************************************************************************/
+
+class CV_EXPORTS CvFuzzyPoint {
+public:
+ double x, y, value;
+
+ CvFuzzyPoint(double _x, double _y);
+};
+
+class CV_EXPORTS CvFuzzyCurve {
+private:
+ std::vector<CvFuzzyPoint> points;
+ double value, centre;
+
+ bool between(double x, double x1, double x2);
+
+public:
+ CvFuzzyCurve();
+ ~CvFuzzyCurve();
+
+ void setCentre(double _centre);
+ double getCentre();
+ void clear();
+ void addPoint(double x, double y);
+ double calcValue(double param);
+ double getValue();
+ void setValue(double _value);
+};
+
+class CV_EXPORTS CvFuzzyFunction {
+public:
+ std::vector<CvFuzzyCurve> curves;
+
+ CvFuzzyFunction();
+ ~CvFuzzyFunction();
+ void addCurve(CvFuzzyCurve *curve, double value = 0);
+ void resetValues();
+ double calcValue();
+ CvFuzzyCurve *newCurve();
+};
+
+class CV_EXPORTS CvFuzzyRule {
+private:
+ CvFuzzyCurve *fuzzyInput1, *fuzzyInput2;
+ CvFuzzyCurve *fuzzyOutput;
+public:
+ CvFuzzyRule();
+ ~CvFuzzyRule();
+ void setRule(CvFuzzyCurve *c1, CvFuzzyCurve *c2, CvFuzzyCurve *o1);
+ double calcValue(double param1, double param2);
+ CvFuzzyCurve *getOutputCurve();
+};
+
+class CV_EXPORTS CvFuzzyController {
+private:
+ std::vector<CvFuzzyRule*> rules;
+public:
+ CvFuzzyController();
+ ~CvFuzzyController();
+ void addRule(CvFuzzyCurve *c1, CvFuzzyCurve *c2, CvFuzzyCurve *o1);
+ double calcOutput(double param1, double param2);
+};
+
+class CV_EXPORTS CvFuzzyMeanShiftTracker
+{
+private:
+ class FuzzyResizer
+ {
+ private:
+ CvFuzzyFunction iInput, iOutput;
+ CvFuzzyController fuzzyController;
+ public:
+ FuzzyResizer();
+ int calcOutput(double edgeDensity, double density);
+ };
+
+ class SearchWindow
+ {
+ public:
+ FuzzyResizer *fuzzyResizer;
+ int x, y;
+ int width, height, maxWidth, maxHeight, ellipseHeight, ellipseWidth;
+ int ldx, ldy, ldw, ldh, numShifts, numIters;
+ int xGc, yGc;
+ long m00, m01, m10, m11, m02, m20;
+ double ellipseAngle;
+ double density;
+ unsigned int depthLow, depthHigh;
+ int verticalEdgeLeft, verticalEdgeRight, horizontalEdgeTop, horizontalEdgeBottom;
+
+ SearchWindow();
+ ~SearchWindow();
+ void setSize(int _x, int _y, int _width, int _height);
+ void initDepthValues(IplImage *maskImage, IplImage *depthMap);
+ bool shift();
+ void extractInfo(IplImage *maskImage, IplImage *depthMap, bool initDepth);
+ void getResizeAttribsEdgeDensityLinear(int &resizeDx, int &resizeDy, int &resizeDw, int &resizeDh);
+ void getResizeAttribsInnerDensity(int &resizeDx, int &resizeDy, int &resizeDw, int &resizeDh);
+ void getResizeAttribsEdgeDensityFuzzy(int &resizeDx, int &resizeDy, int &resizeDw, int &resizeDh);
+ bool meanShift(IplImage *maskImage, IplImage *depthMap, int maxIteration, bool initDepth);
+ };
+
+public:
+ enum TrackingState
+ {
+ tsNone = 0,
+ tsSearching = 1,
+ tsTracking = 2,
+ tsSetWindow = 3,
+ tsDisabled = 10
+ };
+
+ enum ResizeMethod {
+ rmEdgeDensityLinear = 0,
+ rmEdgeDensityFuzzy = 1,
+ rmInnerDensity = 2
+ };
+
+ enum {
+ MinKernelMass = 1000
+ };
+
+ SearchWindow kernel;
+ int searchMode;
+
+private:
+ enum
+ {
+ MaxMeanShiftIteration = 5,
+ MaxSetSizeIteration = 5
+ };
+
+ void findOptimumSearchWindow(SearchWindow &searchWindow, IplImage *maskImage, IplImage *depthMap, int maxIteration, int resizeMethod, bool initDepth);
+
+public:
+ CvFuzzyMeanShiftTracker();
+ ~CvFuzzyMeanShiftTracker();
+
+ void track(IplImage *maskImage, IplImage *depthMap, int resizeMethod, bool resetSearch, int minKernelMass = MinKernelMass);
+};
+
+
+namespace cv
+{
+
+class CV_EXPORTS Octree
+{
+public:
+ struct Node
+ {
+ Node() {}
+ int begin, end;
+ float x_min, x_max, y_min, y_max, z_min, z_max;
+ int maxLevels;
+ bool isLeaf;
+ int children[8];
+ };
+
+ Octree();
+ Octree( const vector<Point3f>& points, int maxLevels = 10, int minPoints = 20 );
+ virtual ~Octree();
+
+ virtual void buildTree( const vector<Point3f>& points, int maxLevels = 10, int minPoints = 20 );
+ virtual void getPointsWithinSphere( const Point3f& center, float radius,
+ vector<Point3f>& points ) const;
+ const vector<Node>& getNodes() const { return nodes; }
+private:
+ int minPoints;
+ vector<Point3f> points;
+ vector<Node> nodes;
+
+ virtual void buildNext(size_t node_ind);
+};
+
+
+class CV_EXPORTS Mesh3D
+{
+public:
+ struct EmptyMeshException {};
+
+ Mesh3D();
+ Mesh3D(const vector<Point3f>& vtx);
+ ~Mesh3D();
+
+ void buildOctree();
+ void clearOctree();
+ float estimateResolution(float tryRatio = 0.1f);
+ void computeNormals(float normalRadius, int minNeighbors = 20);
+ void computeNormals(const vector<int>& subset, float normalRadius, int minNeighbors = 20);
+
+ void writeAsVrml(const String& file, const vector<Scalar>& colors = vector<Scalar>()) const;
+
+ vector<Point3f> vtx;
+ vector<Point3f> normals;
+ float resolution;
+ Octree octree;
+
+ const static Point3f allzero;
+};
+
+class CV_EXPORTS SpinImageModel
+{
+public:
+
+ /* model parameters, leave unset for default or auto estimate */
+ float normalRadius;
+ int minNeighbors;
+
+ float binSize;
+ int imageWidth;
+
+ float lambda;
+ float gamma;
+
+ float T_GeometriccConsistency;
+ float T_GroupingCorespondances;
+
+ /* public interface */
+ SpinImageModel();
+ explicit SpinImageModel(const Mesh3D& mesh);
+ ~SpinImageModel();
+
+ void setLogger(std::ostream* log);
+ void selectRandomSubset(float ratio);
+ void setSubset(const vector<int>& subset);
+ void compute();
+
+ void match(const SpinImageModel& scene, vector< vector<Vec2i> >& result);
+
+ Mat packRandomScaledSpins(bool separateScale = false, size_t xCount = 10, size_t yCount = 10) const;
+
+ size_t getSpinCount() const { return spinImages.rows; }
+ Mat getSpinImage(size_t index) const { return spinImages.row(index); }
+ const Point3f& getSpinVertex(size_t index) const { return mesh.vtx[subset[index]]; }
+ const Point3f& getSpinNormal(size_t index) const { return mesh.normals[subset[index]]; }
+
+ const Mesh3D& getMesh() const { return mesh; }
+ Mesh3D& getMesh() { return mesh; }
+
+ /* static utility functions */
+ static bool spinCorrelation(const Mat& spin1, const Mat& spin2, float lambda, float& result);
+
+ static Point2f calcSpinMapCoo(const Point3f& point, const Point3f& vertex, const Point3f& normal);
+
+ static float geometricConsistency(const Point3f& pointScene1, const Point3f& normalScene1,
+ const Point3f& pointModel1, const Point3f& normalModel1,
+ const Point3f& pointScene2, const Point3f& normalScene2,
+ const Point3f& pointModel2, const Point3f& normalModel2);
+
+ static float groupingCreteria(const Point3f& pointScene1, const Point3f& normalScene1,
+ const Point3f& pointModel1, const Point3f& normalModel1,
+ const Point3f& pointScene2, const Point3f& normalScene2,
+ const Point3f& pointModel2, const Point3f& normalModel2,
+ float gamma);
+protected:
+ void defaultParams();
+
+ void matchSpinToModel(const Mat& spin, vector<int>& indeces,
+ vector<float>& corrCoeffs, bool useExtremeOutliers = true) const;
+
+ void repackSpinImages(const vector<uchar>& mask, Mat& spinImages, bool reAlloc = true) const;
+
+ vector<int> subset;
+ Mesh3D mesh;
+ Mat spinImages;
+ std::ostream* out;
+};
+
+class CV_EXPORTS TickMeter
+{
+public:
+ TickMeter();
+ void start();
+ void stop();
+
+ int64 getTimeTicks() const;
+ double getTimeMicro() const;
+ double getTimeMilli() const;
+ double getTimeSec() const;
+ int64 getCounter() const;
+
+ void reset();
+private:
+ int64 counter;
+ int64 sumTime;
+ int64 startTime;
+};
+
+CV_EXPORTS std::ostream& operator<<(std::ostream& out, const TickMeter& tm);
+
+/****************************************************************************************\
+* HOG (Histogram-of-Oriented-Gradients) Descriptor and Object Detector *
+\****************************************************************************************/
+
+struct CV_EXPORTS HOGDescriptor
+{
+public:
+ enum { L2Hys=0 };
+
+ HOGDescriptor() : winSize(64,128), blockSize(16,16), blockStride(8,8),
+ cellSize(8,8), nbins(9), derivAperture(1), winSigma(-1),
+ histogramNormType(L2Hys), L2HysThreshold(0.2), gammaCorrection(true)
+ {}
+
+ HOGDescriptor(Size _winSize, Size _blockSize, Size _blockStride,
+ Size _cellSize, int _nbins, int _derivAperture=1, double _winSigma=-1,
+ int _histogramNormType=L2Hys, double _L2HysThreshold=0.2, bool _gammaCorrection=false)
+ : winSize(_winSize), blockSize(_blockSize), blockStride(_blockStride), cellSize(_cellSize),
+ nbins(_nbins), derivAperture(_derivAperture), winSigma(_winSigma),
+ histogramNormType(_histogramNormType), L2HysThreshold(_L2HysThreshold),
+ gammaCorrection(_gammaCorrection)
+ {}
+
+ HOGDescriptor(const String& filename)
+ {
+ load(filename);
+ }
+
+ virtual ~HOGDescriptor() {}
+
+ size_t getDescriptorSize() const;
+ bool checkDetectorSize() const;
+ double getWinSigma() const;
+
+ virtual void setSVMDetector(const vector<float>& _svmdetector);
+
+ virtual bool load(const String& filename, const String& objname=String());
+ virtual void save(const String& filename, const String& objname=String()) const;
+
+ virtual void compute(const Mat& img,
+ vector<float>& descriptors,
+ Size winStride=Size(), Size padding=Size(),
+ const vector<Point>& locations=vector<Point>()) const;
+ virtual void detect(const Mat& img, vector<Point>& foundLocations,
+ double hitThreshold=0, Size winStride=Size(),
+ Size padding=Size(),
+ const vector<Point>& searchLocations=vector<Point>()) const;
+ virtual void detectMultiScale(const Mat& img, vector<Rect>& foundLocations,
+ double hitThreshold=0, Size winStride=Size(),
+ Size padding=Size(), double scale=1.05,
+ int groupThreshold=2) const;
+ virtual void computeGradient(const Mat& img, Mat& grad, Mat& angleOfs,
+ Size paddingTL=Size(), Size paddingBR=Size()) const;
+
+ static vector<float> getDefaultPeopleDetector();
+
+ Size winSize;
+ Size blockSize;
+ Size blockStride;
+ Size cellSize;
+ int nbins;
+ int derivAperture;
+ double winSigma;
+ int histogramNormType;
+ double L2HysThreshold;
+ bool gammaCorrection;
+ vector<float> svmDetector;
+};
+
+
+class CV_EXPORTS SelfSimDescriptor
+{
+public:
+ SelfSimDescriptor();
+ SelfSimDescriptor(int _ssize, int _lsize,
+ int _startDistanceBucket=DEFAULT_START_DISTANCE_BUCKET,
+ int _numberOfDistanceBuckets=DEFAULT_NUM_DISTANCE_BUCKETS,
+ int _nangles=DEFAULT_NUM_ANGLES);
+ SelfSimDescriptor(const SelfSimDescriptor& ss);
+ virtual ~SelfSimDescriptor();
+ SelfSimDescriptor& operator = (const SelfSimDescriptor& ss);
+
+ size_t getDescriptorSize() const;
+ Size getGridSize( Size imgsize, Size winStride ) const;
+
+ virtual void compute(const Mat& img, vector<float>& descriptors, Size winStride=Size(),
+ const vector<Point>& locations=vector<Point>()) const;
+ virtual void computeLogPolarMapping(Mat& mappingMask) const;
+ virtual void SSD(const Mat& img, Point pt, Mat& ssd) const;
+
+ int smallSize;
+ int largeSize;
+ int startDistanceBucket;
+ int numberOfDistanceBuckets;
+ int numberOfAngles;
+
+ enum { DEFAULT_SMALL_SIZE = 5, DEFAULT_LARGE_SIZE = 41,
+ DEFAULT_NUM_ANGLES = 20, DEFAULT_START_DISTANCE_BUCKET = 3,
+ DEFAULT_NUM_DISTANCE_BUCKETS = 7 };
+};
+
+
+class CV_EXPORTS PatchGenerator
+{
+public:
+ PatchGenerator();
+ PatchGenerator(double _backgroundMin, double _backgroundMax,
+ double _noiseRange, bool _randomBlur=true,
+ double _lambdaMin=0.6, double _lambdaMax=1.5,
+ double _thetaMin=-CV_PI, double _thetaMax=CV_PI,
+ double _phiMin=-CV_PI, double _phiMax=CV_PI );
+ void operator()(const Mat& image, Point2f pt, Mat& patch, Size patchSize, RNG& rng) const;
+ void operator()(const Mat& image, const Mat& transform, Mat& patch,
+ Size patchSize, RNG& rng) const;
+ void warpWholeImage(const Mat& image, Mat& matT, Mat& buf,
+ Mat& warped, int border, RNG& rng) const;
+ void generateRandomTransform(Point2f srcCenter, Point2f dstCenter,
+ Mat& transform, RNG& rng, bool inverse=false) const;
+ double backgroundMin, backgroundMax;
+ double noiseRange;
+ bool randomBlur;
+ double lambdaMin, lambdaMax;
+ double thetaMin, thetaMax;
+ double phiMin, phiMax;
+};
+
+
+class CV_EXPORTS LDetector
+{
+public:
+ LDetector();
+ LDetector(int _radius, int _threshold, int _nOctaves,
+ int _nViews, double _baseFeatureSize, double _clusteringDistance);
+ void operator()(const Mat& image, vector<KeyPoint>& keypoints, int maxCount=0, bool scaleCoords=true) const;
+ void operator()(const vector<Mat>& pyr, vector<KeyPoint>& keypoints, int maxCount=0, bool scaleCoords=true) const;
+ void getMostStable2D(const Mat& image, vector<KeyPoint>& keypoints,
+ int maxCount, const PatchGenerator& patchGenerator) const;
+ void setVerbose(bool verbose);
+
+ void read(const FileNode& node);
+ void write(FileStorage& fs, const String& name=String()) const;
+
+ int radius;
+ int threshold;
+ int nOctaves;
+ int nViews;
+ bool verbose;
+
+ double baseFeatureSize;
+ double clusteringDistance;
+};
+
+typedef LDetector YAPE;
+
+class CV_EXPORTS FernClassifier
+{
+public:
+ FernClassifier();
+ FernClassifier(const FileNode& node);
+ FernClassifier(const vector<Point2f>& points,
+ const vector<Ptr<Mat> >& refimgs,
+ const vector<int>& labels=vector<int>(),
+ int _nclasses=0, int _patchSize=PATCH_SIZE,
+ int _signatureSize=DEFAULT_SIGNATURE_SIZE,
+ int _nstructs=DEFAULT_STRUCTS,
+ int _structSize=DEFAULT_STRUCT_SIZE,
+ int _nviews=DEFAULT_VIEWS,
+ int _compressionMethod=COMPRESSION_NONE,
+ const PatchGenerator& patchGenerator=PatchGenerator());
+ virtual ~FernClassifier();
+ virtual void read(const FileNode& n);
+ virtual void write(FileStorage& fs, const String& name=String()) const;
+ virtual void trainFromSingleView(const Mat& image,
+ const vector<KeyPoint>& keypoints,
+ int _patchSize=PATCH_SIZE,
+ int _signatureSize=DEFAULT_SIGNATURE_SIZE,
+ int _nstructs=DEFAULT_STRUCTS,
+ int _structSize=DEFAULT_STRUCT_SIZE,
+ int _nviews=DEFAULT_VIEWS,
+ int _compressionMethod=COMPRESSION_NONE,
+ const PatchGenerator& patchGenerator=PatchGenerator());
+ virtual void train(const vector<Point2f>& points,
+ const vector<Ptr<Mat> >& refimgs,
+ const vector<int>& labels=vector<int>(),
+ int _nclasses=0, int _patchSize=PATCH_SIZE,
+ int _signatureSize=DEFAULT_SIGNATURE_SIZE,
+ int _nstructs=DEFAULT_STRUCTS,
+ int _structSize=DEFAULT_STRUCT_SIZE,
+ int _nviews=DEFAULT_VIEWS,
+ int _compressionMethod=COMPRESSION_NONE,
+ const PatchGenerator& patchGenerator=PatchGenerator());
+ virtual int operator()(const Mat& img, Point2f kpt, vector<float>& signature) const;
+ virtual int operator()(const Mat& patch, vector<float>& signature) const;
+ virtual void clear();
+ void setVerbose(bool verbose);
+
+ int getClassCount() const;
+ int getStructCount() const;
+ int getStructSize() const;
+ int getSignatureSize() const;
+ int getCompressionMethod() const;
+ Size getPatchSize() const;
+
+ struct Feature
+ {
+ uchar x1, y1, x2, y2;
+ Feature() : x1(0), y1(0), x2(0), y2(0) {}
+ Feature(int _x1, int _y1, int _x2, int _y2)
+ : x1((uchar)_x1), y1((uchar)_y1), x2((uchar)_x2), y2((uchar)_y2)
+ {}
+ template<typename _Tp> bool operator ()(const Mat_<_Tp>& patch) const
+ { return patch(y1,x1) > patch(y2, x2); }
+ };
+
+ enum
+ {
+ PATCH_SIZE = 31,
+ DEFAULT_STRUCTS = 50,
+ DEFAULT_STRUCT_SIZE = 9,
+ DEFAULT_VIEWS = 5000,
+ DEFAULT_SIGNATURE_SIZE = 176,
+ COMPRESSION_NONE = 0,
+ COMPRESSION_RANDOM_PROJ = 1,
+ COMPRESSION_PCA = 2,
+ DEFAULT_COMPRESSION_METHOD = COMPRESSION_NONE
+ };
+
+protected:
+ virtual void prepare(int _nclasses, int _patchSize, int _signatureSize,
+ int _nstructs, int _structSize,
+ int _nviews, int _compressionMethod);
+ virtual void finalize(RNG& rng);
+ virtual int getLeaf(int fidx, const Mat& patch) const;
+
+ bool verbose;
+ int nstructs;
+ int structSize;
+ int nclasses;
+ int signatureSize;
+ int compressionMethod;
+ int leavesPerStruct;
+ Size patchSize;
+ vector<Feature> features;
+ vector<int> classCounters;
+ vector<float> posteriors;
+};
+
+class CV_EXPORTS PlanarObjectDetector
+{
+public:
+ PlanarObjectDetector();
+ PlanarObjectDetector(const FileNode& node);
+ PlanarObjectDetector(const vector<Mat>& pyr, int _npoints=300,
+ int _patchSize=FernClassifier::PATCH_SIZE,
+ int _nstructs=FernClassifier::DEFAULT_STRUCTS,
+ int _structSize=FernClassifier::DEFAULT_STRUCT_SIZE,
+ int _nviews=FernClassifier::DEFAULT_VIEWS,
+ const LDetector& detector=LDetector(),
+ const PatchGenerator& patchGenerator=PatchGenerator());
+ virtual ~PlanarObjectDetector();
+ virtual void train(const vector<Mat>& pyr, int _npoints=300,
+ int _patchSize=FernClassifier::PATCH_SIZE,
+ int _nstructs=FernClassifier::DEFAULT_STRUCTS,
+ int _structSize=FernClassifier::DEFAULT_STRUCT_SIZE,
+ int _nviews=FernClassifier::DEFAULT_VIEWS,
+ const LDetector& detector=LDetector(),
+ const PatchGenerator& patchGenerator=PatchGenerator());
+ virtual void train(const vector<Mat>& pyr, const vector<KeyPoint>& keypoints,
+ int _patchSize=FernClassifier::PATCH_SIZE,
+ int _nstructs=FernClassifier::DEFAULT_STRUCTS,
+ int _structSize=FernClassifier::DEFAULT_STRUCT_SIZE,
+ int _nviews=FernClassifier::DEFAULT_VIEWS,
+ const LDetector& detector=LDetector(),
+ const PatchGenerator& patchGenerator=PatchGenerator());
+ Rect getModelROI() const;
+ vector<KeyPoint> getModelPoints() const;
+ const LDetector& getDetector() const;
+ const FernClassifier& getClassifier() const;
+ void setVerbose(bool verbose);
+
+ void read(const FileNode& node);
+ void write(FileStorage& fs, const String& name=String()) const;
+ bool operator()(const Mat& image, Mat& H, vector<Point2f>& corners) const;
+ bool operator()(const vector<Mat>& pyr, const vector<KeyPoint>& keypoints,
+ Mat& H, vector<Point2f>& corners, vector<int>* pairs=0) const;
+
+protected:
+ bool verbose;
+ Rect modelROI;
+ vector<KeyPoint> modelPoints;
+ LDetector ldetector;
+ FernClassifier fernClassifier;
+};
+
+
+
+
+// detect corners using FAST algorithm
+CV_EXPORTS void FAST( const Mat& image, vector<KeyPoint>& keypoints, int threshold, bool nonmax_supression=true );
+
+
+class CV_EXPORTS LevMarqSparse
+{
+public:
+ LevMarqSparse();
+ LevMarqSparse(int npoints, // number of points
+ int ncameras, // number of cameras
+ int nPointParams, // number of params per one point (3 in case of 3D points)
+ int nCameraParams, // number of parameters per one camera
+ int nErrParams, // number of parameters in measurement vector
+ // for 1 point at one camera (2 in case of 2D projections)
+ Mat& visibility, // visibility matrix. rows correspond to points, columns correspond to cameras
+ // 1 - point is visible for the camera, 0 - invisible
+ Mat& P0, // starting vector of parameters, first cameras then points
+ Mat& X, // measurements, in order of visibility. non visible cases are skipped
+ TermCriteria criteria, // termination criteria
+
+ // callback for estimation of Jacobian matrices
+ void (CV_CDECL * fjac)(int i, int j, Mat& point_params,
+ Mat& cam_params, Mat& A, Mat& B, void* data),
+ // callback for estimation of backprojection errors
+ void (CV_CDECL * func)(int i, int j, Mat& point_params,
+ Mat& cam_params, Mat& estim, void* data),
+ void* data // user-specific data passed to the callbacks
+ );
+ virtual ~LevMarqSparse();
+
+ virtual void run( int npoints, // number of points
+ int ncameras, // number of cameras
+ int nPointParams, // number of params per one point (3 in case of 3D points)
+ int nCameraParams, // number of parameters per one camera
+ int nErrParams, // number of parameters in measurement vector
+ // for 1 point at one camera (2 in case of 2D projections)
+ Mat& visibility, // visibility matrix. rows correspond to points, columns correspond to cameras
+ // 1 - point is visible for the camera, 0 - invisible
+ Mat& P0, // starting vector of parameters, first cameras then points
+ Mat& X, // measurements, in order of visibility. non visible cases are skipped
+ TermCriteria criteria, // termination criteria
+
+ // callback for estimation of Jacobian matrices
+ void (CV_CDECL * fjac)(int i, int j, Mat& point_params,
+ Mat& cam_params, Mat& A, Mat& B, void* data),
+ // callback for estimation of backprojection errors
+ void (CV_CDECL * func)(int i, int j, Mat& point_params,
+ Mat& cam_params, Mat& estim, void* data),
+ void* data // user-specific data passed to the callbacks
+ );
+
+ virtual void clear();
+
+ // useful function to do simple bundle adjastment tasks
+ static void bundleAdjust(vector<Point3d>& points, //positions of points in global coordinate system (input and output)
+ const vector<vector<Point2d> >& imagePoints, //projections of 3d points for every camera
+ const vector<vector<int> >& visibility, //visibility of 3d points for every camera
+ vector<Mat>& cameraMatrix, //intrinsic matrices of all cameras (input and output)
+ vector<Mat>& R, //rotation matrices of all cameras (input and output)
+ vector<Mat>& T, //translation vector of all cameras (input and output)
+ vector<Mat>& distCoeffs, //distortion coefficients of all cameras (input and output)
+ const TermCriteria& criteria=
+ TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, DBL_EPSILON));
+
+protected:
+ virtual void optimize(); //main function that runs minimization
+
+ //iteratively asks for measurement for visible camera-point pairs
+ void ask_for_proj();
+ //iteratively asks for Jacobians for every camera_point pair
+ void ask_for_projac();
+
+ CvMat* err; //error X-hX
+ double prevErrNorm, errNorm;
+ double lambda;
+ CvTermCriteria criteria;
+ int iters;
+
+ CvMat** U; //size of array is equal to number of cameras
+ CvMat** V; //size of array is equal to number of points
+ CvMat** inv_V_star; //inverse of V*
+
+ CvMat* A;
+ CvMat* B;
+ CvMat* W;
+
+ CvMat* X; //measurement
+ CvMat* hX; //current measurement extimation given new parameter vector
+
+ CvMat* prevP; //current already accepted parameter.
+ CvMat* P; // parameters used to evaluate function with new params
+ // this parameters may be rejected
+
+ CvMat* deltaP; //computed increase of parameters (result of normal system solution )
+
+ CvMat** ea; // sum_i AijT * e_ij , used as right part of normal equation
+ // length of array is j = number of cameras
+ CvMat** eb; // sum_j BijT * e_ij , used as right part of normal equation
+ // length of array is i = number of points
+
+ CvMat** Yj; //length of array is i = num_points
+
+ CvMat* S; //big matrix of block Sjk , each block has size num_cam_params x num_cam_params
+
+ CvMat* JtJ_diag; //diagonal of JtJ, used to backup diagonal elements before augmentation
+
+ CvMat* Vis_index; // matrix which element is index of measurement for point i and camera j
+
+ int num_cams;
+ int num_points;
+ int num_err_param;
+ int num_cam_param;
+ int num_point_param;
+
+ //target function and jacobian pointers, which needs to be initialized
+ void (*fjac)(int i, int j, Mat& point_params, Mat& cam_params, Mat& A, Mat& B, void* data);
+ void (*func)(int i, int j, Mat& point_params, Mat& cam_params, Mat& estim, void* data );
+
+ void* data;
+};
+
+struct DefaultRngAuto
+{
+ const static uint64 def_state = (uint64)-1;
+ const uint64 old_state;
+
+ DefaultRngAuto() : old_state(theRNG().state) { theRNG().state = def_state; }
+ ~DefaultRngAuto() { theRNG().state = old_state; }
+
+ DefaultRngAuto& operator=(const DefaultRngAuto&);
+};
+
+ /****************************************************************************************\
+ * Calonder Descriptor *
+ \****************************************************************************************/
+ /*!
+ A pseudo-random number generator usable with std::random_shuffle.
+ */
+ typedef cv::RNG CalonderRng;
+ typedef unsigned int int_type;
+
+ //----------------------------
+ //randomized_tree.h
+
+ //class RTTester;
+
+ //namespace features {
+ static const size_t DEFAULT_REDUCED_NUM_DIM = 176;
+ static const float LOWER_QUANT_PERC = .03f;
+ static const float UPPER_QUANT_PERC = .92f;
+ static const int PATCH_SIZE = 32;
+ static const int DEFAULT_DEPTH = 9;
+ static const int DEFAULT_VIEWS = 5000;
+ struct RTreeNode;
+
+ struct BaseKeypoint
+ {
+ int x;
+ int y;
+ IplImage* image;
+
+ BaseKeypoint()
+ : x(0), y(0), image(NULL)
+ {}
+
+ BaseKeypoint(int x, int y, IplImage* image)
+ : x(x), y(y), image(image)
+ {}
+ };
+
+ class CSMatrixGenerator {
+ public:
+ typedef enum { PDT_GAUSS=1, PDT_BERNOULLI, PDT_DBFRIENDLY } PHI_DISTR_TYPE;
+ ~CSMatrixGenerator();
+ static float* getCSMatrix(int m, int n, PHI_DISTR_TYPE dt); // do NOT free returned pointer
+
+
+ private:
+ static float *cs_phi_; // matrix for compressive sensing
+ static int cs_phi_m_, cs_phi_n_;
+ };
+
+ class CV_EXPORTS RandomizedTree
+ {
+ public:
+ friend class RTreeClassifier;
+ //friend class ::RTTester;
+
+
+ RandomizedTree();
+ ~RandomizedTree();
+
+ void train(std::vector<BaseKeypoint> const& base_set, cv::RNG &rng,
+ int depth, int views, size_t reduced_num_dim, int num_quant_bits);
+ void train(std::vector<BaseKeypoint> const& base_set, cv::RNG &rng,
+ PatchGenerator &make_patch, int depth, int views, size_t reduced_num_dim,
+ int num_quant_bits);
+
+ // following two funcs are EXPERIMENTAL (do not use unless you know exactly what you do)
+ static void quantizeVector(float *vec, int dim, int N, float bnds[2], int clamp_mode=0);
+ static void quantizeVector(float *src, int dim, int N, float bnds[2], uchar *dst);
+
+ // patch_data must be a 32x32 array (no row padding)
+ float* getPosterior(uchar* patch_data);
+ const float* getPosterior(uchar* patch_data) const;
+ uchar* getPosterior2(uchar* patch_data);
+
+ void read(const char* file_name, int num_quant_bits);
+ void read(std::istream &is, int num_quant_bits);
+ void write(const char* file_name) const;
+ void write(std::ostream &os) const;
+
+ int classes() { return classes_; }
+ int depth() { return depth_; }
+
+ //void setKeepFloatPosteriors(bool b) { keep_float_posteriors_ = b; }
+ void discardFloatPosteriors() { freePosteriors(1); }
+
+ inline void applyQuantization(int num_quant_bits) { makePosteriors2(num_quant_bits); }
+
+ // debug
+ void savePosteriors(std::string url, bool append=false);
+ void savePosteriors2(std::string url, bool append=false);
+
+ private:
+ int classes_;
+ int depth_;
+ int num_leaves_;
+ std::vector<RTreeNode> nodes_;
+ float **posteriors_; // 16-bytes aligned posteriors
+ uchar **posteriors2_; // 16-bytes aligned posteriors
+ std::vector<int> leaf_counts_;
+
+ void createNodes(int num_nodes, cv::RNG &rng);
+ void allocPosteriorsAligned(int num_leaves, int num_classes);
+ void freePosteriors(int which); // which: 1=posteriors_, 2=posteriors2_, 3=both
+ void init(int classes, int depth, cv::RNG &rng);
+ void addExample(int class_id, uchar* patch_data);
+ void finalize(size_t reduced_num_dim, int num_quant_bits);
+ int getIndex(uchar* patch_data) const;
+ inline float* getPosteriorByIndex(int index);
+ inline uchar* getPosteriorByIndex2(int index);
+ inline const float* getPosteriorByIndex(int index) const;
+ //void makeRandomMeasMatrix(float *cs_phi, PHI_DISTR_TYPE dt, size_t reduced_num_dim);
+ void convertPosteriorsToChar();
+ void makePosteriors2(int num_quant_bits);
+ void compressLeaves(size_t reduced_num_dim);
+ void estimateQuantPercForPosteriors(float perc[2]);
+ };
+
+ struct RTreeNode
+ {
+ short offset1, offset2;
+
+ RTreeNode() {}
+
+ RTreeNode(uchar x1, uchar y1, uchar x2, uchar y2)
+ : offset1(y1*PATCH_SIZE + x1),
+ offset2(y2*PATCH_SIZE + x2)
+ {}
+
+ //! Left child on 0, right child on 1
+ inline bool operator() (uchar* patch_data) const
+ {
+ return patch_data[offset1] > patch_data[offset2];
+ }
+ };
+
+
+
+ //} // namespace features
+ //----------------------------
+ //rtree_classifier.h
+ //class RTTester;
+
+ //namespace features {
+
+ class CV_EXPORTS RTreeClassifier
+ {
+ public:
+ //friend class ::RTTester;
+ static const int DEFAULT_TREES = 48;
+ static const size_t DEFAULT_NUM_QUANT_BITS = 4;
+
+ RTreeClassifier();
+
+ //modified
+ void train(std::vector<BaseKeypoint> const& base_set,
+ cv::RNG &rng,
+ int num_trees = RTreeClassifier::DEFAULT_TREES,
+ int depth = DEFAULT_DEPTH,
+ int views = DEFAULT_VIEWS,
+ size_t reduced_num_dim = DEFAULT_REDUCED_NUM_DIM,
+ int num_quant_bits = DEFAULT_NUM_QUANT_BITS, bool print_status = true);
+ void train(std::vector<BaseKeypoint> const& base_set,
+ cv::RNG &rng,
+ PatchGenerator &make_patch,
+ int num_trees = RTreeClassifier::DEFAULT_TREES,
+ int depth = DEFAULT_DEPTH,
+ int views = DEFAULT_VIEWS,
+ size_t reduced_num_dim = DEFAULT_REDUCED_NUM_DIM,
+ int num_quant_bits = DEFAULT_NUM_QUANT_BITS, bool print_status = true);
+
+ // sig must point to a memory block of at least classes()*sizeof(float|uchar) bytes
+ void getSignature(IplImage *patch, uchar *sig);
+ void getSignature(IplImage *patch, float *sig);
+ void getSparseSignature(IplImage *patch, float *sig, float thresh);
+ // TODO: deprecated in favor of getSignature overload, remove
+ void getFloatSignature(IplImage *patch, float *sig) { getSignature(patch, sig); }
+
+ static int countNonZeroElements(float *vec, int n, double tol=1e-10);
+ static inline void safeSignatureAlloc(uchar **sig, int num_sig=1, int sig_len=176);
+ static inline uchar* safeSignatureAlloc(int num_sig=1, int sig_len=176);
+
+ inline int classes() { return classes_; }
+ inline int original_num_classes() { return original_num_classes_; }
+
+ void setQuantization(int num_quant_bits);
+ void discardFloatPosteriors();
+
+ void read(const char* file_name);
+ void read(std::istream &is);
+ void write(const char* file_name) const;
+ void write(std::ostream &os) const;
+
+ // experimental and debug
+ void saveAllFloatPosteriors(std::string file_url);
+ void saveAllBytePosteriors(std::string file_url);
+ void setFloatPosteriorsFromTextfile_176(std::string url);
+ float countZeroElements();
+
+ std::vector<RandomizedTree> trees_;
+
+ private:
+ int classes_;
+ int num_quant_bits_;
+ uchar **posteriors_;
+ ushort *ptemp_;
+ int original_num_classes_;
+ bool keep_floats_;
+ };
+
+CV_EXPORTS bool find4QuadCornerSubpix(const Mat& img, std::vector<Point2f>& corners, Size region_size);
+
+
+class CV_EXPORTS BackgroundSubtractor
+{
+public:
+ virtual ~BackgroundSubtractor();
+ virtual void operator()(const Mat& image, Mat& fgmask, double learningRate=0);
+};
+
+
+class CV_EXPORTS BackgroundSubtractorMOG : public BackgroundSubtractor
+{
+public:
+ BackgroundSubtractorMOG();
+ BackgroundSubtractorMOG(int history, int nmixtures, double backgroundRatio, double noiseSigma=0);
+ virtual ~BackgroundSubtractorMOG();
+ virtual void operator()(const Mat& image, Mat& fgmask, double learningRate=0);
+
+ virtual void initialize(Size frameSize, int frameType);
+
+ Size frameSize;
+ int frameType;
+ Mat bgmodel;
+ int nframes;
+ int history;
+ int nmixtures;
+ double varThreshold;
+ double backgroundRatio;
+ double noiseSigma;
+};
+
+
+// CvAffinePose: defines a parameterized affine transformation of an image patch.
+// An image patch is rotated on angle phi (in degrees), then scaled lambda1 times
+// along horizontal and lambda2 times along vertical direction, and then rotated again
+// on angle (theta - phi).
+class CV_EXPORTS CvAffinePose
+{
+public:
+ float phi;
+ float theta;
+ float lambda1;
+ float lambda2;
+};
+
+
+class CV_EXPORTS OneWayDescriptor
+{
+public:
+ OneWayDescriptor();
+ ~OneWayDescriptor();
+
+ // allocates memory for given descriptor parameters
+ void Allocate(int pose_count, CvSize size, int nChannels);
+
+ // GenerateSamples: generates affine transformed patches with averaging them over small transformation variations.
+ // If external poses and transforms were specified, uses them instead of generating random ones
+ // - pose_count: the number of poses to be generated
+ // - frontal: the input patch (can be a roi in a larger image)
+ // - norm: if nonzero, normalizes the output patch so that the sum of pixel intensities is 1
+ void GenerateSamples(int pose_count, IplImage* frontal, int norm = 0);
+
+ // GenerateSamplesFast: generates affine transformed patches with averaging them over small transformation variations.
+ // Uses precalculated transformed pca components.
+ // - frontal: the input patch (can be a roi in a larger image)
+ // - pca_hr_avg: pca average vector
+ // - pca_hr_eigenvectors: pca eigenvectors
+ // - pca_descriptors: an array of precomputed descriptors of pca components containing their affine transformations
+ // pca_descriptors[0] corresponds to the average, pca_descriptors[1]-pca_descriptors[pca_dim] correspond to eigenvectors
+ void GenerateSamplesFast(IplImage* frontal, CvMat* pca_hr_avg,
+ CvMat* pca_hr_eigenvectors, OneWayDescriptor* pca_descriptors);
+
+ // sets the poses and corresponding transforms
+ void SetTransforms(CvAffinePose* poses, CvMat** transforms);
+
+ // Initialize: builds a descriptor.
+ // - pose_count: the number of poses to build. If poses were set externally, uses them rather than generating random ones
+ // - frontal: input patch. Can be a roi in a larger image
+ // - feature_name: the feature name to be associated with the descriptor
+ // - norm: if 1, the affine transformed patches are normalized so that their sum is 1
+ void Initialize(int pose_count, IplImage* frontal, const char* feature_name = 0, int norm = 0);
+
+ // InitializeFast: builds a descriptor using precomputed descriptors of pca components
+ // - pose_count: the number of poses to build
+ // - frontal: input patch. Can be a roi in a larger image
+ // - feature_name: the feature name to be associated with the descriptor
+ // - pca_hr_avg: average vector for PCA
+ // - pca_hr_eigenvectors: PCA eigenvectors (one vector per row)
+ // - pca_descriptors: precomputed descriptors of PCA components, the first descriptor for the average vector
+ // followed by the descriptors for eigenvectors
+ void InitializeFast(int pose_count, IplImage* frontal, const char* feature_name,
+ CvMat* pca_hr_avg, CvMat* pca_hr_eigenvectors, OneWayDescriptor* pca_descriptors);
+
+ // ProjectPCASample: unwarps an image patch into a vector and projects it into PCA space
+ // - patch: input image patch
+ // - avg: PCA average vector
+ // - eigenvectors: PCA eigenvectors, one per row
+ // - pca_coeffs: output PCA coefficients
+ void ProjectPCASample(IplImage* patch, CvMat* avg, CvMat* eigenvectors, CvMat* pca_coeffs) const;
+
+ // InitializePCACoeffs: projects all warped patches into PCA space
+ // - avg: PCA average vector
+ // - eigenvectors: PCA eigenvectors, one per row
+ void InitializePCACoeffs(CvMat* avg, CvMat* eigenvectors);
+
+ // EstimatePose: finds the closest match between an input patch and a set of patches with different poses
+ // - patch: input image patch
+ // - pose_idx: the output index of the closest pose
+ // - distance: the distance to the closest pose (L2 distance)
+ void EstimatePose(IplImage* patch, int& pose_idx, float& distance) const;
+
+ // EstimatePosePCA: finds the closest match between an input patch and a set of patches with different poses.
+ // The distance between patches is computed in PCA space
+ // - patch: input image patch
+ // - pose_idx: the output index of the closest pose
+ // - distance: distance to the closest pose (L2 distance in PCA space)
+ // - avg: PCA average vector. If 0, matching without PCA is used
+ // - eigenvectors: PCA eigenvectors, one per row
+ void EstimatePosePCA(CvArr* patch, int& pose_idx, float& distance, CvMat* avg, CvMat* eigenvalues) const;
+
+ // GetPatchSize: returns the size of each image patch after warping (2 times smaller than the input patch)
+ CvSize GetPatchSize() const
+ {
+ return m_patch_size;
+ }
+
+ // GetInputPatchSize: returns the required size of the patch that the descriptor is built from
+ // (2 time larger than the patch after warping)
+ CvSize GetInputPatchSize() const
+ {
+ return cvSize(m_patch_size.width*2, m_patch_size.height*2);
+ }
+
+ // GetPatch: returns a patch corresponding to specified pose index
+ // - index: pose index
+ // - return value: the patch corresponding to specified pose index
+ IplImage* GetPatch(int index);
+
+ // GetPose: returns a pose corresponding to specified pose index
+ // - index: pose index
+ // - return value: the pose corresponding to specified pose index
+ CvAffinePose GetPose(int index) const;
+
+ // Save: saves all patches with different poses to a specified path
+ void Save(const char* path);
+
+ // ReadByName: reads a descriptor from a file storage
+ // - fs: file storage
+ // - parent: parent node
+ // - name: node name
+ // - return value: 1 if succeeded, 0 otherwise
+ int ReadByName(CvFileStorage* fs, CvFileNode* parent, const char* name);
+
+ // Write: writes a descriptor into a file storage
+ // - fs: file storage
+ // - name: node name
+ void Write(CvFileStorage* fs, const char* name);
+
+ // GetFeatureName: returns a name corresponding to a feature
+ const char* GetFeatureName() const;
+
+ // GetCenter: returns the center of the feature
+ CvPoint GetCenter() const;
+
+ void SetPCADimHigh(int pca_dim_high) {m_pca_dim_high = pca_dim_high;};
+ void SetPCADimLow(int pca_dim_low) {m_pca_dim_low = pca_dim_low;};
+
+ int GetPCADimLow() const;
+ int GetPCADimHigh() const;
+
+ CvMat** GetPCACoeffs() const {return m_pca_coeffs;}
+
+protected:
+ int m_pose_count; // the number of poses
+ CvSize m_patch_size; // size of each image
+ IplImage** m_samples; // an array of length m_pose_count containing the patch in different poses
+ IplImage* m_input_patch;
+ IplImage* m_train_patch;
+ CvMat** m_pca_coeffs; // an array of length m_pose_count containing pca decomposition of the patch in different poses
+ CvAffinePose* m_affine_poses; // an array of poses
+ CvMat** m_transforms; // an array of affine transforms corresponding to poses
+
+ std::string m_feature_name; // the name of the feature associated with the descriptor
+ CvPoint m_center; // the coordinates of the feature (the center of the input image ROI)
+
+ int m_pca_dim_high; // the number of descriptor pca components to use for generating affine poses
+ int m_pca_dim_low; // the number of pca components to use for comparison
+};
+
+
+// OneWayDescriptorBase: encapsulates functionality for training/loading a set of one way descriptors
+// and finding the nearest closest descriptor to an input feature
+class CV_EXPORTS OneWayDescriptorBase
+{
+public:
+
+ // creates an instance of OneWayDescriptor from a set of training files
+ // - patch_size: size of the input (large) patch
+ // - pose_count: the number of poses to generate for each descriptor
+ // - train_path: path to training files
+ // - pca_config: the name of the file that contains PCA for small patches (2 times smaller
+ // than patch_size each dimension
+ // - pca_hr_config: the name of the file that contains PCA for large patches (of patch_size size)
+ // - pca_desc_config: the name of the file that contains descriptors of PCA components
+ OneWayDescriptorBase(CvSize patch_size, int pose_count, const char* train_path = 0, const char* pca_config = 0,
+ const char* pca_hr_config = 0, const char* pca_desc_config = 0, int pyr_levels = 1,
+ int pca_dim_high = 100, int pca_dim_low = 100);
+
+ ~OneWayDescriptorBase();
+
+ // Allocate: allocates memory for a given number of descriptors
+ void Allocate(int train_feature_count);
+
+ // AllocatePCADescriptors: allocates memory for pca descriptors
+ void AllocatePCADescriptors();
+
+ // returns patch size
+ CvSize GetPatchSize() const {return m_patch_size;};
+ // returns the number of poses for each descriptor
+ int GetPoseCount() const {return m_pose_count;};
+
+ // returns the number of pyramid levels
+ int GetPyrLevels() const {return m_pyr_levels;};
+
+ // returns the number of descriptors
+ int GetDescriptorCount() const {return m_train_feature_count;};
+
+ // CreateDescriptorsFromImage: creates descriptors for each of the input features
+ // - src: input image
+ // - features: input features
+ // - pyr_levels: the number of pyramid levels
+ void CreateDescriptorsFromImage(IplImage* src, const std::vector<cv::KeyPoint>& features);
+
+ // CreatePCADescriptors: generates descriptors for PCA components, needed for fast generation of feature descriptors
+ void CreatePCADescriptors();
+
+ // returns a feature descriptor by feature index
+ const OneWayDescriptor* GetDescriptor(int desc_idx) const {return &m_descriptors[desc_idx];};
+
+ // FindDescriptor: finds the closest descriptor
+ // - patch: input image patch
+ // - desc_idx: output index of the closest descriptor to the input patch
+ // - pose_idx: output index of the closest pose of the closest descriptor to the input patch
+ // - distance: distance from the input patch to the closest feature pose
+ // - _scales: scales of the input patch for each descriptor
+ // - scale_ranges: input scales variation (float[2])
+ void FindDescriptor(IplImage* patch, int& desc_idx, int& pose_idx, float& distance, float* _scale = 0, float* scale_ranges = 0) const;
+
+ // - patch: input image patch
+ // - n: number of the closest indexes
+ // - desc_idxs: output indexes of the closest descriptor to the input patch (n)
+ // - pose_idx: output indexes of the closest pose of the closest descriptor to the input patch (n)
+ // - distances: distance from the input patch to the closest feature pose (n)
+ // - _scales: scales of the input patch
+ // - scale_ranges: input scales variation (float[2])
+ void FindDescriptor(IplImage* patch, int n, std::vector<int>& desc_idxs, std::vector<int>& pose_idxs,
+ std::vector<float>& distances, std::vector<float>& _scales, float* scale_ranges = 0) const;
+
+ // FindDescriptor: finds the closest descriptor
+ // - src: input image
+ // - pt: center of the feature
+ // - desc_idx: output index of the closest descriptor to the input patch
+ // - pose_idx: output index of the closest pose of the closest descriptor to the input patch
+ // - distance: distance from the input patch to the closest feature pose
+ void FindDescriptor(IplImage* src, cv::Point2f pt, int& desc_idx, int& pose_idx, float& distance) const;
+
+ // InitializePoses: generates random poses
+ void InitializePoses();
+
+ // InitializeTransformsFromPoses: generates 2x3 affine matrices from poses (initializes m_transforms)
+ void InitializeTransformsFromPoses();
+
+ // InitializePoseTransforms: subsequently calls InitializePoses and InitializeTransformsFromPoses
+ void InitializePoseTransforms();
+
+ // InitializeDescriptor: initializes a descriptor
+ // - desc_idx: descriptor index
+ // - train_image: image patch (ROI is supported)
+ // - feature_label: feature textual label
+ void InitializeDescriptor(int desc_idx, IplImage* train_image, const char* feature_label);
+
+ void InitializeDescriptor(int desc_idx, IplImage* train_image, const cv::KeyPoint& keypoint, const char* feature_label);
+
+ // InitializeDescriptors: load features from an image and create descriptors for each of them
+ void InitializeDescriptors(IplImage* train_image, const vector<cv::KeyPoint>& features,
+ const char* feature_label = "", int desc_start_idx = 0);
+
+ // LoadPCADescriptors: loads PCA descriptors from a file
+ // - filename: input filename
+ int LoadPCADescriptors(const char* filename);
+
+ // SavePCADescriptors: saves PCA descriptors to a file
+ // - filename: output filename
+ void SavePCADescriptors(const char* filename);
+
+ // SetPCAHigh: sets the high resolution pca matrices (copied to internal structures)
+ void SetPCAHigh(CvMat* avg, CvMat* eigenvectors);
+
+ // SetPCALow: sets the low resolution pca matrices (copied to internal structures)
+ void SetPCALow(CvMat* avg, CvMat* eigenvectors);
+
+ int GetLowPCA(CvMat** avg, CvMat** eigenvectors)
+ {
+ *avg = m_pca_avg;
+ *eigenvectors = m_pca_eigenvectors;
+ return m_pca_dim_low;
+ };
+
+ void ConvertDescriptorsArrayToTree(); // Converting pca_descriptors array to KD tree
+
+
+protected:
+ CvSize m_patch_size; // patch size
+ int m_pose_count; // the number of poses for each descriptor
+ int m_train_feature_count; // the number of the training features
+ OneWayDescriptor* m_descriptors; // array of train feature descriptors
+ CvMat* m_pca_avg; // PCA average Vector for small patches
+ CvMat* m_pca_eigenvectors; // PCA eigenvectors for small patches
+ CvMat* m_pca_hr_avg; // PCA average Vector for large patches
+ CvMat* m_pca_hr_eigenvectors; // PCA eigenvectors for large patches
+ OneWayDescriptor* m_pca_descriptors; // an array of PCA descriptors
+
+ cv::flann::Index* m_pca_descriptors_tree;
+ CvMat* m_pca_descriptors_matrix;
+
+ CvAffinePose* m_poses; // array of poses
+ CvMat** m_transforms; // array of affine transformations corresponding to poses
+
+ int m_pca_dim_high;
+ int m_pca_dim_low;
+
+ int m_pyr_levels;
+
+};
+
+class OneWayDescriptorObject : public OneWayDescriptorBase
+{
+public:
+ // creates an instance of OneWayDescriptorObject from a set of training files
+ // - patch_size: size of the input (large) patch
+ // - pose_count: the number of poses to generate for each descriptor
+ // - train_path: path to training files
+ // - pca_config: the name of the file that contains PCA for small patches (2 times smaller
+ // than patch_size each dimension
+ // - pca_hr_config: the name of the file that contains PCA for large patches (of patch_size size)
+ // - pca_desc_config: the name of the file that contains descriptors of PCA components
+ OneWayDescriptorObject(CvSize patch_size, int pose_count, const char* train_path, const char* pca_config,
+ const char* pca_hr_config = 0, const char* pca_desc_config = 0, int pyr_levels = 1);
+
+ ~OneWayDescriptorObject();
+
+ // Allocate: allocates memory for a given number of features
+ // - train_feature_count: the total number of features
+ // - object_feature_count: the number of features extracted from the object
+ void Allocate(int train_feature_count, int object_feature_count);
+
+
+ void SetLabeledFeatures(const vector<cv::KeyPoint>& features) {m_train_features = features;};
+ vector<cv::KeyPoint>& GetLabeledFeatures() {return m_train_features;};
+ const vector<cv::KeyPoint>& GetLabeledFeatures() const {return m_train_features;};
+ vector<cv::KeyPoint> _GetLabeledFeatures() const;
+
+ // IsDescriptorObject: returns 1 if descriptor with specified index is positive, otherwise 0
+ int IsDescriptorObject(int desc_idx) const;
+
+ // MatchPointToPart: returns the part number of a feature if it matches one of the object parts, otherwise -1
+ int MatchPointToPart(CvPoint pt) const;
+
+ // GetDescriptorPart: returns the part number of the feature corresponding to a specified descriptor
+ // - desc_idx: descriptor index
+ int GetDescriptorPart(int desc_idx) const;
+
+
+ void InitializeObjectDescriptors(IplImage* train_image, const vector<cv::KeyPoint>& features,
+ const char* feature_label, int desc_start_idx = 0, float scale = 1.0f,
+ int is_background = 0);
+
+ // GetObjectFeatureCount: returns the number of object features
+ int GetObjectFeatureCount() const {return m_object_feature_count;};
+
+protected:
+ int* m_part_id; // contains part id for each of object descriptors
+ vector<cv::KeyPoint> m_train_features; // train features
+ int m_object_feature_count; // the number of the positive features
+
+};
+
+
+}
+
+#endif /* __cplusplus */
+
+#endif /* __CVAUX_HPP__ */
+
+/* End of file. */