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