Orb.cpp
Go to the documentation of this file.
1 /*********************************************************************
2 * Software License Agreement (BSD License)
3 *
4 * Copyright (c) 2009, Willow Garage, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
17 * * Neither the name of the Willow Garage nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 *********************************************************************/
34 
39 #include <rtabmap/utilite/UStl.h>
40 
41 #include "opencv2/features2d/features2d.hpp"
42 #include "opencv2/imgproc/imgproc.hpp"
43 #include "opencv2/imgproc/imgproc_c.h"
44 #include <algorithm>
45 #include <iterator>
46 
47 #include "Orb.h"
49 
50 using namespace cv;
51 
52 namespace rtabmap
53 {
54 
55 const float HARRIS_K = 0.04f;
56 
61 static void
62 HarrisResponses(const Mat& img, std::vector<KeyPoint>& pts, int blockSize, float harris_k)
63 {
64  CV_Assert( img.type() == CV_8UC1 && blockSize*blockSize <= 2048 );
65 
66  size_t ptidx, ptsize = pts.size();
67 
68  const uchar* ptr00 = img.ptr<uchar>();
69  int step = (int)(img.step/img.elemSize1());
70  int r = blockSize/2;
71 
72  float scale = (1 << 2) * blockSize * 255.0f;
73  scale = 1.0f / scale;
74  float scale_sq_sq = scale * scale * scale * scale;
75 
76  AutoBuffer<int> ofsbuf(blockSize*blockSize);
77  int* ofs = ofsbuf;
78  for( int i = 0; i < blockSize; i++ )
79  for( int j = 0; j < blockSize; j++ )
80  ofs[i*blockSize + j] = (int)(i*step + j);
81 
82  for( ptidx = 0; ptidx < ptsize; ptidx++ )
83  {
84  int x0 = cvRound(pts[ptidx].pt.x - r);
85  int y0 = cvRound(pts[ptidx].pt.y - r);
86 
87  const uchar* ptr0 = ptr00 + y0*step + x0;
88  int a = 0, b = 0, c = 0;
89 
90  for( int k = 0; k < blockSize*blockSize; k++ )
91  {
92  const uchar* ptr = ptr0 + ofs[k];
93  int Ix = (ptr[1] - ptr[-1])*2 + (ptr[-step+1] - ptr[-step-1]) + (ptr[step+1] - ptr[step-1]);
94  int Iy = (ptr[step] - ptr[-step])*2 + (ptr[step-1] - ptr[-step-1]) + (ptr[step+1] - ptr[-step+1]);
95  a += Ix*Ix;
96  b += Iy*Iy;
97  c += Ix*Iy;
98  }
99  pts[ptidx].response = ((float)a * b - (float)c * c -
100  harris_k * ((float)a + b) * ((float)a + b))*scale_sq_sq;
101  }
102 }
103 
105 
106 static float IC_Angle(const Mat& image, const int half_k, Point2f pt,
107  const std::vector<int> & u_max)
108 {
109  int m_01 = 0, m_10 = 0;
110 
111  const uchar* center = &image.at<uchar> (cvRound(pt.y), cvRound(pt.x));
112 
113  // Treat the center line differently, v=0
114  for (int u = -half_k; u <= half_k; ++u)
115  m_10 += u * center[u];
116 
117  // Go line by line in the circular patch
118  int step = (int)image.step1();
119  for (int v = 1; v <= half_k; ++v)
120  {
121  // Proceed over the two lines
122  int v_sum = 0;
123  int d = u_max[v];
124  for (int u = -d; u <= d; ++u)
125  {
126  int val_plus = center[u + v*step], val_minus = center[u - v*step];
127  v_sum += (val_plus - val_minus);
128  m_10 += u * (val_plus + val_minus);
129  }
130  m_01 += v * v_sum;
131  }
132 
133  return fastAtan2((float)m_01, (float)m_10);
134 }
135 
137 
138 static void computeOrbDescriptor(const KeyPoint& kpt,
139  const Mat& img, const Point* pattern,
140  uchar* desc, int dsize, int WTA_K)
141 {
142  float angle = kpt.angle;
143  //angle = cvFloor(angle/12)*12.f;
144  angle *= (float)(CV_PI/180.f);
145  float a = (float)cos(angle), b = (float)sin(angle);
146 
147  const uchar* center = &img.at<uchar>(cvRound(kpt.pt.y), cvRound(kpt.pt.x));
148  int step = (int)img.step;
149 
150  float x, y;
151  int ix, iy;
152 #if 1
153  #define GET_VALUE(idx) \
154  (x = pattern[idx].x*a - pattern[idx].y*b, \
155  y = pattern[idx].x*b + pattern[idx].y*a, \
156  ix = cvRound(x), \
157  iy = cvRound(y), \
158  *(center + iy*step + ix) )
159 #else
160  #define GET_VALUE(idx) \
161  (x = pattern[idx].x*a - pattern[idx].y*b, \
162  y = pattern[idx].x*b + pattern[idx].y*a, \
163  ix = cvFloor(x), iy = cvFloor(y), \
164  x -= ix, y -= iy, \
165  cvRound(center[iy*step + ix]*(1-x)*(1-y) + center[(iy+1)*step + ix]*(1-x)*y + \
166  center[iy*step + ix+1]*x*(1-y) + center[(iy+1)*step + ix+1]*x*y))
167 #endif
168 
169  if( WTA_K == 2 )
170  {
171  for (int i = 0; i < dsize; ++i, pattern += 16)
172  {
173  int t0, t1, val;
174  t0 = GET_VALUE(0); t1 = GET_VALUE(1);
175  val = t0 < t1;
176  t0 = GET_VALUE(2); t1 = GET_VALUE(3);
177  val |= (t0 < t1) << 1;
178  t0 = GET_VALUE(4); t1 = GET_VALUE(5);
179  val |= (t0 < t1) << 2;
180  t0 = GET_VALUE(6); t1 = GET_VALUE(7);
181  val |= (t0 < t1) << 3;
182  t0 = GET_VALUE(8); t1 = GET_VALUE(9);
183  val |= (t0 < t1) << 4;
184  t0 = GET_VALUE(10); t1 = GET_VALUE(11);
185  val |= (t0 < t1) << 5;
186  t0 = GET_VALUE(12); t1 = GET_VALUE(13);
187  val |= (t0 < t1) << 6;
188  t0 = GET_VALUE(14); t1 = GET_VALUE(15);
189  val |= (t0 < t1) << 7;
190 
191  desc[i] = (uchar)val;
192  }
193  }
194  else if( WTA_K == 3 )
195  {
196  for (int i = 0; i < dsize; ++i, pattern += 12)
197  {
198  int t0, t1, t2, val;
199  t0 = GET_VALUE(0); t1 = GET_VALUE(1); t2 = GET_VALUE(2);
200  val = t2 > t1 ? (t2 > t0 ? 2 : 0) : (t1 > t0);
201 
202  t0 = GET_VALUE(3); t1 = GET_VALUE(4); t2 = GET_VALUE(5);
203  val |= (t2 > t1 ? (t2 > t0 ? 2 : 0) : (t1 > t0)) << 2;
204 
205  t0 = GET_VALUE(6); t1 = GET_VALUE(7); t2 = GET_VALUE(8);
206  val |= (t2 > t1 ? (t2 > t0 ? 2 : 0) : (t1 > t0)) << 4;
207 
208  t0 = GET_VALUE(9); t1 = GET_VALUE(10); t2 = GET_VALUE(11);
209  val |= (t2 > t1 ? (t2 > t0 ? 2 : 0) : (t1 > t0)) << 6;
210 
211  desc[i] = (uchar)val;
212  }
213  }
214  else if( WTA_K == 4 )
215  {
216  for (int i = 0; i < dsize; ++i, pattern += 16)
217  {
218  int t0, t1, t2, t3, u, v, k, val;
219  t0 = GET_VALUE(0); t1 = GET_VALUE(1);
220  t2 = GET_VALUE(2); t3 = GET_VALUE(3);
221  u = 0, v = 2;
222  if( t1 > t0 ) t0 = t1, u = 1;
223  if( t3 > t2 ) t2 = t3, v = 3;
224  k = t0 > t2 ? u : v;
225  val = k;
226 
227  t0 = GET_VALUE(4); t1 = GET_VALUE(5);
228  t2 = GET_VALUE(6); t3 = GET_VALUE(7);
229  u = 0, v = 2;
230  if( t1 > t0 ) t0 = t1, u = 1;
231  if( t3 > t2 ) t2 = t3, v = 3;
232  k = t0 > t2 ? u : v;
233  val |= k << 2;
234 
235  t0 = GET_VALUE(8); t1 = GET_VALUE(9);
236  t2 = GET_VALUE(10); t3 = GET_VALUE(11);
237  u = 0, v = 2;
238  if( t1 > t0 ) t0 = t1, u = 1;
239  if( t3 > t2 ) t2 = t3, v = 3;
240  k = t0 > t2 ? u : v;
241  val |= k << 4;
242 
243  t0 = GET_VALUE(12); t1 = GET_VALUE(13);
244  t2 = GET_VALUE(14); t3 = GET_VALUE(15);
245  u = 0, v = 2;
246  if( t1 > t0 ) t0 = t1, u = 1;
247  if( t3 > t2 ) t2 = t3, v = 3;
248  k = t0 > t2 ? u : v;
249  val |= k << 6;
250 
251  desc[i] = (uchar)val;
252  }
253  }
254  else
255  CV_Error( CV_StsBadSize, "Wrong WTA_K. It can be only 2, 3 or 4." );
256 
257  #undef GET_VALUE
258 }
259 
260 
261 static void initializeOrbPattern( const Point* pattern0, std::vector<Point>& pattern, int ntuples, int tupleSize, int poolSize )
262 {
263  RNG rng(0x12345678);
264  int i, k, k1;
265  pattern.resize(ntuples*tupleSize);
266 
267  for( i = 0; i < ntuples; i++ )
268  {
269  for( k = 0; k < tupleSize; k++ )
270  {
271  for(;;)
272  {
273  int idx = rng.uniform(0, poolSize);
274  Point pt = pattern0[idx];
275  for( k1 = 0; k1 < k; k1++ )
276  if( pattern[tupleSize*i + k1] == pt )
277  break;
278  if( k1 == k )
279  {
280  pattern[tupleSize*i + k] = pt;
281  break;
282  }
283  }
284  }
285  }
286 }
287 
288 static int bit_pattern_31_[256*4] =
289 {
290  8,-3, 9,5/*mean (0), correlation (0)*/,
291  4,2, 7,-12/*mean (1.12461e-05), correlation (0.0437584)*/,
292  -11,9, -8,2/*mean (3.37382e-05), correlation (0.0617409)*/,
293  7,-12, 12,-13/*mean (5.62303e-05), correlation (0.0636977)*/,
294  2,-13, 2,12/*mean (0.000134953), correlation (0.085099)*/,
295  1,-7, 1,6/*mean (0.000528565), correlation (0.0857175)*/,
296  -2,-10, -2,-4/*mean (0.0188821), correlation (0.0985774)*/,
297  -13,-13, -11,-8/*mean (0.0363135), correlation (0.0899616)*/,
298  -13,-3, -12,-9/*mean (0.121806), correlation (0.099849)*/,
299  10,4, 11,9/*mean (0.122065), correlation (0.093285)*/,
300  -13,-8, -8,-9/*mean (0.162787), correlation (0.0942748)*/,
301  -11,7, -9,12/*mean (0.21561), correlation (0.0974438)*/,
302  7,7, 12,6/*mean (0.160583), correlation (0.130064)*/,
303  -4,-5, -3,0/*mean (0.228171), correlation (0.132998)*/,
304  -13,2, -12,-3/*mean (0.00997526), correlation (0.145926)*/,
305  -9,0, -7,5/*mean (0.198234), correlation (0.143636)*/,
306  12,-6, 12,-1/*mean (0.0676226), correlation (0.16689)*/,
307  -3,6, -2,12/*mean (0.166847), correlation (0.171682)*/,
308  -6,-13, -4,-8/*mean (0.101215), correlation (0.179716)*/,
309  11,-13, 12,-8/*mean (0.200641), correlation (0.192279)*/,
310  4,7, 5,1/*mean (0.205106), correlation (0.186848)*/,
311  5,-3, 10,-3/*mean (0.234908), correlation (0.192319)*/,
312  3,-7, 6,12/*mean (0.0709964), correlation (0.210872)*/,
313  -8,-7, -6,-2/*mean (0.0939834), correlation (0.212589)*/,
314  -2,11, -1,-10/*mean (0.127778), correlation (0.20866)*/,
315  -13,12, -8,10/*mean (0.14783), correlation (0.206356)*/,
316  -7,3, -5,-3/*mean (0.182141), correlation (0.198942)*/,
317  -4,2, -3,7/*mean (0.188237), correlation (0.21384)*/,
318  -10,-12, -6,11/*mean (0.14865), correlation (0.23571)*/,
319  5,-12, 6,-7/*mean (0.222312), correlation (0.23324)*/,
320  5,-6, 7,-1/*mean (0.229082), correlation (0.23389)*/,
321  1,0, 4,-5/*mean (0.241577), correlation (0.215286)*/,
322  9,11, 11,-13/*mean (0.00338507), correlation (0.251373)*/,
323  4,7, 4,12/*mean (0.131005), correlation (0.257622)*/,
324  2,-1, 4,4/*mean (0.152755), correlation (0.255205)*/,
325  -4,-12, -2,7/*mean (0.182771), correlation (0.244867)*/,
326  -8,-5, -7,-10/*mean (0.186898), correlation (0.23901)*/,
327  4,11, 9,12/*mean (0.226226), correlation (0.258255)*/,
328  0,-8, 1,-13/*mean (0.0897886), correlation (0.274827)*/,
329  -13,-2, -8,2/*mean (0.148774), correlation (0.28065)*/,
330  -3,-2, -2,3/*mean (0.153048), correlation (0.283063)*/,
331  -6,9, -4,-9/*mean (0.169523), correlation (0.278248)*/,
332  8,12, 10,7/*mean (0.225337), correlation (0.282851)*/,
333  0,9, 1,3/*mean (0.226687), correlation (0.278734)*/,
334  7,-5, 11,-10/*mean (0.00693882), correlation (0.305161)*/,
335  -13,-6, -11,0/*mean (0.0227283), correlation (0.300181)*/,
336  10,7, 12,1/*mean (0.125517), correlation (0.31089)*/,
337  -6,-3, -6,12/*mean (0.131748), correlation (0.312779)*/,
338  10,-9, 12,-4/*mean (0.144827), correlation (0.292797)*/,
339  -13,8, -8,-12/*mean (0.149202), correlation (0.308918)*/,
340  -13,0, -8,-4/*mean (0.160909), correlation (0.310013)*/,
341  3,3, 7,8/*mean (0.177755), correlation (0.309394)*/,
342  5,7, 10,-7/*mean (0.212337), correlation (0.310315)*/,
343  -1,7, 1,-12/*mean (0.214429), correlation (0.311933)*/,
344  3,-10, 5,6/*mean (0.235807), correlation (0.313104)*/,
345  2,-4, 3,-10/*mean (0.00494827), correlation (0.344948)*/,
346  -13,0, -13,5/*mean (0.0549145), correlation (0.344675)*/,
347  -13,-7, -12,12/*mean (0.103385), correlation (0.342715)*/,
348  -13,3, -11,8/*mean (0.134222), correlation (0.322922)*/,
349  -7,12, -4,7/*mean (0.153284), correlation (0.337061)*/,
350  6,-10, 12,8/*mean (0.154881), correlation (0.329257)*/,
351  -9,-1, -7,-6/*mean (0.200967), correlation (0.33312)*/,
352  -2,-5, 0,12/*mean (0.201518), correlation (0.340635)*/,
353  -12,5, -7,5/*mean (0.207805), correlation (0.335631)*/,
354  3,-10, 8,-13/*mean (0.224438), correlation (0.34504)*/,
355  -7,-7, -4,5/*mean (0.239361), correlation (0.338053)*/,
356  -3,-2, -1,-7/*mean (0.240744), correlation (0.344322)*/,
357  2,9, 5,-11/*mean (0.242949), correlation (0.34145)*/,
358  -11,-13, -5,-13/*mean (0.244028), correlation (0.336861)*/,
359  -1,6, 0,-1/*mean (0.247571), correlation (0.343684)*/,
360  5,-3, 5,2/*mean (0.000697256), correlation (0.357265)*/,
361  -4,-13, -4,12/*mean (0.00213675), correlation (0.373827)*/,
362  -9,-6, -9,6/*mean (0.0126856), correlation (0.373938)*/,
363  -12,-10, -8,-4/*mean (0.0152497), correlation (0.364237)*/,
364  10,2, 12,-3/*mean (0.0299933), correlation (0.345292)*/,
365  7,12, 12,12/*mean (0.0307242), correlation (0.366299)*/,
366  -7,-13, -6,5/*mean (0.0534975), correlation (0.368357)*/,
367  -4,9, -3,4/*mean (0.099865), correlation (0.372276)*/,
368  7,-1, 12,2/*mean (0.117083), correlation (0.364529)*/,
369  -7,6, -5,1/*mean (0.126125), correlation (0.369606)*/,
370  -13,11, -12,5/*mean (0.130364), correlation (0.358502)*/,
371  -3,7, -2,-6/*mean (0.131691), correlation (0.375531)*/,
372  7,-8, 12,-7/*mean (0.160166), correlation (0.379508)*/,
373  -13,-7, -11,-12/*mean (0.167848), correlation (0.353343)*/,
374  1,-3, 12,12/*mean (0.183378), correlation (0.371916)*/,
375  2,-6, 3,0/*mean (0.228711), correlation (0.371761)*/,
376  -4,3, -2,-13/*mean (0.247211), correlation (0.364063)*/,
377  -1,-13, 1,9/*mean (0.249325), correlation (0.378139)*/,
378  7,1, 8,-6/*mean (0.000652272), correlation (0.411682)*/,
379  1,-1, 3,12/*mean (0.00248538), correlation (0.392988)*/,
380  9,1, 12,6/*mean (0.0206815), correlation (0.386106)*/,
381  -1,-9, -1,3/*mean (0.0364485), correlation (0.410752)*/,
382  -13,-13, -10,5/*mean (0.0376068), correlation (0.398374)*/,
383  7,7, 10,12/*mean (0.0424202), correlation (0.405663)*/,
384  12,-5, 12,9/*mean (0.0942645), correlation (0.410422)*/,
385  6,3, 7,11/*mean (0.1074), correlation (0.413224)*/,
386  5,-13, 6,10/*mean (0.109256), correlation (0.408646)*/,
387  2,-12, 2,3/*mean (0.131691), correlation (0.416076)*/,
388  3,8, 4,-6/*mean (0.165081), correlation (0.417569)*/,
389  2,6, 12,-13/*mean (0.171874), correlation (0.408471)*/,
390  9,-12, 10,3/*mean (0.175146), correlation (0.41296)*/,
391  -8,4, -7,9/*mean (0.183682), correlation (0.402956)*/,
392  -11,12, -4,-6/*mean (0.184672), correlation (0.416125)*/,
393  1,12, 2,-8/*mean (0.191487), correlation (0.386696)*/,
394  6,-9, 7,-4/*mean (0.192668), correlation (0.394771)*/,
395  2,3, 3,-2/*mean (0.200157), correlation (0.408303)*/,
396  6,3, 11,0/*mean (0.204588), correlation (0.411762)*/,
397  3,-3, 8,-8/*mean (0.205904), correlation (0.416294)*/,
398  7,8, 9,3/*mean (0.213237), correlation (0.409306)*/,
399  -11,-5, -6,-4/*mean (0.243444), correlation (0.395069)*/,
400  -10,11, -5,10/*mean (0.247672), correlation (0.413392)*/,
401  -5,-8, -3,12/*mean (0.24774), correlation (0.411416)*/,
402  -10,5, -9,0/*mean (0.00213675), correlation (0.454003)*/,
403  8,-1, 12,-6/*mean (0.0293635), correlation (0.455368)*/,
404  4,-6, 6,-11/*mean (0.0404971), correlation (0.457393)*/,
405  -10,12, -8,7/*mean (0.0481107), correlation (0.448364)*/,
406  4,-2, 6,7/*mean (0.050641), correlation (0.455019)*/,
407  -2,0, -2,12/*mean (0.0525978), correlation (0.44338)*/,
408  -5,-8, -5,2/*mean (0.0629667), correlation (0.457096)*/,
409  7,-6, 10,12/*mean (0.0653846), correlation (0.445623)*/,
410  -9,-13, -8,-8/*mean (0.0858749), correlation (0.449789)*/,
411  -5,-13, -5,-2/*mean (0.122402), correlation (0.450201)*/,
412  8,-8, 9,-13/*mean (0.125416), correlation (0.453224)*/,
413  -9,-11, -9,0/*mean (0.130128), correlation (0.458724)*/,
414  1,-8, 1,-2/*mean (0.132467), correlation (0.440133)*/,
415  7,-4, 9,1/*mean (0.132692), correlation (0.454)*/,
416  -2,1, -1,-4/*mean (0.135695), correlation (0.455739)*/,
417  11,-6, 12,-11/*mean (0.142904), correlation (0.446114)*/,
418  -12,-9, -6,4/*mean (0.146165), correlation (0.451473)*/,
419  3,7, 7,12/*mean (0.147627), correlation (0.456643)*/,
420  5,5, 10,8/*mean (0.152901), correlation (0.455036)*/,
421  0,-4, 2,8/*mean (0.167083), correlation (0.459315)*/,
422  -9,12, -5,-13/*mean (0.173234), correlation (0.454706)*/,
423  0,7, 2,12/*mean (0.18312), correlation (0.433855)*/,
424  -1,2, 1,7/*mean (0.185504), correlation (0.443838)*/,
425  5,11, 7,-9/*mean (0.185706), correlation (0.451123)*/,
426  3,5, 6,-8/*mean (0.188968), correlation (0.455808)*/,
427  -13,-4, -8,9/*mean (0.191667), correlation (0.459128)*/,
428  -5,9, -3,-3/*mean (0.193196), correlation (0.458364)*/,
429  -4,-7, -3,-12/*mean (0.196536), correlation (0.455782)*/,
430  6,5, 8,0/*mean (0.1972), correlation (0.450481)*/,
431  -7,6, -6,12/*mean (0.199438), correlation (0.458156)*/,
432  -13,6, -5,-2/*mean (0.211224), correlation (0.449548)*/,
433  1,-10, 3,10/*mean (0.211718), correlation (0.440606)*/,
434  4,1, 8,-4/*mean (0.213034), correlation (0.443177)*/,
435  -2,-2, 2,-13/*mean (0.234334), correlation (0.455304)*/,
436  2,-12, 12,12/*mean (0.235684), correlation (0.443436)*/,
437  -2,-13, 0,-6/*mean (0.237674), correlation (0.452525)*/,
438  4,1, 9,3/*mean (0.23962), correlation (0.444824)*/,
439  -6,-10, -3,-5/*mean (0.248459), correlation (0.439621)*/,
440  -3,-13, -1,1/*mean (0.249505), correlation (0.456666)*/,
441  7,5, 12,-11/*mean (0.00119208), correlation (0.495466)*/,
442  4,-2, 5,-7/*mean (0.00372245), correlation (0.484214)*/,
443  -13,9, -9,-5/*mean (0.00741116), correlation (0.499854)*/,
444  7,1, 8,6/*mean (0.0208952), correlation (0.499773)*/,
445  7,-8, 7,6/*mean (0.0220085), correlation (0.501609)*/,
446  -7,-4, -7,1/*mean (0.0233806), correlation (0.496568)*/,
447  -8,11, -7,-8/*mean (0.0236505), correlation (0.489719)*/,
448  -13,6, -12,-8/*mean (0.0268781), correlation (0.503487)*/,
449  2,4, 3,9/*mean (0.0323324), correlation (0.501938)*/,
450  10,-5, 12,3/*mean (0.0399235), correlation (0.494029)*/,
451  -6,-5, -6,7/*mean (0.0420153), correlation (0.486579)*/,
452  8,-3, 9,-8/*mean (0.0548021), correlation (0.484237)*/,
453  2,-12, 2,8/*mean (0.0616622), correlation (0.496642)*/,
454  -11,-2, -10,3/*mean (0.0627755), correlation (0.498563)*/,
455  -12,-13, -7,-9/*mean (0.0829622), correlation (0.495491)*/,
456  -11,0, -10,-5/*mean (0.0843342), correlation (0.487146)*/,
457  5,-3, 11,8/*mean (0.0929937), correlation (0.502315)*/,
458  -2,-13, -1,12/*mean (0.113327), correlation (0.48941)*/,
459  -1,-8, 0,9/*mean (0.132119), correlation (0.467268)*/,
460  -13,-11, -12,-5/*mean (0.136269), correlation (0.498771)*/,
461  -10,-2, -10,11/*mean (0.142173), correlation (0.498714)*/,
462  -3,9, -2,-13/*mean (0.144141), correlation (0.491973)*/,
463  2,-3, 3,2/*mean (0.14892), correlation (0.500782)*/,
464  -9,-13, -4,0/*mean (0.150371), correlation (0.498211)*/,
465  -4,6, -3,-10/*mean (0.152159), correlation (0.495547)*/,
466  -4,12, -2,-7/*mean (0.156152), correlation (0.496925)*/,
467  -6,-11, -4,9/*mean (0.15749), correlation (0.499222)*/,
468  6,-3, 6,11/*mean (0.159211), correlation (0.503821)*/,
469  -13,11, -5,5/*mean (0.162427), correlation (0.501907)*/,
470  11,11, 12,6/*mean (0.16652), correlation (0.497632)*/,
471  7,-5, 12,-2/*mean (0.169141), correlation (0.484474)*/,
472  -1,12, 0,7/*mean (0.169456), correlation (0.495339)*/,
473  -4,-8, -3,-2/*mean (0.171457), correlation (0.487251)*/,
474  -7,1, -6,7/*mean (0.175), correlation (0.500024)*/,
475  -13,-12, -8,-13/*mean (0.175866), correlation (0.497523)*/,
476  -7,-2, -6,-8/*mean (0.178273), correlation (0.501854)*/,
477  -8,5, -6,-9/*mean (0.181107), correlation (0.494888)*/,
478  -5,-1, -4,5/*mean (0.190227), correlation (0.482557)*/,
479  -13,7, -8,10/*mean (0.196739), correlation (0.496503)*/,
480  1,5, 5,-13/*mean (0.19973), correlation (0.499759)*/,
481  1,0, 10,-13/*mean (0.204465), correlation (0.49873)*/,
482  9,12, 10,-1/*mean (0.209334), correlation (0.49063)*/,
483  5,-8, 10,-9/*mean (0.211134), correlation (0.503011)*/,
484  -1,11, 1,-13/*mean (0.212), correlation (0.499414)*/,
485  -9,-3, -6,2/*mean (0.212168), correlation (0.480739)*/,
486  -1,-10, 1,12/*mean (0.212731), correlation (0.502523)*/,
487  -13,1, -8,-10/*mean (0.21327), correlation (0.489786)*/,
488  8,-11, 10,-6/*mean (0.214159), correlation (0.488246)*/,
489  2,-13, 3,-6/*mean (0.216993), correlation (0.50287)*/,
490  7,-13, 12,-9/*mean (0.223639), correlation (0.470502)*/,
491  -10,-10, -5,-7/*mean (0.224089), correlation (0.500852)*/,
492  -10,-8, -8,-13/*mean (0.228666), correlation (0.502629)*/,
493  4,-6, 8,5/*mean (0.22906), correlation (0.498305)*/,
494  3,12, 8,-13/*mean (0.233378), correlation (0.503825)*/,
495  -4,2, -3,-3/*mean (0.234323), correlation (0.476692)*/,
496  5,-13, 10,-12/*mean (0.236392), correlation (0.475462)*/,
497  4,-13, 5,-1/*mean (0.236842), correlation (0.504132)*/,
498  -9,9, -4,3/*mean (0.236977), correlation (0.497739)*/,
499  0,3, 3,-9/*mean (0.24314), correlation (0.499398)*/,
500  -12,1, -6,1/*mean (0.243297), correlation (0.489447)*/,
501  3,2, 4,-8/*mean (0.00155196), correlation (0.553496)*/,
502  -10,-10, -10,9/*mean (0.00239541), correlation (0.54297)*/,
503  8,-13, 12,12/*mean (0.0034413), correlation (0.544361)*/,
504  -8,-12, -6,-5/*mean (0.003565), correlation (0.551225)*/,
505  2,2, 3,7/*mean (0.00835583), correlation (0.55285)*/,
506  10,6, 11,-8/*mean (0.00885065), correlation (0.540913)*/,
507  6,8, 8,-12/*mean (0.0101552), correlation (0.551085)*/,
508  -7,10, -6,5/*mean (0.0102227), correlation (0.533635)*/,
509  -3,-9, -3,9/*mean (0.0110211), correlation (0.543121)*/,
510  -1,-13, -1,5/*mean (0.0113473), correlation (0.550173)*/,
511  -3,-7, -3,4/*mean (0.0140913), correlation (0.554774)*/,
512  -8,-2, -8,3/*mean (0.017049), correlation (0.55461)*/,
513  4,2, 12,12/*mean (0.01778), correlation (0.546921)*/,
514  2,-5, 3,11/*mean (0.0224022), correlation (0.549667)*/,
515  6,-9, 11,-13/*mean (0.029161), correlation (0.546295)*/,
516  3,-1, 7,12/*mean (0.0303081), correlation (0.548599)*/,
517  11,-1, 12,4/*mean (0.0355151), correlation (0.523943)*/,
518  -3,0, -3,6/*mean (0.0417904), correlation (0.543395)*/,
519  4,-11, 4,12/*mean (0.0487292), correlation (0.542818)*/,
520  2,-4, 2,1/*mean (0.0575124), correlation (0.554888)*/,
521  -10,-6, -8,1/*mean (0.0594242), correlation (0.544026)*/,
522  -13,7, -11,1/*mean (0.0597391), correlation (0.550524)*/,
523  -13,12, -11,-13/*mean (0.0608974), correlation (0.55383)*/,
524  6,0, 11,-13/*mean (0.065126), correlation (0.552006)*/,
525  0,-1, 1,4/*mean (0.074224), correlation (0.546372)*/,
526  -13,3, -9,-2/*mean (0.0808592), correlation (0.554875)*/,
527  -9,8, -6,-3/*mean (0.0883378), correlation (0.551178)*/,
528  -13,-6, -8,-2/*mean (0.0901035), correlation (0.548446)*/,
529  5,-9, 8,10/*mean (0.0949843), correlation (0.554694)*/,
530  2,7, 3,-9/*mean (0.0994152), correlation (0.550979)*/,
531  -1,-6, -1,-1/*mean (0.10045), correlation (0.552714)*/,
532  9,5, 11,-2/*mean (0.100686), correlation (0.552594)*/,
533  11,-3, 12,-8/*mean (0.101091), correlation (0.532394)*/,
534  3,0, 3,5/*mean (0.101147), correlation (0.525576)*/,
535  -1,4, 0,10/*mean (0.105263), correlation (0.531498)*/,
536  3,-6, 4,5/*mean (0.110785), correlation (0.540491)*/,
537  -13,0, -10,5/*mean (0.112798), correlation (0.536582)*/,
538  5,8, 12,11/*mean (0.114181), correlation (0.555793)*/,
539  8,9, 9,-6/*mean (0.117431), correlation (0.553763)*/,
540  7,-4, 8,-12/*mean (0.118522), correlation (0.553452)*/,
541  -10,4, -10,9/*mean (0.12094), correlation (0.554785)*/,
542  7,3, 12,4/*mean (0.122582), correlation (0.555825)*/,
543  9,-7, 10,-2/*mean (0.124978), correlation (0.549846)*/,
544  7,0, 12,-2/*mean (0.127002), correlation (0.537452)*/,
545  -1,-6, 0,-11/*mean (0.127148), correlation (0.547401)*/
546 };
547 
548 
549 static void makeRandomPattern(int patchSize, Point* pattern, int npoints)
550 {
551  RNG rng(0x34985739); // we always start with a fixed seed,
552  // to make patterns the same on each run
553  for( int i = 0; i < npoints; i++ )
554  {
555  pattern[i].x = rng.uniform(-patchSize/2, patchSize/2+1);
556  pattern[i].y = rng.uniform(-patchSize/2, patchSize/2+1);
557  }
558 }
559 
560 
561 static inline float getScale(int level, int firstLevel, double scaleFactor)
562 {
563  return (float)std::pow(scaleFactor, (double)(level - firstLevel));
564 }
565 
569 CV_ORB::CV_ORB(int _nfeatures, float _scaleFactor, int _nlevels, int _edgeThreshold,
570  int _firstLevel, int _WTA_K, int _scoreType, int _patchSize, const ParametersMap & _fastParameters) :
571  nfeatures(_nfeatures), scaleFactor(_scaleFactor), nlevels(_nlevels),
572  edgeThreshold(_edgeThreshold), firstLevel(_firstLevel), WTA_K(_WTA_K),
573  scoreType(_scoreType), patchSize(_patchSize), fastParameters(_fastParameters)
574 {}
575 
576 
578 {
579  return kBytes;
580 }
581 
583 {
584  return CV_8U;
585 }
586 
592 void CV_ORB::operator()(InputArray image, InputArray mask, std::vector<KeyPoint>& keypoints) const
593 {
594  (*this)(image, mask, keypoints, noArray(), false);
595 }
596 
597 
604 static void computeOrientation(const Mat& image, std::vector<KeyPoint>& keypoints,
605  int halfPatchSize, const std::vector<int>& umax)
606 {
607  // Process each keypoint
608  for (std::vector<KeyPoint>::iterator keypoint = keypoints.begin(),
609  keypointEnd = keypoints.end(); keypoint != keypointEnd; ++keypoint)
610  {
611  keypoint->angle = IC_Angle(image, halfPatchSize, keypoint->pt, umax);
612  }
613 }
614 
615 
621 static void computeKeyPoints(const std::vector<Mat>& imagePyramid,
622  const std::vector<Mat>& maskPyramid,
623  std::vector<std::vector<KeyPoint> >& allKeypoints,
624  int nfeatures, int firstLevel, double scaleFactor,
625  int edgeThreshold, int patchSize, int scoreType,
627 {
628  int nlevels = (int)imagePyramid.size();
629  std::vector<int> nfeaturesPerLevel(nlevels);
630 
631  // fill the extractors and descriptors for the corresponding scales
632  float factor = (float)(1.0 / scaleFactor);
633  float ndesiredFeaturesPerScale = nfeatures*(1 - factor)/(1 - (float)pow((double)factor, (double)nlevels));
634 
635  int sumFeatures = 0;
636  for( int level = 0; level < nlevels-1; level++ )
637  {
638  nfeaturesPerLevel[level] = cvRound(ndesiredFeaturesPerScale);
639  sumFeatures += nfeaturesPerLevel[level];
640  ndesiredFeaturesPerScale *= factor;
641  }
642  nfeaturesPerLevel[nlevels-1] = std::max(nfeatures - sumFeatures, 0);
643 
644  // Make sure we forget about what is too close to the boundary
645  //edge_threshold_ = std::max(edge_threshold_, patch_size_/2 + kKernelWidth / 2 + 2);
646 
647  // pre-compute the end of a row in a circular patch
648  int halfPatchSize = patchSize / 2;
649  std::vector<int> umax(halfPatchSize + 2);
650 
651  int v, v0, vmax = cvFloor(halfPatchSize * sqrt(2.f) / 2 + 1);
652  int vmin = cvCeil(halfPatchSize * sqrt(2.f) / 2);
653  for (v = 0; v <= vmax; ++v)
654  umax[v] = cvRound(sqrt((double)halfPatchSize * halfPatchSize - v * v));
655 
656  // Make sure we are symmetric
657  for (v = halfPatchSize, v0 = 0; v >= vmin; --v)
658  {
659  while (umax[v0] == umax[v0 + 1])
660  ++v0;
661  umax[v] = v0;
662  ++v0;
663  }
664 
665  allKeypoints.resize(nlevels);
666 
667  for (int level = 0; level < nlevels; ++level)
668  {
669  int featuresNum = nfeaturesPerLevel[level];
670  allKeypoints[level].reserve(featuresNum*2);
671 
672  std::vector<KeyPoint> & keypoints = allKeypoints[level];
673 
674  // Detect FAST features, maxFeatures is used by the GridAdaptor of FAST
675  uInsert(fastParameters, ParametersPair(Parameters::kKpMaxFeatures(), uNumber2Str(scoreType == CV_ORB::HARRIS_SCORE?2*featuresNum:featuresNum)));
676  FAST fast(fastParameters);
677  keypoints = fast.generateKeypoints(imagePyramid[level], maskPyramid[level]);
678 
679  // Remove keypoints very close to the border
680  KeyPointsFilter::runByImageBorder(keypoints, imagePyramid[level].size(), edgeThreshold);
681 
682  if( scoreType == CV_ORB::HARRIS_SCORE )
683  {
684  // Keep more points than necessary as FAST does not give amazing corners
685  KeyPointsFilter::retainBest(keypoints, 2 * featuresNum);
686 
687  // Compute the Harris cornerness (better scoring than FAST)
688  HarrisResponses(imagePyramid[level], keypoints, 7, HARRIS_K);
689  }
690 
691  //cull to the final desired level, using the new Harris scores or the original FAST scores.
692  KeyPointsFilter::retainBest(keypoints, featuresNum);
693 
694  float sf = getScale(level, firstLevel, scaleFactor);
695 
696  // Set the level of the coordinates
697  for (std::vector<KeyPoint>::iterator keypoint = keypoints.begin(),
698  keypointEnd = keypoints.end(); keypoint != keypointEnd; ++keypoint)
699  {
700  keypoint->octave = level;
701  keypoint->size = patchSize*sf;
702  }
703 
704  computeOrientation(imagePyramid[level], keypoints, halfPatchSize, umax);
705  }
706 }
707 
708 
716 static void computeDescriptors(const Mat& image, std::vector<KeyPoint>& keypoints, Mat& descriptors,
717  const std::vector<Point>& pattern, int dsize, int WTA_K)
718 {
719  //convert to grayscale if more than one color
720  CV_Assert(image.type() == CV_8UC1);
721  //create the descriptor mat, keypoints.size() rows, BYTES cols
722  descriptors = Mat::zeros((int)keypoints.size(), dsize, CV_8UC1);
723 
724  for (size_t i = 0; i < keypoints.size(); i++)
725  computeOrbDescriptor(keypoints[i], image, &pattern[0], descriptors.ptr((int)i), dsize, WTA_K);
726 }
727 
728 
737 void CV_ORB::operator()( InputArray _image, InputArray _mask, std::vector<KeyPoint>& _keypoints,
738  OutputArray _descriptors, bool useProvidedKeypoints) const
739 {
740  CV_Assert(patchSize >= 2);
741 
742  bool do_keypoints = !useProvidedKeypoints;
743  bool do_descriptors = _descriptors.needed();
744 
745  if( (!do_keypoints && !do_descriptors) || _image.empty() )
746  return;
747 
748  //ROI handling
749  const int HARRIS_BLOCK_SIZE = 9;
750  int halfPatchSize = patchSize / 2;
751  int border = std::max(edgeThreshold, std::max(halfPatchSize, HARRIS_BLOCK_SIZE/2))+1;
752 
753  Mat image = _image.getMat(), mask = _mask.getMat();
754  if( image.type() != CV_8UC1 )
755  cvtColor(_image, image, CV_BGR2GRAY);
756 
757  int levelsNum = this->nlevels;
758 
759  if( !do_keypoints )
760  {
761  // if we have pre-computed keypoints, they may use more levels than it is set in parameters
762  // !!!TODO!!! implement more correct method, independent from the used keypoint detector.
763  // Namely, the detector should provide correct size of each keypoint. Based on the keypoint size
764  // and the algorithm used (i.e. BRIEF, running on 31x31 patches) we should compute the approximate
765  // scale-factor that we need to apply. Then we should cluster all the computed scale-factors and
766  // for each cluster compute the corresponding image.
767  //
768  // In short, ultimately the descriptor should
769  // ignore octave parameter and deal only with the keypoint size.
770  levelsNum = 0;
771  for( size_t i = 0; i < _keypoints.size(); i++ )
772  levelsNum = std::max(levelsNum, std::max(_keypoints[i].octave, 0));
773  levelsNum++;
774  }
775 
776  // Pre-compute the scale pyramids
777  std::vector<Mat> imagePyramid(levelsNum), maskPyramid(levelsNum);
778  for (int level = 0; level < levelsNum; ++level)
779  {
780  float scale = 1/getScale(level, firstLevel, scaleFactor);
781  Size sz(cvRound(image.cols*scale), cvRound(image.rows*scale));
782  Size wholeSize(sz.width + border*2, sz.height + border*2);
783  Mat temp(wholeSize, image.type()), masktemp;
784  imagePyramid[level] = temp(Rect(border, border, sz.width, sz.height));
785 
786  if( !mask.empty() )
787  {
788  masktemp = Mat(wholeSize, mask.type());
789  maskPyramid[level] = masktemp(Rect(border, border, sz.width, sz.height));
790  }
791 
792  // Compute the resized image
793  if( level != firstLevel )
794  {
795  if( level < firstLevel )
796  {
797  resize(image, imagePyramid[level], sz, 0, 0, INTER_LINEAR);
798  if (!mask.empty())
799  resize(mask, maskPyramid[level], sz, 0, 0, INTER_LINEAR);
800  }
801  else
802  {
803  resize(imagePyramid[level-1], imagePyramid[level], sz, 0, 0, INTER_LINEAR);
804  if (!mask.empty())
805  {
806  resize(maskPyramid[level-1], maskPyramid[level], sz, 0, 0, INTER_LINEAR);
807  threshold(maskPyramid[level], maskPyramid[level], 254, 0, THRESH_TOZERO);
808  }
809  }
810 
811  copyMakeBorder(imagePyramid[level], temp, border, border, border, border,
812  BORDER_REFLECT_101+BORDER_ISOLATED);
813  if (!mask.empty())
814  copyMakeBorder(maskPyramid[level], masktemp, border, border, border, border,
815  BORDER_CONSTANT+BORDER_ISOLATED);
816  }
817  else
818  {
819  copyMakeBorder(image, temp, border, border, border, border,
820  BORDER_REFLECT_101);
821  if( !mask.empty() )
822  copyMakeBorder(mask, masktemp, border, border, border, border,
823  BORDER_CONSTANT+BORDER_ISOLATED);
824  }
825  }
826 
827  // Pre-compute the keypoints (we keep the best over all scales, so this has to be done beforehand
828  std::vector < std::vector<KeyPoint> > allKeypoints;
829  if( do_keypoints )
830  {
831  // Get keypoints, those will be far enough from the border that no check will be required for the descriptor
832  computeKeyPoints(imagePyramid, maskPyramid, allKeypoints,
836 
837  // make sure we have the right number of keypoints keypoints
838  /*vector<KeyPoint> temp;
839 
840  for (int level = 0; level < n_levels; ++level)
841  {
842  vector<KeyPoint>& keypoints = all_keypoints[level];
843  temp.insert(temp.end(), keypoints.begin(), keypoints.end());
844  keypoints.clear();
845  }
846 
847  KeyPoint::retainBest(temp, n_features_);
848 
849  for (vector<KeyPoint>::iterator keypoint = temp.begin(),
850  keypoint_end = temp.end(); keypoint != keypoint_end; ++keypoint)
851  all_keypoints[keypoint->octave].push_back(*keypoint);*/
852  }
853  else
854  {
855  // Remove keypoints very close to the border
856  KeyPointsFilter::runByImageBorder(_keypoints, image.size(), edgeThreshold);
857 
858  // Cluster the input keypoints depending on the level they were computed at
859  allKeypoints.resize(levelsNum);
860  for (std::vector<KeyPoint>::iterator keypoint = _keypoints.begin(),
861  keypointEnd = _keypoints.end(); keypoint != keypointEnd; ++keypoint)
862  allKeypoints[keypoint->octave].push_back(*keypoint);
863 
864  // Make sure we rescale the coordinates
865  for (int level = 0; level < levelsNum; ++level)
866  {
867  if (level == firstLevel)
868  continue;
869 
870  std::vector<KeyPoint> & keypoints = allKeypoints[level];
871  float scale = 1/getScale(level, firstLevel, scaleFactor);
872  for (std::vector<KeyPoint>::iterator keypoint = keypoints.begin(),
873  keypointEnd = keypoints.end(); keypoint != keypointEnd; ++keypoint)
874  keypoint->pt *= scale;
875  }
876  }
877 
878  Mat descriptors;
879  std::vector<Point> pattern;
880 
881  if( do_descriptors )
882  {
883  int nkeypoints = 0;
884  for (int level = 0; level < levelsNum; ++level)
885  nkeypoints += (int)allKeypoints[level].size();
886  if( nkeypoints == 0 )
887  _descriptors.release();
888  else
889  {
890  _descriptors.create(nkeypoints, descriptorSize(), CV_8U);
891  descriptors = _descriptors.getMat();
892  }
893 
894  const int npoints = 512;
895  Point patternbuf[npoints];
896  const Point* pattern0 = (const Point*)bit_pattern_31_;
897 
898  if( patchSize != 31 )
899  {
900  pattern0 = patternbuf;
901  makeRandomPattern(patchSize, patternbuf, npoints);
902  }
903 
904  CV_Assert( WTA_K == 2 || WTA_K == 3 || WTA_K == 4 );
905 
906  if( WTA_K == 2 )
907  std::copy(pattern0, pattern0 + npoints, std::back_inserter(pattern));
908  else
909  {
910  int ntuples = descriptorSize()*4;
911  initializeOrbPattern(pattern0, pattern, ntuples, WTA_K, npoints);
912  }
913  }
914 
915  _keypoints.clear();
916  int offset = 0;
917  for (int level = 0; level < levelsNum; ++level)
918  {
919  // Get the features and compute their orientation
920  std::vector<KeyPoint>& keypoints = allKeypoints[level];
921  int nkeypoints = (int)keypoints.size();
922 
923  // Compute the descriptors
924  if (do_descriptors)
925  {
926  Mat desc;
927  if (!descriptors.empty())
928  {
929  desc = descriptors.rowRange(offset, offset + nkeypoints);
930  }
931 
932  offset += nkeypoints;
933  // preprocess the resized image
934  Mat& workingMat = imagePyramid[level];
935  //boxFilter(working_mat, working_mat, working_mat.depth(), Size(5,5), Point(-1,-1), true, BORDER_REFLECT_101);
936  GaussianBlur(workingMat, workingMat, Size(7, 7), 2, 2, BORDER_REFLECT_101);
937  computeDescriptors(workingMat, keypoints, desc, pattern, descriptorSize(), WTA_K);
938  }
939 
940  // Copy to the output data
941  if (level != firstLevel)
942  {
943  float scale = getScale(level, firstLevel, scaleFactor);
944  for (std::vector<KeyPoint>::iterator keypoint = keypoints.begin(),
945  keypointEnd = keypoints.end(); keypoint != keypointEnd; ++keypoint)
946  keypoint->pt *= scale;
947  }
948  // And add the keypoints to the output
949  _keypoints.insert(_keypoints.end(), keypoints.begin(), keypoints.end());
950  }
951 }
952 
953 void CV_ORB::detectImpl( const Mat& image, std::vector<KeyPoint>& keypoints, const Mat& mask) const
954 {
955  (*this)(image, mask, keypoints, noArray(), false);
956 }
957 
958 void CV_ORB::computeImpl( const Mat& image, std::vector<KeyPoint>& keypoints, Mat& descriptors) const
959 {
960  (*this)(image, Mat(), keypoints, descriptors, true);
961 }
962 
963 }
d
GLM_FUNC_DECL genIType mask(genIType const &count)
static void computeDescriptors(const Mat &image, std::vector< KeyPoint > &keypoints, Mat &descriptors, const std::vector< Point > &pattern, int dsize, int WTA_K)
Definition: Orb.cpp:716
CV_PROP_RW double scaleFactor
Definition: Orb.h:85
constexpr T pow(const T base, const std::size_t exponent)
static float getScale(int level, int firstLevel, double scaleFactor)
Definition: Orb.cpp:561
void detectImpl(const cv::Mat &image, std::vector< cv::KeyPoint > &keypoints, const cv::Mat &mask=cv::Mat()) const
Definition: Orb.cpp:953
f
x
GLM_FUNC_DECL vecType< T, P > sqrt(vecType< T, P > const &x)
unsigned char uchar
Definition: matrix.h:41
std::pair< std::string, std::string > ParametersPair
Definition: Parameters.h:44
GLM_FUNC_DECL detail::tmat4x4< T, P > scale(detail::tmat4x4< T, P > const &m, detail::tvec3< T, P > const &v)
ParametersMap fastParameters
Definition: Orb.h:93
std::map< std::string, std::string > ParametersMap
Definition: Parameters.h:43
GLM_FUNC_DECL T angle(detail::tquat< T, P > const &x)
static int bit_pattern_31_[256 *4]
Definition: Orb.cpp:288
Some conversion functions.
Definition: Features2d.h:41
static void HarrisResponses(const Mat &img, std::vector< KeyPoint > &pts, int blockSize, float harris_k)
Definition: Orb.cpp:62
std::vector< cv::KeyPoint > generateKeypoints(const cv::Mat &image, const cv::Mat &mask=cv::Mat())
Definition: Features2d.cpp:670
GLM_FUNC_DECL genType step(genType const &edge, genType const &x)
CV_PROP_RW int nlevels
Definition: Orb.h:86
CV_PROP_RW int edgeThreshold
Definition: Orb.h:87
GLM_FUNC_DECL genType cos(genType const &angle)
Wrappers of STL for convenient functions.
GLM_FUNC_DECL genType sin(genType const &angle)
const float HARRIS_K
Definition: Orb.cpp:55
static void initializeOrbPattern(const Point *pattern0, std::vector< Point > &pattern, int ntuples, int tupleSize, int poolSize)
Definition: Orb.cpp:261
CvImagePtr cvtColor(const CvImageConstPtr &source, const std::string &encoding)
static void makeRandomPattern(int patchSize, Point *pattern, int npoints)
Definition: Orb.cpp:549
int descriptorSize() const
Definition: Orb.cpp:577
static void computeKeyPoints(const std::vector< Mat > &imagePyramid, const std::vector< Mat > &maskPyramid, std::vector< std::vector< KeyPoint > > &allKeypoints, int nfeatures, int firstLevel, double scaleFactor, int edgeThreshold, int patchSize, int scoreType, ParametersMap fastParameters)
Definition: Orb.cpp:621
CV_PROP_RW int patchSize
Definition: Orb.h:91
int descriptorType() const
Definition: Orb.cpp:582
#define GET_VALUE(idx)
static void computeOrbDescriptor(const KeyPoint &kpt, const Mat &img, const Point *pattern, uchar *desc, int dsize, int WTA_K)
Definition: Orb.cpp:138
CV_PROP_RW int scoreType
Definition: Orb.h:90
void computeImpl(const cv::Mat &image, std::vector< cv::KeyPoint > &keypoints, cv::Mat &descriptors) const
Definition: Orb.cpp:958
GLM_FUNC_DECL genType max(genType const &x, genType const &y)
static bool computeOrientation(Eigen::Vector3f A, Eigen::Vector3f E, Eigen::Quaternionf &orientation)
static float IC_Angle(const Mat &image, const int half_k, Point2f pt, const std::vector< int > &u_max)
Definition: Orb.cpp:106
void operator()(cv::InputArray image, cv::InputArray mask, std::vector< cv::KeyPoint > &keypoints) const
CV_PROP_RW int WTA_K
Definition: Orb.h:89
std::string UTILITE_EXP uNumber2Str(unsigned int number)
Definition: UConversion.cpp:91
CV_PROP_RW int nfeatures
Definition: Orb.h:84
void uInsert(std::map< K, V > &map, const std::pair< K, V > &pair)
Definition: UStl.h:443
CV_PROP_RW int firstLevel
Definition: Orb.h:88


rtabmap
Author(s): Mathieu Labbe
autogenerated on Mon Jan 23 2023 03:37:29