1 Feature Detection and Description
2 =================================
8 .. ocv:class:: RandomizedTree
10 Class containing a base structure for ``RTreeClassifier``. ::
12 class CV_EXPORTS RandomizedTree
15 friend class RTreeClassifier;
20 void train(std::vector<BaseKeypoint> const& base_set,
21 RNG &rng, int depth, int views,
22 size_t reduced_num_dim, int num_quant_bits);
23 void train(std::vector<BaseKeypoint> const& base_set,
24 RNG &rng, PatchGenerator &make_patch, int depth,
25 int views, size_t reduced_num_dim, int num_quant_bits);
27 // next two functions are EXPERIMENTAL
28 //(do not use unless you know exactly what you do)
29 static void quantizeVector(float *vec, int dim, int N, float bnds[2],
31 static void quantizeVector(float *src, int dim, int N, float bnds[2],
34 // patch_data must be a 32x32 array (no row padding)
35 float* getPosterior(uchar* patch_data);
36 const float* getPosterior(uchar* patch_data) const;
37 uchar* getPosterior2(uchar* patch_data);
39 void read(const char* file_name, int num_quant_bits);
40 void read(std::istream &is, int num_quant_bits);
41 void write(const char* file_name) const;
42 void write(std::ostream &os) const;
44 int classes() { return classes_; }
45 int depth() { return depth_; }
47 void discardFloatPosteriors() { freePosteriors(1); }
49 inline void applyQuantization(int num_quant_bits)
50 { makePosteriors2(num_quant_bits); }
56 std::vector<RTreeNode> nodes_;
57 float **posteriors_; // 16-byte aligned posteriors
58 uchar **posteriors2_; // 16-byte aligned posteriors
59 std::vector<int> leaf_counts_;
61 void createNodes(int num_nodes, RNG &rng);
62 void allocPosteriorsAligned(int num_leaves, int num_classes);
63 void freePosteriors(int which);
64 // which: 1=posteriors_, 2=posteriors2_, 3=both
65 void init(int classes, int depth, RNG &rng);
66 void addExample(int class_id, uchar* patch_data);
67 void finalize(size_t reduced_num_dim, int num_quant_bits);
68 int getIndex(uchar* patch_data) const;
69 inline float* getPosteriorByIndex(int index);
70 inline uchar* getPosteriorByIndex2(int index);
71 inline const float* getPosteriorByIndex(int index) const;
72 void convertPosteriorsToChar();
73 void makePosteriors2(int num_quant_bits);
74 void compressLeaves(size_t reduced_num_dim);
75 void estimateQuantPercForPosteriors(float perc[2]);
80 * : PYTHON : An example using Randomized Tree training for letter recognition can be found at opencv_source_code/samples/python2/letter_recog.py
83 -------------------------
84 Trains a randomized tree using an input set of keypoints.
86 .. ocv:function:: void RandomizedTree::train( vector<BaseKeypoint> const& base_set, RNG & rng, int depth, int views, size_t reduced_num_dim, int num_quant_bits )
88 .. ocv:function:: void RandomizedTree::train( vector<BaseKeypoint> const& base_set, RNG & rng, PatchGenerator & make_patch, int depth, int views, size_t reduced_num_dim, int num_quant_bits )
90 :param base_set: Vector of the ``BaseKeypoint`` type. It contains image keypoints used for training.
92 :param rng: Random-number generator used for training.
94 :param make_patch: Patch generator used for training.
96 :param depth: Maximum tree depth.
98 :param views: Number of random views of each keypoint neighborhood to generate.
100 :param reduced_num_dim: Number of dimensions used in the compressed signature.
102 :param num_quant_bits: Number of bits used for quantization.
106 * : An example on training a Random Tree Classifier for letter recognition can be found at opencv_source_code\samples\cpp\letter_recog.cpp
109 ------------------------
110 Reads a pre-saved randomized tree from a file or stream.
112 .. ocv:function:: RandomizedTree::read(const char* file_name, int num_quant_bits)
114 .. ocv:function:: RandomizedTree::read(std::istream &is, int num_quant_bits)
116 :param file_name: Name of the file that contains randomized tree data.
118 :param is: Input stream associated with the file that contains randomized tree data.
120 :param num_quant_bits: Number of bits used for quantization.
124 RandomizedTree::write
125 -------------------------
126 Writes the current randomized tree to a file or stream.
128 .. ocv:function:: void RandomizedTree::write(const char* file_name) const
130 .. ocv:function:: void RandomizedTree::write(std::ostream &os) const
132 :param file_name: Name of the file where randomized tree data is stored.
134 :param os: Output stream associated with the file where randomized tree data is stored.
138 RandomizedTree::applyQuantization
139 -------------------------------------
140 .. ocv:function:: void RandomizedTree::applyQuantization(int num_quant_bits)
142 Applies quantization to the current randomized tree.
144 :param num_quant_bits: Number of bits used for quantization.
149 .. ocv:struct:: RTreeNode
151 Class containing a base structure for ``RandomizedTree``. ::
155 short offset1, offset2;
159 RTreeNode(uchar x1, uchar y1, uchar x2, uchar y2)
160 : offset1(y1*PATCH_SIZE + x1),
161 offset2(y2*PATCH_SIZE + x2)
164 //! Left child on 0, right child on 1
165 inline bool operator() (uchar* patch_data) const
167 return patch_data[offset1] > patch_data[offset2];
175 .. ocv:class:: RTreeClassifier
177 Class containing ``RTreeClassifier``. It represents the Calonder descriptor originally introduced by Michael Calonder. ::
179 class CV_EXPORTS RTreeClassifier
182 static const int DEFAULT_TREES = 48;
183 static const size_t DEFAULT_NUM_QUANT_BITS = 4;
187 void train(std::vector<BaseKeypoint> const& base_set,
189 int num_trees = RTreeClassifier::DEFAULT_TREES,
190 int depth = DEFAULT_DEPTH,
191 int views = DEFAULT_VIEWS,
192 size_t reduced_num_dim = DEFAULT_REDUCED_NUM_DIM,
193 int num_quant_bits = DEFAULT_NUM_QUANT_BITS,
194 bool print_status = true);
195 void train(std::vector<BaseKeypoint> const& base_set,
197 PatchGenerator &make_patch,
198 int num_trees = RTreeClassifier::DEFAULT_TREES,
199 int depth = DEFAULT_DEPTH,
200 int views = DEFAULT_VIEWS,
201 size_t reduced_num_dim = DEFAULT_REDUCED_NUM_DIM,
202 int num_quant_bits = DEFAULT_NUM_QUANT_BITS,
203 bool print_status = true);
205 // sig must point to a memory block of at least
206 //classes()*sizeof(float|uchar) bytes
207 void getSignature(IplImage *patch, uchar *sig);
208 void getSignature(IplImage *patch, float *sig);
209 void getSparseSignature(IplImage *patch, float *sig,
212 static int countNonZeroElements(float *vec, int n, double tol=1e-10);
213 static inline void safeSignatureAlloc(uchar **sig, int num_sig=1,
215 static inline uchar* safeSignatureAlloc(int num_sig=1,
218 inline int classes() { return classes_; }
219 inline int original_num_classes()
220 { return original_num_classes_; }
222 void setQuantization(int num_quant_bits);
223 void discardFloatPosteriors();
225 void read(const char* file_name);
226 void read(std::istream &is);
227 void write(const char* file_name) const;
228 void write(std::ostream &os) const;
230 std::vector<RandomizedTree> trees_;
237 int original_num_classes_;
243 RTreeClassifier::train
244 --------------------------
245 Trains a randomized tree classifier using an input set of keypoints.
247 .. ocv:function:: void RTreeClassifier::train( vector<BaseKeypoint> const& base_set, RNG & rng, int num_trees=RTreeClassifier::DEFAULT_TREES, int depth=RandomizedTree::DEFAULT_DEPTH, int views=RandomizedTree::DEFAULT_VIEWS, size_t reduced_num_dim=RandomizedTree::DEFAULT_REDUCED_NUM_DIM, int num_quant_bits=DEFAULT_NUM_QUANT_BITS )
249 .. ocv:function:: void RTreeClassifier::train( vector<BaseKeypoint> const& base_set, RNG & rng, PatchGenerator & make_patch, int num_trees=RTreeClassifier::DEFAULT_TREES, int depth=RandomizedTree::DEFAULT_DEPTH, int views=RandomizedTree::DEFAULT_VIEWS, size_t reduced_num_dim=RandomizedTree::DEFAULT_REDUCED_NUM_DIM, int num_quant_bits=DEFAULT_NUM_QUANT_BITS )
251 :param base_set: Vector of the ``BaseKeypoint`` type. It contains image keypoints used for training.
253 :param rng: Random-number generator used for training.
255 :param make_patch: Patch generator used for training.
257 :param num_trees: Number of randomized trees used in ``RTreeClassificator`` .
259 :param depth: Maximum tree depth.
261 :param views: Number of random views of each keypoint neighborhood to generate.
263 :param reduced_num_dim: Number of dimensions used in the compressed signature.
265 :param num_quant_bits: Number of bits used for quantization.
268 RTreeClassifier::getSignature
269 ---------------------------------
270 Returns a signature for an image patch.
272 .. ocv:function:: void RTreeClassifier::getSignature(IplImage *patch, uchar *sig)
274 .. ocv:function:: void RTreeClassifier::getSignature(IplImage *patch, float *sig)
276 :param patch: Image patch to calculate the signature for.
277 :param sig: Output signature (array dimension is ``reduced_num_dim)`` .
281 RTreeClassifier::getSparseSignature
282 ---------------------------------------
283 Returns a sparse signature for an image patch
285 .. ocv:function:: void RTreeClassifier::getSparseSignature(IplImage *patch, float *sig, float thresh)
287 :param patch: Image patch to calculate the signature for.
289 :param sig: Output signature (array dimension is ``reduced_num_dim)`` .
291 :param thresh: Threshold used for compressing the signature.
293 Returns a signature for an image patch similarly to ``getSignature`` but uses a threshold for removing all signature elements below the threshold so that the signature is compressed.
296 RTreeClassifier::countNonZeroElements
297 -----------------------------------------
298 Returns the number of non-zero elements in an input array.
300 .. ocv:function:: static int RTreeClassifier::countNonZeroElements(float *vec, int n, double tol=1e-10)
302 :param vec: Input vector containing float elements.
304 :param n: Input vector size.
306 :param tol: Threshold used for counting elements. All elements less than ``tol`` are considered as zero elements.
310 RTreeClassifier::read
311 -------------------------
312 Reads a pre-saved ``RTreeClassifier`` from a file or stream.
314 .. ocv:function:: void RTreeClassifier::read(const char* file_name)
316 .. ocv:function:: void RTreeClassifier::read( std::istream & is )
318 :param file_name: Name of the file that contains randomized tree data.
320 :param is: Input stream associated with the file that contains randomized tree data.
324 RTreeClassifier::write
325 --------------------------
326 Writes the current ``RTreeClassifier`` to a file or stream.
328 .. ocv:function:: void RTreeClassifier::write(const char* file_name) const
330 .. ocv:function:: void RTreeClassifier::write(std::ostream &os) const
332 :param file_name: Name of the file where randomized tree data is stored.
334 :param os: Output stream associated with the file where randomized tree data is stored.
338 RTreeClassifier::setQuantization
339 ------------------------------------
340 Applies quantization to the current randomized tree.
342 .. ocv:function:: void RTreeClassifier::setQuantization(int num_quant_bits)
344 :param num_quant_bits: Number of bits used for quantization.
346 The example below demonstrates the usage of ``RTreeClassifier`` for matching the features. The features are extracted from the test and train images with SURF. Output is
347 :math:`best\_corr` and
348 :math:`best\_corr\_idx` arrays that keep the best probabilities and corresponding features indices for every train feature. ::
350 CvMemStorage* storage = cvCreateMemStorage(0);
351 CvSeq *objectKeypoints = 0, *objectDescriptors = 0;
352 CvSeq *imageKeypoints = 0, *imageDescriptors = 0;
353 CvSURFParams params = cvSURFParams(500, 1);
354 cvExtractSURF( test_image, 0, &imageKeypoints, &imageDescriptors,
356 cvExtractSURF( train_image, 0, &objectKeypoints, &objectDescriptors,
359 RTreeClassifier detector;
360 int patch_width = PATCH_SIZE;
361 iint patch_height = PATCH_SIZE;
362 vector<BaseKeypoint> base_set;
365 for (i=0;i<(n_points > 0 ? n_points : objectKeypoints->total);i++)
367 point=(CvSURFPoint*)cvGetSeqElem(objectKeypoints,i);
369 BaseKeypoint(point->pt.x,point->pt.y,train_image));
373 RNG rng( cvGetTickCount() );
374 PatchGenerator gen(0,255,2,false,0.7,1.3,-CV_PI/3,CV_PI/3,
377 printf("RTree Classifier training...n");
378 detector.train(base_set,rng,gen,24,DEFAULT_DEPTH,2000,
379 (int)base_set.size(), detector.DEFAULT_NUM_QUANT_BITS);
382 float* signature = new float[detector.original_num_classes()];
385 if (imageKeypoints->total > 0)
387 best_corr = new float[imageKeypoints->total];
388 best_corr_idx = new int[imageKeypoints->total];
391 for(i=0; i < imageKeypoints->total; i++)
393 point=(CvSURFPoint*)cvGetSeqElem(imageKeypoints,i);
397 CvRect roi = cvRect((int)(point->pt.x) - patch_width/2,
398 (int)(point->pt.y) - patch_height/2,
399 patch_width, patch_height);
400 cvSetImageROI(test_image, roi);
401 roi = cvGetImageROI(test_image);
402 if(roi.width != patch_width || roi.height != patch_height)
404 best_corr_idx[i] = part_idx;
409 cvSetImageROI(test_image, roi);
410 IplImage* roi_image =
411 cvCreateImage(cvSize(roi.width, roi.height),
412 test_image->depth, test_image->nChannels);
413 cvCopy(test_image,roi_image);
415 detector.getSignature(roi_image, signature);
416 for (int j = 0; j< detector.original_num_classes();j++)
418 if (prob < signature[j])
425 best_corr_idx[i] = part_idx;
429 cvReleaseImage(&roi_image);
431 cvResetImageROI(test_image);