1 /*********************************************************************
2 * Software License Agreement (BSD License)
4 * Copyright (c) 2009, Willow Garage, Inc.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
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 *********************************************************************/
35 /** Authors: Ethan Rublee, Vincent Rabaud, Gary Bradski */
37 #include "precomp.hpp"
38 #include "opencl_kernels_features2d.hpp"
42 #define CV_IMPL_ADD(x)
45 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
50 const float HARRIS_K = 0.04f;
52 template<typename _Tp> inline void copyVectorToUMat(const std::vector<_Tp>& v, OutputArray um)
57 Mat(1, (int)(v.size()*sizeof(v[0])), CV_8U, (void*)&v[0]).copyTo(um);
62 ocl_HarrisResponses(const UMat& imgbuf,
63 const UMat& layerinfo,
64 const UMat& keypoints,
66 int nkeypoints, int blockSize, float harris_k)
68 size_t globalSize[] = {(size_t)nkeypoints};
70 float scale = 1.f/((1 << 2) * blockSize * 255.f);
71 float scale_sq_sq = scale * scale * scale * scale;
73 ocl::Kernel hr_ker("ORB_HarrisResponses", ocl::features2d::orb_oclsrc,
74 format("-D ORB_RESPONSES -D blockSize=%d -D scale_sq_sq=%.12ef -D HARRIS_K=%.12ff", blockSize, scale_sq_sq, harris_k));
78 return hr_ker.args(ocl::KernelArg::ReadOnlyNoSize(imgbuf),
79 ocl::KernelArg::PtrReadOnly(layerinfo),
80 ocl::KernelArg::PtrReadOnly(keypoints),
81 ocl::KernelArg::PtrWriteOnly(responses),
82 nkeypoints).run(1, globalSize, 0, true);
86 ocl_ICAngles(const UMat& imgbuf, const UMat& layerinfo,
87 const UMat& keypoints, UMat& responses,
88 const UMat& umax, int nkeypoints, int half_k)
90 size_t globalSize[] = {(size_t)nkeypoints};
92 ocl::Kernel icangle_ker("ORB_ICAngle", ocl::features2d::orb_oclsrc, "-D ORB_ANGLES");
93 if( icangle_ker.empty() )
96 return icangle_ker.args(ocl::KernelArg::ReadOnlyNoSize(imgbuf),
97 ocl::KernelArg::PtrReadOnly(layerinfo),
98 ocl::KernelArg::PtrReadOnly(keypoints),
99 ocl::KernelArg::PtrWriteOnly(responses),
100 ocl::KernelArg::PtrReadOnly(umax),
101 nkeypoints, half_k).run(1, globalSize, 0, true);
106 ocl_computeOrbDescriptors(const UMat& imgbuf, const UMat& layerInfo,
107 const UMat& keypoints, UMat& desc, const UMat& pattern,
108 int nkeypoints, int dsize, int wta_k)
110 size_t globalSize[] = {(size_t)nkeypoints};
112 ocl::Kernel desc_ker("ORB_computeDescriptor", ocl::features2d::orb_oclsrc,
113 format("-D ORB_DESCRIPTORS -D WTA_K=%d", wta_k));
114 if( desc_ker.empty() )
117 return desc_ker.args(ocl::KernelArg::ReadOnlyNoSize(imgbuf),
118 ocl::KernelArg::PtrReadOnly(layerInfo),
119 ocl::KernelArg::PtrReadOnly(keypoints),
120 ocl::KernelArg::PtrWriteOnly(desc),
121 ocl::KernelArg::PtrReadOnly(pattern),
122 nkeypoints, dsize).run(1, globalSize, 0, true);
127 * Function that computes the Harris responses in a
128 * blockSize x blockSize patch at given points in the image
131 HarrisResponses(const Mat& img, const std::vector<Rect>& layerinfo,
132 std::vector<KeyPoint>& pts, int blockSize, float harris_k)
134 CV_Assert( img.type() == CV_8UC1 && blockSize*blockSize <= 2048 );
136 size_t ptidx, ptsize = pts.size();
138 const uchar* ptr00 = img.ptr<uchar>();
139 int step = (int)(img.step/img.elemSize1());
142 float scale = 1.f/((1 << 2) * blockSize * 255.f);
143 float scale_sq_sq = scale * scale * scale * scale;
145 AutoBuffer<int> ofsbuf(blockSize*blockSize);
146 int* ofs = ofsbuf.data();
147 for( int i = 0; i < blockSize; i++ )
148 for( int j = 0; j < blockSize; j++ )
149 ofs[i*blockSize + j] = (int)(i*step + j);
151 for( ptidx = 0; ptidx < ptsize; ptidx++ )
153 int x0 = cvRound(pts[ptidx].pt.x);
154 int y0 = cvRound(pts[ptidx].pt.y);
155 int z = pts[ptidx].octave;
157 const uchar* ptr0 = ptr00 + (y0 - r + layerinfo[z].y)*step + x0 - r + layerinfo[z].x;
158 int a = 0, b = 0, c = 0;
160 for( int k = 0; k < blockSize*blockSize; k++ )
162 const uchar* ptr = ptr0 + ofs[k];
163 int Ix = (ptr[1] - ptr[-1])*2 + (ptr[-step+1] - ptr[-step-1]) + (ptr[step+1] - ptr[step-1]);
164 int Iy = (ptr[step] - ptr[-step])*2 + (ptr[step-1] - ptr[-step-1]) + (ptr[step+1] - ptr[-step+1]);
169 pts[ptidx].response = ((float)a * b - (float)c * c -
170 harris_k * ((float)a + b) * ((float)a + b))*scale_sq_sq;
174 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
176 static void ICAngles(const Mat& img, const std::vector<Rect>& layerinfo,
177 std::vector<KeyPoint>& pts, const std::vector<int> & u_max, int half_k)
179 int step = (int)img.step1();
180 size_t ptidx, ptsize = pts.size();
182 for( ptidx = 0; ptidx < ptsize; ptidx++ )
184 const Rect& layer = layerinfo[pts[ptidx].octave];
185 const uchar* center = &img.at<uchar>(cvRound(pts[ptidx].pt.y) + layer.y, cvRound(pts[ptidx].pt.x) + layer.x);
187 int m_01 = 0, m_10 = 0;
189 // Treat the center line differently, v=0
190 for (int u = -half_k; u <= half_k; ++u)
191 m_10 += u * center[u];
193 // Go line by line in the circular patch
194 for (int v = 1; v <= half_k; ++v)
196 // Proceed over the two lines
199 for (int u = -d; u <= d; ++u)
201 int val_plus = center[u + v*step], val_minus = center[u - v*step];
202 v_sum += (val_plus - val_minus);
203 m_10 += u * (val_plus + val_minus);
208 pts[ptidx].angle = fastAtan2((float)m_01, (float)m_10);
212 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
215 computeOrbDescriptors( const Mat& imagePyramid, const std::vector<Rect>& layerInfo,
216 const std::vector<float>& layerScale, std::vector<KeyPoint>& keypoints,
217 Mat& descriptors, const std::vector<Point>& _pattern, int dsize, int wta_k )
219 int step = (int)imagePyramid.step;
220 int j, i, nkeypoints = (int)keypoints.size();
222 for( j = 0; j < nkeypoints; j++ )
224 const KeyPoint& kpt = keypoints[j];
225 const Rect& layer = layerInfo[kpt.octave];
226 float scale = 1.f/layerScale[kpt.octave];
227 float angle = kpt.angle;
229 angle *= (float)(CV_PI/180.f);
230 float a = (float)cos(angle), b = (float)sin(angle);
232 const uchar* center = &imagePyramid.at<uchar>(cvRound(kpt.pt.y*scale) + layer.y,
233 cvRound(kpt.pt.x*scale) + layer.x);
236 const Point* pattern = &_pattern[0];
237 uchar* desc = descriptors.ptr<uchar>(j);
240 #define GET_VALUE(idx) \
241 (x = pattern[idx].x*a - pattern[idx].y*b, \
242 y = pattern[idx].x*b + pattern[idx].y*a, \
245 *(center + iy*step + ix) )
247 #define GET_VALUE(idx) \
248 (x = pattern[idx].x*a - pattern[idx].y*b, \
249 y = pattern[idx].x*b + pattern[idx].y*a, \
250 ix = cvFloor(x), iy = cvFloor(y), \
252 cvRound(center[iy*step + ix]*(1-x)*(1-y) + center[(iy+1)*step + ix]*(1-x)*y + \
253 center[iy*step + ix+1]*x*(1-y) + center[(iy+1)*step + ix+1]*x*y))
258 for (i = 0; i < dsize; ++i, pattern += 16)
261 t0 = GET_VALUE(0); t1 = GET_VALUE(1);
263 t0 = GET_VALUE(2); t1 = GET_VALUE(3);
264 val |= (t0 < t1) << 1;
265 t0 = GET_VALUE(4); t1 = GET_VALUE(5);
266 val |= (t0 < t1) << 2;
267 t0 = GET_VALUE(6); t1 = GET_VALUE(7);
268 val |= (t0 < t1) << 3;
269 t0 = GET_VALUE(8); t1 = GET_VALUE(9);
270 val |= (t0 < t1) << 4;
271 t0 = GET_VALUE(10); t1 = GET_VALUE(11);
272 val |= (t0 < t1) << 5;
273 t0 = GET_VALUE(12); t1 = GET_VALUE(13);
274 val |= (t0 < t1) << 6;
275 t0 = GET_VALUE(14); t1 = GET_VALUE(15);
276 val |= (t0 < t1) << 7;
278 desc[i] = (uchar)val;
281 else if( wta_k == 3 )
283 for (i = 0; i < dsize; ++i, pattern += 12)
286 t0 = GET_VALUE(0); t1 = GET_VALUE(1); t2 = GET_VALUE(2);
287 val = t2 > t1 ? (t2 > t0 ? 2 : 0) : (t1 > t0);
289 t0 = GET_VALUE(3); t1 = GET_VALUE(4); t2 = GET_VALUE(5);
290 val |= (t2 > t1 ? (t2 > t0 ? 2 : 0) : (t1 > t0)) << 2;
292 t0 = GET_VALUE(6); t1 = GET_VALUE(7); t2 = GET_VALUE(8);
293 val |= (t2 > t1 ? (t2 > t0 ? 2 : 0) : (t1 > t0)) << 4;
295 t0 = GET_VALUE(9); t1 = GET_VALUE(10); t2 = GET_VALUE(11);
296 val |= (t2 > t1 ? (t2 > t0 ? 2 : 0) : (t1 > t0)) << 6;
298 desc[i] = (uchar)val;
301 else if( wta_k == 4 )
303 for (i = 0; i < dsize; ++i, pattern += 16)
305 int t0, t1, t2, t3, u, v, k, val;
306 t0 = GET_VALUE(0); t1 = GET_VALUE(1);
307 t2 = GET_VALUE(2); t3 = GET_VALUE(3);
309 if( t1 > t0 ) t0 = t1, u = 1;
310 if( t3 > t2 ) t2 = t3, v = 3;
314 t0 = GET_VALUE(4); t1 = GET_VALUE(5);
315 t2 = GET_VALUE(6); t3 = GET_VALUE(7);
317 if( t1 > t0 ) t0 = t1, u = 1;
318 if( t3 > t2 ) t2 = t3, v = 3;
322 t0 = GET_VALUE(8); t1 = GET_VALUE(9);
323 t2 = GET_VALUE(10); t3 = GET_VALUE(11);
325 if( t1 > t0 ) t0 = t1, u = 1;
326 if( t3 > t2 ) t2 = t3, v = 3;
330 t0 = GET_VALUE(12); t1 = GET_VALUE(13);
331 t2 = GET_VALUE(14); t3 = GET_VALUE(15);
333 if( t1 > t0 ) t0 = t1, u = 1;
334 if( t3 > t2 ) t2 = t3, v = 3;
338 desc[i] = (uchar)val;
342 CV_Error( Error::StsBadSize, "Wrong wta_k. It can be only 2, 3 or 4." );
348 static void initializeOrbPattern( const Point* pattern0, std::vector<Point>& pattern, int ntuples, int tupleSize, int poolSize )
352 pattern.resize(ntuples*tupleSize);
354 for( i = 0; i < ntuples; i++ )
356 for( k = 0; k < tupleSize; k++ )
360 int idx = rng.uniform(0, poolSize);
361 Point pt = pattern0[idx];
362 for( k1 = 0; k1 < k; k1++ )
363 if( pattern[tupleSize*i + k1] == pt )
367 pattern[tupleSize*i + k] = pt;
375 static int bit_pattern_31_[256*4] =
377 8,-3, 9,5/*mean (0), correlation (0)*/,
378 4,2, 7,-12/*mean (1.12461e-05), correlation (0.0437584)*/,
379 -11,9, -8,2/*mean (3.37382e-05), correlation (0.0617409)*/,
380 7,-12, 12,-13/*mean (5.62303e-05), correlation (0.0636977)*/,
381 2,-13, 2,12/*mean (0.000134953), correlation (0.085099)*/,
382 1,-7, 1,6/*mean (0.000528565), correlation (0.0857175)*/,
383 -2,-10, -2,-4/*mean (0.0188821), correlation (0.0985774)*/,
384 -13,-13, -11,-8/*mean (0.0363135), correlation (0.0899616)*/,
385 -13,-3, -12,-9/*mean (0.121806), correlation (0.099849)*/,
386 10,4, 11,9/*mean (0.122065), correlation (0.093285)*/,
387 -13,-8, -8,-9/*mean (0.162787), correlation (0.0942748)*/,
388 -11,7, -9,12/*mean (0.21561), correlation (0.0974438)*/,
389 7,7, 12,6/*mean (0.160583), correlation (0.130064)*/,
390 -4,-5, -3,0/*mean (0.228171), correlation (0.132998)*/,
391 -13,2, -12,-3/*mean (0.00997526), correlation (0.145926)*/,
392 -9,0, -7,5/*mean (0.198234), correlation (0.143636)*/,
393 12,-6, 12,-1/*mean (0.0676226), correlation (0.16689)*/,
394 -3,6, -2,12/*mean (0.166847), correlation (0.171682)*/,
395 -6,-13, -4,-8/*mean (0.101215), correlation (0.179716)*/,
396 11,-13, 12,-8/*mean (0.200641), correlation (0.192279)*/,
397 4,7, 5,1/*mean (0.205106), correlation (0.186848)*/,
398 5,-3, 10,-3/*mean (0.234908), correlation (0.192319)*/,
399 3,-7, 6,12/*mean (0.0709964), correlation (0.210872)*/,
400 -8,-7, -6,-2/*mean (0.0939834), correlation (0.212589)*/,
401 -2,11, -1,-10/*mean (0.127778), correlation (0.20866)*/,
402 -13,12, -8,10/*mean (0.14783), correlation (0.206356)*/,
403 -7,3, -5,-3/*mean (0.182141), correlation (0.198942)*/,
404 -4,2, -3,7/*mean (0.188237), correlation (0.21384)*/,
405 -10,-12, -6,11/*mean (0.14865), correlation (0.23571)*/,
406 5,-12, 6,-7/*mean (0.222312), correlation (0.23324)*/,
407 5,-6, 7,-1/*mean (0.229082), correlation (0.23389)*/,
408 1,0, 4,-5/*mean (0.241577), correlation (0.215286)*/,
409 9,11, 11,-13/*mean (0.00338507), correlation (0.251373)*/,
410 4,7, 4,12/*mean (0.131005), correlation (0.257622)*/,
411 2,-1, 4,4/*mean (0.152755), correlation (0.255205)*/,
412 -4,-12, -2,7/*mean (0.182771), correlation (0.244867)*/,
413 -8,-5, -7,-10/*mean (0.186898), correlation (0.23901)*/,
414 4,11, 9,12/*mean (0.226226), correlation (0.258255)*/,
415 0,-8, 1,-13/*mean (0.0897886), correlation (0.274827)*/,
416 -13,-2, -8,2/*mean (0.148774), correlation (0.28065)*/,
417 -3,-2, -2,3/*mean (0.153048), correlation (0.283063)*/,
418 -6,9, -4,-9/*mean (0.169523), correlation (0.278248)*/,
419 8,12, 10,7/*mean (0.225337), correlation (0.282851)*/,
420 0,9, 1,3/*mean (0.226687), correlation (0.278734)*/,
421 7,-5, 11,-10/*mean (0.00693882), correlation (0.305161)*/,
422 -13,-6, -11,0/*mean (0.0227283), correlation (0.300181)*/,
423 10,7, 12,1/*mean (0.125517), correlation (0.31089)*/,
424 -6,-3, -6,12/*mean (0.131748), correlation (0.312779)*/,
425 10,-9, 12,-4/*mean (0.144827), correlation (0.292797)*/,
426 -13,8, -8,-12/*mean (0.149202), correlation (0.308918)*/,
427 -13,0, -8,-4/*mean (0.160909), correlation (0.310013)*/,
428 3,3, 7,8/*mean (0.177755), correlation (0.309394)*/,
429 5,7, 10,-7/*mean (0.212337), correlation (0.310315)*/,
430 -1,7, 1,-12/*mean (0.214429), correlation (0.311933)*/,
431 3,-10, 5,6/*mean (0.235807), correlation (0.313104)*/,
432 2,-4, 3,-10/*mean (0.00494827), correlation (0.344948)*/,
433 -13,0, -13,5/*mean (0.0549145), correlation (0.344675)*/,
434 -13,-7, -12,12/*mean (0.103385), correlation (0.342715)*/,
435 -13,3, -11,8/*mean (0.134222), correlation (0.322922)*/,
436 -7,12, -4,7/*mean (0.153284), correlation (0.337061)*/,
437 6,-10, 12,8/*mean (0.154881), correlation (0.329257)*/,
438 -9,-1, -7,-6/*mean (0.200967), correlation (0.33312)*/,
439 -2,-5, 0,12/*mean (0.201518), correlation (0.340635)*/,
440 -12,5, -7,5/*mean (0.207805), correlation (0.335631)*/,
441 3,-10, 8,-13/*mean (0.224438), correlation (0.34504)*/,
442 -7,-7, -4,5/*mean (0.239361), correlation (0.338053)*/,
443 -3,-2, -1,-7/*mean (0.240744), correlation (0.344322)*/,
444 2,9, 5,-11/*mean (0.242949), correlation (0.34145)*/,
445 -11,-13, -5,-13/*mean (0.244028), correlation (0.336861)*/,
446 -1,6, 0,-1/*mean (0.247571), correlation (0.343684)*/,
447 5,-3, 5,2/*mean (0.000697256), correlation (0.357265)*/,
448 -4,-13, -4,12/*mean (0.00213675), correlation (0.373827)*/,
449 -9,-6, -9,6/*mean (0.0126856), correlation (0.373938)*/,
450 -12,-10, -8,-4/*mean (0.0152497), correlation (0.364237)*/,
451 10,2, 12,-3/*mean (0.0299933), correlation (0.345292)*/,
452 7,12, 12,12/*mean (0.0307242), correlation (0.366299)*/,
453 -7,-13, -6,5/*mean (0.0534975), correlation (0.368357)*/,
454 -4,9, -3,4/*mean (0.099865), correlation (0.372276)*/,
455 7,-1, 12,2/*mean (0.117083), correlation (0.364529)*/,
456 -7,6, -5,1/*mean (0.126125), correlation (0.369606)*/,
457 -13,11, -12,5/*mean (0.130364), correlation (0.358502)*/,
458 -3,7, -2,-6/*mean (0.131691), correlation (0.375531)*/,
459 7,-8, 12,-7/*mean (0.160166), correlation (0.379508)*/,
460 -13,-7, -11,-12/*mean (0.167848), correlation (0.353343)*/,
461 1,-3, 12,12/*mean (0.183378), correlation (0.371916)*/,
462 2,-6, 3,0/*mean (0.228711), correlation (0.371761)*/,
463 -4,3, -2,-13/*mean (0.247211), correlation (0.364063)*/,
464 -1,-13, 1,9/*mean (0.249325), correlation (0.378139)*/,
465 7,1, 8,-6/*mean (0.000652272), correlation (0.411682)*/,
466 1,-1, 3,12/*mean (0.00248538), correlation (0.392988)*/,
467 9,1, 12,6/*mean (0.0206815), correlation (0.386106)*/,
468 -1,-9, -1,3/*mean (0.0364485), correlation (0.410752)*/,
469 -13,-13, -10,5/*mean (0.0376068), correlation (0.398374)*/,
470 7,7, 10,12/*mean (0.0424202), correlation (0.405663)*/,
471 12,-5, 12,9/*mean (0.0942645), correlation (0.410422)*/,
472 6,3, 7,11/*mean (0.1074), correlation (0.413224)*/,
473 5,-13, 6,10/*mean (0.109256), correlation (0.408646)*/,
474 2,-12, 2,3/*mean (0.131691), correlation (0.416076)*/,
475 3,8, 4,-6/*mean (0.165081), correlation (0.417569)*/,
476 2,6, 12,-13/*mean (0.171874), correlation (0.408471)*/,
477 9,-12, 10,3/*mean (0.175146), correlation (0.41296)*/,
478 -8,4, -7,9/*mean (0.183682), correlation (0.402956)*/,
479 -11,12, -4,-6/*mean (0.184672), correlation (0.416125)*/,
480 1,12, 2,-8/*mean (0.191487), correlation (0.386696)*/,
481 6,-9, 7,-4/*mean (0.192668), correlation (0.394771)*/,
482 2,3, 3,-2/*mean (0.200157), correlation (0.408303)*/,
483 6,3, 11,0/*mean (0.204588), correlation (0.411762)*/,
484 3,-3, 8,-8/*mean (0.205904), correlation (0.416294)*/,
485 7,8, 9,3/*mean (0.213237), correlation (0.409306)*/,
486 -11,-5, -6,-4/*mean (0.243444), correlation (0.395069)*/,
487 -10,11, -5,10/*mean (0.247672), correlation (0.413392)*/,
488 -5,-8, -3,12/*mean (0.24774), correlation (0.411416)*/,
489 -10,5, -9,0/*mean (0.00213675), correlation (0.454003)*/,
490 8,-1, 12,-6/*mean (0.0293635), correlation (0.455368)*/,
491 4,-6, 6,-11/*mean (0.0404971), correlation (0.457393)*/,
492 -10,12, -8,7/*mean (0.0481107), correlation (0.448364)*/,
493 4,-2, 6,7/*mean (0.050641), correlation (0.455019)*/,
494 -2,0, -2,12/*mean (0.0525978), correlation (0.44338)*/,
495 -5,-8, -5,2/*mean (0.0629667), correlation (0.457096)*/,
496 7,-6, 10,12/*mean (0.0653846), correlation (0.445623)*/,
497 -9,-13, -8,-8/*mean (0.0858749), correlation (0.449789)*/,
498 -5,-13, -5,-2/*mean (0.122402), correlation (0.450201)*/,
499 8,-8, 9,-13/*mean (0.125416), correlation (0.453224)*/,
500 -9,-11, -9,0/*mean (0.130128), correlation (0.458724)*/,
501 1,-8, 1,-2/*mean (0.132467), correlation (0.440133)*/,
502 7,-4, 9,1/*mean (0.132692), correlation (0.454)*/,
503 -2,1, -1,-4/*mean (0.135695), correlation (0.455739)*/,
504 11,-6, 12,-11/*mean (0.142904), correlation (0.446114)*/,
505 -12,-9, -6,4/*mean (0.146165), correlation (0.451473)*/,
506 3,7, 7,12/*mean (0.147627), correlation (0.456643)*/,
507 5,5, 10,8/*mean (0.152901), correlation (0.455036)*/,
508 0,-4, 2,8/*mean (0.167083), correlation (0.459315)*/,
509 -9,12, -5,-13/*mean (0.173234), correlation (0.454706)*/,
510 0,7, 2,12/*mean (0.18312), correlation (0.433855)*/,
511 -1,2, 1,7/*mean (0.185504), correlation (0.443838)*/,
512 5,11, 7,-9/*mean (0.185706), correlation (0.451123)*/,
513 3,5, 6,-8/*mean (0.188968), correlation (0.455808)*/,
514 -13,-4, -8,9/*mean (0.191667), correlation (0.459128)*/,
515 -5,9, -3,-3/*mean (0.193196), correlation (0.458364)*/,
516 -4,-7, -3,-12/*mean (0.196536), correlation (0.455782)*/,
517 6,5, 8,0/*mean (0.1972), correlation (0.450481)*/,
518 -7,6, -6,12/*mean (0.199438), correlation (0.458156)*/,
519 -13,6, -5,-2/*mean (0.211224), correlation (0.449548)*/,
520 1,-10, 3,10/*mean (0.211718), correlation (0.440606)*/,
521 4,1, 8,-4/*mean (0.213034), correlation (0.443177)*/,
522 -2,-2, 2,-13/*mean (0.234334), correlation (0.455304)*/,
523 2,-12, 12,12/*mean (0.235684), correlation (0.443436)*/,
524 -2,-13, 0,-6/*mean (0.237674), correlation (0.452525)*/,
525 4,1, 9,3/*mean (0.23962), correlation (0.444824)*/,
526 -6,-10, -3,-5/*mean (0.248459), correlation (0.439621)*/,
527 -3,-13, -1,1/*mean (0.249505), correlation (0.456666)*/,
528 7,5, 12,-11/*mean (0.00119208), correlation (0.495466)*/,
529 4,-2, 5,-7/*mean (0.00372245), correlation (0.484214)*/,
530 -13,9, -9,-5/*mean (0.00741116), correlation (0.499854)*/,
531 7,1, 8,6/*mean (0.0208952), correlation (0.499773)*/,
532 7,-8, 7,6/*mean (0.0220085), correlation (0.501609)*/,
533 -7,-4, -7,1/*mean (0.0233806), correlation (0.496568)*/,
534 -8,11, -7,-8/*mean (0.0236505), correlation (0.489719)*/,
535 -13,6, -12,-8/*mean (0.0268781), correlation (0.503487)*/,
536 2,4, 3,9/*mean (0.0323324), correlation (0.501938)*/,
537 10,-5, 12,3/*mean (0.0399235), correlation (0.494029)*/,
538 -6,-5, -6,7/*mean (0.0420153), correlation (0.486579)*/,
539 8,-3, 9,-8/*mean (0.0548021), correlation (0.484237)*/,
540 2,-12, 2,8/*mean (0.0616622), correlation (0.496642)*/,
541 -11,-2, -10,3/*mean (0.0627755), correlation (0.498563)*/,
542 -12,-13, -7,-9/*mean (0.0829622), correlation (0.495491)*/,
543 -11,0, -10,-5/*mean (0.0843342), correlation (0.487146)*/,
544 5,-3, 11,8/*mean (0.0929937), correlation (0.502315)*/,
545 -2,-13, -1,12/*mean (0.113327), correlation (0.48941)*/,
546 -1,-8, 0,9/*mean (0.132119), correlation (0.467268)*/,
547 -13,-11, -12,-5/*mean (0.136269), correlation (0.498771)*/,
548 -10,-2, -10,11/*mean (0.142173), correlation (0.498714)*/,
549 -3,9, -2,-13/*mean (0.144141), correlation (0.491973)*/,
550 2,-3, 3,2/*mean (0.14892), correlation (0.500782)*/,
551 -9,-13, -4,0/*mean (0.150371), correlation (0.498211)*/,
552 -4,6, -3,-10/*mean (0.152159), correlation (0.495547)*/,
553 -4,12, -2,-7/*mean (0.156152), correlation (0.496925)*/,
554 -6,-11, -4,9/*mean (0.15749), correlation (0.499222)*/,
555 6,-3, 6,11/*mean (0.159211), correlation (0.503821)*/,
556 -13,11, -5,5/*mean (0.162427), correlation (0.501907)*/,
557 11,11, 12,6/*mean (0.16652), correlation (0.497632)*/,
558 7,-5, 12,-2/*mean (0.169141), correlation (0.484474)*/,
559 -1,12, 0,7/*mean (0.169456), correlation (0.495339)*/,
560 -4,-8, -3,-2/*mean (0.171457), correlation (0.487251)*/,
561 -7,1, -6,7/*mean (0.175), correlation (0.500024)*/,
562 -13,-12, -8,-13/*mean (0.175866), correlation (0.497523)*/,
563 -7,-2, -6,-8/*mean (0.178273), correlation (0.501854)*/,
564 -8,5, -6,-9/*mean (0.181107), correlation (0.494888)*/,
565 -5,-1, -4,5/*mean (0.190227), correlation (0.482557)*/,
566 -13,7, -8,10/*mean (0.196739), correlation (0.496503)*/,
567 1,5, 5,-13/*mean (0.19973), correlation (0.499759)*/,
568 1,0, 10,-13/*mean (0.204465), correlation (0.49873)*/,
569 9,12, 10,-1/*mean (0.209334), correlation (0.49063)*/,
570 5,-8, 10,-9/*mean (0.211134), correlation (0.503011)*/,
571 -1,11, 1,-13/*mean (0.212), correlation (0.499414)*/,
572 -9,-3, -6,2/*mean (0.212168), correlation (0.480739)*/,
573 -1,-10, 1,12/*mean (0.212731), correlation (0.502523)*/,
574 -13,1, -8,-10/*mean (0.21327), correlation (0.489786)*/,
575 8,-11, 10,-6/*mean (0.214159), correlation (0.488246)*/,
576 2,-13, 3,-6/*mean (0.216993), correlation (0.50287)*/,
577 7,-13, 12,-9/*mean (0.223639), correlation (0.470502)*/,
578 -10,-10, -5,-7/*mean (0.224089), correlation (0.500852)*/,
579 -10,-8, -8,-13/*mean (0.228666), correlation (0.502629)*/,
580 4,-6, 8,5/*mean (0.22906), correlation (0.498305)*/,
581 3,12, 8,-13/*mean (0.233378), correlation (0.503825)*/,
582 -4,2, -3,-3/*mean (0.234323), correlation (0.476692)*/,
583 5,-13, 10,-12/*mean (0.236392), correlation (0.475462)*/,
584 4,-13, 5,-1/*mean (0.236842), correlation (0.504132)*/,
585 -9,9, -4,3/*mean (0.236977), correlation (0.497739)*/,
586 0,3, 3,-9/*mean (0.24314), correlation (0.499398)*/,
587 -12,1, -6,1/*mean (0.243297), correlation (0.489447)*/,
588 3,2, 4,-8/*mean (0.00155196), correlation (0.553496)*/,
589 -10,-10, -10,9/*mean (0.00239541), correlation (0.54297)*/,
590 8,-13, 12,12/*mean (0.0034413), correlation (0.544361)*/,
591 -8,-12, -6,-5/*mean (0.003565), correlation (0.551225)*/,
592 2,2, 3,7/*mean (0.00835583), correlation (0.55285)*/,
593 10,6, 11,-8/*mean (0.00885065), correlation (0.540913)*/,
594 6,8, 8,-12/*mean (0.0101552), correlation (0.551085)*/,
595 -7,10, -6,5/*mean (0.0102227), correlation (0.533635)*/,
596 -3,-9, -3,9/*mean (0.0110211), correlation (0.543121)*/,
597 -1,-13, -1,5/*mean (0.0113473), correlation (0.550173)*/,
598 -3,-7, -3,4/*mean (0.0140913), correlation (0.554774)*/,
599 -8,-2, -8,3/*mean (0.017049), correlation (0.55461)*/,
600 4,2, 12,12/*mean (0.01778), correlation (0.546921)*/,
601 2,-5, 3,11/*mean (0.0224022), correlation (0.549667)*/,
602 6,-9, 11,-13/*mean (0.029161), correlation (0.546295)*/,
603 3,-1, 7,12/*mean (0.0303081), correlation (0.548599)*/,
604 11,-1, 12,4/*mean (0.0355151), correlation (0.523943)*/,
605 -3,0, -3,6/*mean (0.0417904), correlation (0.543395)*/,
606 4,-11, 4,12/*mean (0.0487292), correlation (0.542818)*/,
607 2,-4, 2,1/*mean (0.0575124), correlation (0.554888)*/,
608 -10,-6, -8,1/*mean (0.0594242), correlation (0.544026)*/,
609 -13,7, -11,1/*mean (0.0597391), correlation (0.550524)*/,
610 -13,12, -11,-13/*mean (0.0608974), correlation (0.55383)*/,
611 6,0, 11,-13/*mean (0.065126), correlation (0.552006)*/,
612 0,-1, 1,4/*mean (0.074224), correlation (0.546372)*/,
613 -13,3, -9,-2/*mean (0.0808592), correlation (0.554875)*/,
614 -9,8, -6,-3/*mean (0.0883378), correlation (0.551178)*/,
615 -13,-6, -8,-2/*mean (0.0901035), correlation (0.548446)*/,
616 5,-9, 8,10/*mean (0.0949843), correlation (0.554694)*/,
617 2,7, 3,-9/*mean (0.0994152), correlation (0.550979)*/,
618 -1,-6, -1,-1/*mean (0.10045), correlation (0.552714)*/,
619 9,5, 11,-2/*mean (0.100686), correlation (0.552594)*/,
620 11,-3, 12,-8/*mean (0.101091), correlation (0.532394)*/,
621 3,0, 3,5/*mean (0.101147), correlation (0.525576)*/,
622 -1,4, 0,10/*mean (0.105263), correlation (0.531498)*/,
623 3,-6, 4,5/*mean (0.110785), correlation (0.540491)*/,
624 -13,0, -10,5/*mean (0.112798), correlation (0.536582)*/,
625 5,8, 12,11/*mean (0.114181), correlation (0.555793)*/,
626 8,9, 9,-6/*mean (0.117431), correlation (0.553763)*/,
627 7,-4, 8,-12/*mean (0.118522), correlation (0.553452)*/,
628 -10,4, -10,9/*mean (0.12094), correlation (0.554785)*/,
629 7,3, 12,4/*mean (0.122582), correlation (0.555825)*/,
630 9,-7, 10,-2/*mean (0.124978), correlation (0.549846)*/,
631 7,0, 12,-2/*mean (0.127002), correlation (0.537452)*/,
632 -1,-6, 0,-11/*mean (0.127148), correlation (0.547401)*/
636 static void makeRandomPattern(int patchSize, Point* pattern, int npoints)
638 RNG rng(0x34985739); // we always start with a fixed seed,
639 // to make patterns the same on each run
640 for( int i = 0; i < npoints; i++ )
642 pattern[i].x = rng.uniform(-patchSize/2, patchSize/2+1);
643 pattern[i].y = rng.uniform(-patchSize/2, patchSize/2+1);
648 static inline float getScale(int level, int firstLevel, double scaleFactor)
650 return (float)std::pow(scaleFactor, (double)(level - firstLevel));
654 class ORB_Impl CV_FINAL : public ORB
657 explicit ORB_Impl(int _nfeatures, float _scaleFactor, int _nlevels, int _edgeThreshold,
658 int _firstLevel, int _WTA_K, int _scoreType, int _patchSize, int _fastThreshold) :
659 nfeatures(_nfeatures), scaleFactor(_scaleFactor), nlevels(_nlevels),
660 edgeThreshold(_edgeThreshold), firstLevel(_firstLevel), wta_k(_WTA_K),
661 scoreType(_scoreType), patchSize(_patchSize), fastThreshold(_fastThreshold)
664 void setMaxFeatures(int maxFeatures) CV_OVERRIDE { nfeatures = maxFeatures; }
665 int getMaxFeatures() const CV_OVERRIDE { return nfeatures; }
667 void setScaleFactor(double scaleFactor_) CV_OVERRIDE { scaleFactor = scaleFactor_; }
668 double getScaleFactor() const CV_OVERRIDE { return scaleFactor; }
670 void setNLevels(int nlevels_) CV_OVERRIDE { nlevels = nlevels_; }
671 int getNLevels() const CV_OVERRIDE { return nlevels; }
673 void setEdgeThreshold(int edgeThreshold_) CV_OVERRIDE { edgeThreshold = edgeThreshold_; }
674 int getEdgeThreshold() const CV_OVERRIDE { return edgeThreshold; }
676 void setFirstLevel(int firstLevel_) CV_OVERRIDE { CV_Assert(firstLevel_ >= 0); firstLevel = firstLevel_; }
677 int getFirstLevel() const CV_OVERRIDE { return firstLevel; }
679 void setWTA_K(int wta_k_) CV_OVERRIDE { wta_k = wta_k_; }
680 int getWTA_K() const CV_OVERRIDE { return wta_k; }
682 void setScoreType(int scoreType_) CV_OVERRIDE { scoreType = scoreType_; }
683 int getScoreType() const CV_OVERRIDE { return scoreType; }
685 void setPatchSize(int patchSize_) CV_OVERRIDE { patchSize = patchSize_; }
686 int getPatchSize() const CV_OVERRIDE { return patchSize; }
688 void setFastThreshold(int fastThreshold_) CV_OVERRIDE { fastThreshold = fastThreshold_; }
689 int getFastThreshold() const CV_OVERRIDE { return fastThreshold; }
691 // returns the descriptor size in bytes
692 int descriptorSize() const CV_OVERRIDE;
693 // returns the descriptor type
694 int descriptorType() const CV_OVERRIDE;
695 // returns the default norm type
696 int defaultNorm() const CV_OVERRIDE;
698 // Compute the ORB_Impl features and descriptors on an image
699 void detectAndCompute( InputArray image, InputArray mask, std::vector<KeyPoint>& keypoints,
700 OutputArray descriptors, bool useProvidedKeypoints=false ) CV_OVERRIDE;
715 int ORB_Impl::descriptorSize() const
720 int ORB_Impl::descriptorType() const
725 int ORB_Impl::defaultNorm() const
733 return NORM_HAMMING2;
740 static void uploadORBKeypoints(const std::vector<KeyPoint>& src, std::vector<Vec3i>& buf, OutputArray dst)
742 size_t i, n = src.size();
743 buf.resize(std::max(buf.size(), n));
744 for( i = 0; i < n; i++ )
745 buf[i] = Vec3i(cvRound(src[i].pt.x), cvRound(src[i].pt.y), src[i].octave);
746 copyVectorToUMat(buf, dst);
756 static void uploadORBKeypoints(const std::vector<KeyPoint>& src,
757 const std::vector<float>& layerScale,
758 std::vector<Vec4i>& buf, OutputArray dst)
760 size_t i, n = src.size();
761 buf.resize(std::max(buf.size(), n));
762 for( i = 0; i < n; i++ )
764 int z = src[i].octave;
765 float scale = 1.f/layerScale[z];
767 angle.f = src[i].angle;
768 buf[i] = Vec4i(cvRound(src[i].pt.x*scale), cvRound(src[i].pt.y*scale), z, angle.i);
770 copyVectorToUMat(buf, dst);
774 /** Compute the ORB_Impl keypoints on an image
775 * @param image_pyramid the image pyramid to compute the features and descriptors on
776 * @param mask_pyramid the masks to apply at every level
777 * @param keypoints the resulting keypoints, clustered per level
779 static void computeKeyPoints(const Mat& imagePyramid,
780 const UMat& uimagePyramid,
781 const Mat& maskPyramid,
782 const std::vector<Rect>& layerInfo,
783 const UMat& ulayerInfo,
784 const std::vector<float>& layerScale,
785 std::vector<KeyPoint>& allKeypoints,
786 int nfeatures, double scaleFactor,
787 int edgeThreshold, int patchSize, int scoreType,
788 bool useOCL, int fastThreshold )
791 CV_UNUSED(uimagePyramid);CV_UNUSED(ulayerInfo);CV_UNUSED(useOCL);
794 int i, nkeypoints, level, nlevels = (int)layerInfo.size();
795 std::vector<int> nfeaturesPerLevel(nlevels);
797 // fill the extractors and descriptors for the corresponding scales
798 float factor = (float)(1.0 / scaleFactor);
799 float ndesiredFeaturesPerScale = nfeatures*(1 - factor)/(1 - (float)std::pow((double)factor, (double)nlevels));
802 for( level = 0; level < nlevels-1; level++ )
804 nfeaturesPerLevel[level] = cvRound(ndesiredFeaturesPerScale);
805 sumFeatures += nfeaturesPerLevel[level];
806 ndesiredFeaturesPerScale *= factor;
808 nfeaturesPerLevel[nlevels-1] = std::max(nfeatures - sumFeatures, 0);
810 // Make sure we forget about what is too close to the boundary
811 //edge_threshold_ = std::max(edge_threshold_, patch_size_/2 + kKernelWidth / 2 + 2);
813 // pre-compute the end of a row in a circular patch
814 int halfPatchSize = patchSize / 2;
815 std::vector<int> umax(halfPatchSize + 2);
817 int v, v0, vmax = cvFloor(halfPatchSize * std::sqrt(2.f) / 2 + 1);
818 int vmin = cvCeil(halfPatchSize * std::sqrt(2.f) / 2);
819 for (v = 0; v <= vmax; ++v)
820 umax[v] = cvRound(std::sqrt((double)halfPatchSize * halfPatchSize - v * v));
822 // Make sure we are symmetric
823 for (v = halfPatchSize, v0 = 0; v >= vmin; --v)
825 while (umax[v0] == umax[v0 + 1])
831 allKeypoints.clear();
832 std::vector<KeyPoint> keypoints;
833 std::vector<int> counters(nlevels);
834 keypoints.reserve(nfeaturesPerLevel[0]*2);
836 for( level = 0; level < nlevels; level++ )
838 int featuresNum = nfeaturesPerLevel[level];
839 Mat img = imagePyramid(layerInfo[level]);
840 Mat mask = maskPyramid.empty() ? Mat() : maskPyramid(layerInfo[level]);
842 // Detect FAST features, 20 is a good threshold
844 Ptr<FastFeatureDetector> fd = FastFeatureDetector::create(fastThreshold, true);
845 fd->detect(img, keypoints, mask);
848 // Remove keypoints very close to the border
849 KeyPointsFilter::runByImageBorder(keypoints, img.size(), edgeThreshold);
851 // Keep more points than necessary as FAST does not give amazing corners
852 KeyPointsFilter::retainBest(keypoints, scoreType == ORB_Impl::HARRIS_SCORE ? 2 * featuresNum : featuresNum);
854 nkeypoints = (int)keypoints.size();
855 counters[level] = nkeypoints;
857 float sf = layerScale[level];
858 for( i = 0; i < nkeypoints; i++ )
860 keypoints[i].octave = level;
861 keypoints[i].size = patchSize*sf;
864 std::copy(keypoints.begin(), keypoints.end(), std::back_inserter(allKeypoints));
867 std::vector<Vec3i> ukeypoints_buf;
869 nkeypoints = (int)allKeypoints.size();
875 UMat ukeypoints, uresponses(1, nkeypoints, CV_32F);
877 // Select best features using the Harris cornerness (better scoring than FAST)
878 if( scoreType == ORB_Impl::HARRIS_SCORE )
883 uploadORBKeypoints(allKeypoints, ukeypoints_buf, ukeypoints);
884 useOCL = ocl_HarrisResponses( uimagePyramid, ulayerInfo, ukeypoints,
885 uresponses, nkeypoints, 7, HARRIS_K );
888 CV_IMPL_ADD(CV_IMPL_OCL);
889 uresponses.copyTo(responses);
890 for( i = 0; i < nkeypoints; i++ )
891 allKeypoints[i].response = responses.at<float>(i);
897 HarrisResponses(imagePyramid, layerInfo, allKeypoints, 7, HARRIS_K);
899 std::vector<KeyPoint> newAllKeypoints;
900 newAllKeypoints.reserve(nfeaturesPerLevel[0]*nlevels);
903 for( level = 0; level < nlevels; level++ )
905 int featuresNum = nfeaturesPerLevel[level];
906 nkeypoints = counters[level];
907 keypoints.resize(nkeypoints);
908 std::copy(allKeypoints.begin() + offset,
909 allKeypoints.begin() + offset + nkeypoints,
911 offset += nkeypoints;
913 //cull to the final desired level, using the new Harris scores.
914 KeyPointsFilter::retainBest(keypoints, featuresNum);
916 std::copy(keypoints.begin(), keypoints.end(), std::back_inserter(newAllKeypoints));
918 std::swap(allKeypoints, newAllKeypoints);
921 nkeypoints = (int)allKeypoints.size();
928 copyVectorToUMat(umax, uumax);
930 uploadORBKeypoints(allKeypoints, ukeypoints_buf, ukeypoints);
931 useOCL = ocl_ICAngles(uimagePyramid, ulayerInfo, ukeypoints, uresponses, uumax,
932 nkeypoints, halfPatchSize);
936 CV_IMPL_ADD(CV_IMPL_OCL);
937 uresponses.copyTo(responses);
938 for( i = 0; i < nkeypoints; i++ )
939 allKeypoints[i].angle = responses.at<float>(i);
946 ICAngles(imagePyramid, layerInfo, allKeypoints, umax, halfPatchSize);
949 for( i = 0; i < nkeypoints; i++ )
951 float scale = layerScale[allKeypoints[i].octave];
952 allKeypoints[i].pt *= scale;
957 /** Compute the ORB_Impl features and descriptors on an image
958 * @param img the image to compute the features and descriptors on
959 * @param mask the mask to apply
960 * @param keypoints the resulting keypoints
961 * @param descriptors the resulting descriptors
962 * @param do_keypoints if true, the keypoints are computed, otherwise used as an input
963 * @param do_descriptors if true, also computes the descriptors
965 void ORB_Impl::detectAndCompute( InputArray _image, InputArray _mask,
966 std::vector<KeyPoint>& keypoints,
967 OutputArray _descriptors, bool useProvidedKeypoints )
969 CV_INSTRUMENT_REGION();
971 CV_Assert(patchSize >= 2);
973 bool do_keypoints = !useProvidedKeypoints;
974 bool do_descriptors = _descriptors.needed();
976 if( (!do_keypoints && !do_descriptors) || _image.empty() )
980 const int HARRIS_BLOCK_SIZE = 9;
981 int halfPatchSize = patchSize / 2;
982 // sqrt(2.0) is for handling patch rotation
983 int descPatchSize = cvCeil(halfPatchSize*sqrt(2.0));
984 int border = std::max(edgeThreshold, std::max(descPatchSize, HARRIS_BLOCK_SIZE/2))+1;
986 bool useOCL = ocl::isOpenCLActivated() && OCL_FORCE_CHECK(_image.isUMat() || _descriptors.isUMat());
988 Mat image = _image.getMat(), mask = _mask.getMat();
989 if( image.type() != CV_8UC1 )
990 cvtColor(_image, image, COLOR_BGR2GRAY);
992 int i, level, nLevels = this->nlevels, nkeypoints = (int)keypoints.size();
993 bool sortedByLevel = true;
997 // if we have pre-computed keypoints, they may use more levels than it is set in parameters
998 // !!!TODO!!! implement more correct method, independent from the used keypoint detector.
999 // Namely, the detector should provide correct size of each keypoint. Based on the keypoint size
1000 // and the algorithm used (i.e. BRIEF, running on 31x31 patches) we should compute the approximate
1001 // scale-factor that we need to apply. Then we should cluster all the computed scale-factors and
1002 // for each cluster compute the corresponding image.
1004 // In short, ultimately the descriptor should
1005 // ignore octave parameter and deal only with the keypoint size.
1007 for( i = 0; i < nkeypoints; i++ )
1009 level = keypoints[i].octave;
1010 CV_Assert(level >= 0);
1011 if( i > 0 && level < keypoints[i-1].octave )
1012 sortedByLevel = false;
1013 nLevels = std::max(nLevels, level);
1018 std::vector<Rect> layerInfo(nLevels);
1019 std::vector<int> layerOfs(nLevels);
1020 std::vector<float> layerScale(nLevels);
1021 Mat imagePyramid, maskPyramid;
1022 UMat uimagePyramid, ulayerInfo;
1024 int level_dy = image.rows + border*2;
1025 Point level_ofs(0,0);
1026 Size bufSize((cvRound(image.cols/getScale(0, firstLevel, scaleFactor)) + border*2 + 15) & -16, 0);
1028 for( level = 0; level < nLevels; level++ )
1030 float scale = getScale(level, firstLevel, scaleFactor);
1031 layerScale[level] = scale;
1032 Size sz(cvRound(image.cols/scale), cvRound(image.rows/scale));
1033 Size wholeSize(sz.width + border*2, sz.height + border*2);
1034 if( level_ofs.x + wholeSize.width > bufSize.width )
1036 level_ofs = Point(0, level_ofs.y + level_dy);
1037 level_dy = wholeSize.height;
1040 Rect linfo(level_ofs.x + border, level_ofs.y + border, sz.width, sz.height);
1041 layerInfo[level] = linfo;
1042 layerOfs[level] = linfo.y*bufSize.width + linfo.x;
1043 level_ofs.x += wholeSize.width;
1045 bufSize.height = level_ofs.y + level_dy;
1047 imagePyramid.create(bufSize, CV_8U);
1049 maskPyramid.create(bufSize, CV_8U);
1051 Mat prevImg = image, prevMask = mask;
1053 // Pre-compute the scale pyramids
1054 for (level = 0; level < nLevels; ++level)
1056 Rect linfo = layerInfo[level];
1057 Size sz(linfo.width, linfo.height);
1058 Size wholeSize(sz.width + border*2, sz.height + border*2);
1059 Rect wholeLinfo = Rect(linfo.x - border, linfo.y - border, wholeSize.width, wholeSize.height);
1060 Mat extImg = imagePyramid(wholeLinfo), extMask;
1061 Mat currImg = extImg(Rect(border, border, sz.width, sz.height)), currMask;
1065 extMask = maskPyramid(wholeLinfo);
1066 currMask = extMask(Rect(border, border, sz.width, sz.height));
1069 // Compute the resized image
1070 if( level != firstLevel )
1072 resize(prevImg, currImg, sz, 0, 0, INTER_LINEAR_EXACT);
1075 resize(prevMask, currMask, sz, 0, 0, INTER_LINEAR_EXACT);
1076 if( level > firstLevel )
1077 threshold(currMask, currMask, 254, 0, THRESH_TOZERO);
1080 copyMakeBorder(currImg, extImg, border, border, border, border,
1081 BORDER_REFLECT_101+BORDER_ISOLATED);
1083 copyMakeBorder(currMask, extMask, border, border, border, border,
1084 BORDER_CONSTANT+BORDER_ISOLATED);
1088 copyMakeBorder(image, extImg, border, border, border, border,
1089 BORDER_REFLECT_101);
1091 copyMakeBorder(mask, extMask, border, border, border, border,
1092 BORDER_CONSTANT+BORDER_ISOLATED);
1094 if (level > firstLevel)
1097 prevMask = currMask;
1102 copyVectorToUMat(layerOfs, ulayerInfo);
1107 imagePyramid.copyTo(uimagePyramid);
1109 // Get keypoints, those will be far enough from the border that no check will be required for the descriptor
1110 computeKeyPoints(imagePyramid, uimagePyramid, maskPyramid,
1111 layerInfo, ulayerInfo, layerScale, keypoints,
1112 nfeatures, scaleFactor, edgeThreshold, patchSize, scoreType, useOCL, fastThreshold);
1116 KeyPointsFilter::runByImageBorder(keypoints, image.size(), edgeThreshold);
1118 if( !sortedByLevel )
1120 std::vector<std::vector<KeyPoint> > allKeypoints(nLevels);
1121 nkeypoints = (int)keypoints.size();
1122 for( i = 0; i < nkeypoints; i++ )
1124 level = keypoints[i].octave;
1125 CV_Assert(0 <= level);
1126 allKeypoints[level].push_back(keypoints[i]);
1129 for( level = 0; level < nLevels; level++ )
1130 std::copy(allKeypoints[level].begin(), allKeypoints[level].end(), std::back_inserter(keypoints));
1134 if( do_descriptors )
1136 int dsize = descriptorSize();
1138 nkeypoints = (int)keypoints.size();
1139 if( nkeypoints == 0 )
1141 _descriptors.release();
1145 _descriptors.create(nkeypoints, dsize, CV_8U);
1146 std::vector<Point> pattern;
1148 const int npoints = 512;
1149 Point patternbuf[npoints];
1150 const Point* pattern0 = (const Point*)bit_pattern_31_;
1152 if( patchSize != 31 )
1154 pattern0 = patternbuf;
1155 makeRandomPattern(patchSize, patternbuf, npoints);
1158 CV_Assert( wta_k == 2 || wta_k == 3 || wta_k == 4 );
1161 std::copy(pattern0, pattern0 + npoints, std::back_inserter(pattern));
1164 int ntuples = descriptorSize()*4;
1165 initializeOrbPattern(pattern0, pattern, ntuples, wta_k, npoints);
1168 for( level = 0; level < nLevels; level++ )
1170 // preprocess the resized image
1171 Mat workingMat = imagePyramid(layerInfo[level]);
1173 //boxFilter(working_mat, working_mat, working_mat.depth(), Size(5,5), Point(-1,-1), true, BORDER_REFLECT_101);
1174 GaussianBlur(workingMat, workingMat, Size(7, 7), 2, 2, BORDER_REFLECT_101);
1180 imagePyramid.copyTo(uimagePyramid);
1181 std::vector<Vec4i> kptbuf;
1182 UMat ukeypoints, upattern;
1183 copyVectorToUMat(pattern, upattern);
1184 uploadORBKeypoints(keypoints, layerScale, kptbuf, ukeypoints);
1186 UMat udescriptors = _descriptors.getUMat();
1187 useOCL = ocl_computeOrbDescriptors(uimagePyramid, ulayerInfo,
1188 ukeypoints, udescriptors, upattern,
1189 nkeypoints, dsize, wta_k);
1192 CV_IMPL_ADD(CV_IMPL_OCL);
1199 Mat descriptors = _descriptors.getMat();
1200 computeOrbDescriptors(imagePyramid, layerInfo, layerScale,
1201 keypoints, descriptors, pattern, dsize, wta_k);
1206 Ptr<ORB> ORB::create(int nfeatures, float scaleFactor, int nlevels, int edgeThreshold,
1207 int firstLevel, int wta_k, int scoreType, int patchSize, int fastThreshold)
1209 CV_Assert(firstLevel >= 0);
1210 return makePtr<ORB_Impl>(nfeatures, scaleFactor, nlevels, edgeThreshold,
1211 firstLevel, wta_k, scoreType, patchSize, fastThreshold);
1214 String ORB::getDefaultName() const
1216 return (Feature2D::getDefaultName() + ".ORB");