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);
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 : 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) { nfeatures = maxFeatures; }
665
int getMaxFeatures() const { return nfeatures; }
667
void setScaleFactor(double scaleFactor_) { scaleFactor = scaleFactor_; }
668
double getScaleFactor() const { return scaleFactor; }
670
void setNLevels(int nlevels_) { nlevels = nlevels_; }
671
int getNLevels() const { return nlevels; }
673
void setEdgeThreshold(int edgeThreshold_) { edgeThreshold = edgeThreshold_; }
674
int getEdgeThreshold() const { return edgeThreshold; }
676
void setFirstLevel(int firstLevel_) { firstLevel = firstLevel_; }
677
int getFirstLevel() const { return firstLevel; }
679
void setWTA_K(int wta_k_) { wta_k = wta_k_; }
680
int getWTA_K() const { return wta_k; }
682
void setScoreType(int scoreType_) { scoreType = scoreType_; }
683
int getScoreType() const { return scoreType; }
685
void setPatchSize(int patchSize_) { patchSize = patchSize_; }
686
int getPatchSize() const { return patchSize; }
688
void setFastThreshold(int fastThreshold_) { fastThreshold = fastThreshold_; }
689
int getFastThreshold() const { return fastThreshold; }
691
// returns the descriptor size in bytes
692
int descriptorSize() const;
693
// returns the descriptor type
694
int descriptorType() const;
695
// returns the default norm type
696
int defaultNorm() const;
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 );
715
int ORB_Impl::descriptorSize() const
720
int ORB_Impl::descriptorType() const
725
int ORB_Impl::defaultNorm() const
731
static void uploadORBKeypoints(const std::vector<KeyPoint>& src, std::vector<Vec3i>& buf, OutputArray dst)
733
size_t i, n = src.size();
734
buf.resize(std::max(buf.size(), n));
735
for( i = 0; i < n; i++ )
736
buf[i] = Vec3i(cvRound(src[i].pt.x), cvRound(src[i].pt.y), src[i].octave);
737
copyVectorToUMat(buf, dst);
747
static void uploadORBKeypoints(const std::vector<KeyPoint>& src,
748
const std::vector<float>& layerScale,
749
std::vector<Vec4i>& buf, OutputArray dst)
751
size_t i, n = src.size();
752
buf.resize(std::max(buf.size(), n));
753
for( i = 0; i < n; i++ )
755
int z = src[i].octave;
756
float scale = 1.f/layerScale[z];
758
angle.f = src[i].angle;
759
buf[i] = Vec4i(cvRound(src[i].pt.x*scale), cvRound(src[i].pt.y*scale), z, angle.i);
761
copyVectorToUMat(buf, dst);
765
/** Compute the ORB_Impl keypoints on an image
766
* @param image_pyramid the image pyramid to compute the features and descriptors on
767
* @param mask_pyramid the masks to apply at every level
768
* @param keypoints the resulting keypoints, clustered per level
770
static void computeKeyPoints(const Mat& imagePyramid,
771
const UMat& uimagePyramid,
772
const Mat& maskPyramid,
773
const std::vector<Rect>& layerInfo,
774
const UMat& ulayerInfo,
775
const std::vector<float>& layerScale,
776
std::vector<KeyPoint>& allKeypoints,
777
int nfeatures, double scaleFactor,
778
int edgeThreshold, int patchSize, int scoreType,
779
bool useOCL, int fastThreshold )
782
(void)uimagePyramid;(void)ulayerInfo;(void)useOCL;
785
int i, nkeypoints, level, nlevels = (int)layerInfo.size();
786
std::vector<int> nfeaturesPerLevel(nlevels);
788
// fill the extractors and descriptors for the corresponding scales
789
float factor = (float)(1.0 / scaleFactor);
790
float ndesiredFeaturesPerScale = nfeatures*(1 - factor)/(1 - (float)std::pow((double)factor, (double)nlevels));
793
for( level = 0; level < nlevels-1; level++ )
795
nfeaturesPerLevel[level] = cvRound(ndesiredFeaturesPerScale);
796
sumFeatures += nfeaturesPerLevel[level];
797
ndesiredFeaturesPerScale *= factor;
799
nfeaturesPerLevel[nlevels-1] = std::max(nfeatures - sumFeatures, 0);
801
// Make sure we forget about what is too close to the boundary
802
//edge_threshold_ = std::max(edge_threshold_, patch_size_/2 + kKernelWidth / 2 + 2);
804
// pre-compute the end of a row in a circular patch
805
int halfPatchSize = patchSize / 2;
806
std::vector<int> umax(halfPatchSize + 2);
808
int v, v0, vmax = cvFloor(halfPatchSize * std::sqrt(2.f) / 2 + 1);
809
int vmin = cvCeil(halfPatchSize * std::sqrt(2.f) / 2);
810
for (v = 0; v <= vmax; ++v)
811
umax[v] = cvRound(std::sqrt((double)halfPatchSize * halfPatchSize - v * v));
813
// Make sure we are symmetric
814
for (v = halfPatchSize, v0 = 0; v >= vmin; --v)
816
while (umax[v0] == umax[v0 + 1])
822
allKeypoints.clear();
823
std::vector<KeyPoint> keypoints;
824
std::vector<int> counters(nlevels);
825
keypoints.reserve(nfeaturesPerLevel[0]*2);
827
for( level = 0; level < nlevels; level++ )
829
int featuresNum = nfeaturesPerLevel[level];
830
Mat img = imagePyramid(layerInfo[level]);
831
Mat mask = maskPyramid.empty() ? Mat() : maskPyramid(layerInfo[level]);
833
// Detect FAST features, 20 is a good threshold
835
Ptr<FastFeatureDetector> fd = FastFeatureDetector::create(fastThreshold, true);
836
fd->detect(img, keypoints, mask);
839
// Remove keypoints very close to the border
840
KeyPointsFilter::runByImageBorder(keypoints, img.size(), edgeThreshold);
842
// Keep more points than necessary as FAST does not give amazing corners
843
KeyPointsFilter::retainBest(keypoints, scoreType == ORB_Impl::HARRIS_SCORE ? 2 * featuresNum : featuresNum);
845
nkeypoints = (int)keypoints.size();
846
counters[level] = nkeypoints;
848
float sf = layerScale[level];
849
for( i = 0; i < nkeypoints; i++ )
851
keypoints[i].octave = level;
852
keypoints[i].size = patchSize*sf;
855
std::copy(keypoints.begin(), keypoints.end(), std::back_inserter(allKeypoints));
858
std::vector<Vec3i> ukeypoints_buf;
860
nkeypoints = (int)allKeypoints.size();
866
UMat ukeypoints, uresponses(1, nkeypoints, CV_32F);
868
// Select best features using the Harris cornerness (better scoring than FAST)
869
if( scoreType == ORB_Impl::HARRIS_SCORE )
874
uploadORBKeypoints(allKeypoints, ukeypoints_buf, ukeypoints);
875
useOCL = ocl_HarrisResponses( uimagePyramid, ulayerInfo, ukeypoints,
876
uresponses, nkeypoints, 7, HARRIS_K );
879
CV_IMPL_ADD(CV_IMPL_OCL);
880
uresponses.copyTo(responses);
881
for( i = 0; i < nkeypoints; i++ )
882
allKeypoints[i].response = responses.at<float>(i);
888
HarrisResponses(imagePyramid, layerInfo, allKeypoints, 7, HARRIS_K);
890
std::vector<KeyPoint> newAllKeypoints;
891
newAllKeypoints.reserve(nfeaturesPerLevel[0]*nlevels);
894
for( level = 0; level < nlevels; level++ )
896
int featuresNum = nfeaturesPerLevel[level];
897
nkeypoints = counters[level];
898
keypoints.resize(nkeypoints);
899
std::copy(allKeypoints.begin() + offset,
900
allKeypoints.begin() + offset + nkeypoints,
902
offset += nkeypoints;
904
//cull to the final desired level, using the new Harris scores.
905
KeyPointsFilter::retainBest(keypoints, featuresNum);
907
std::copy(keypoints.begin(), keypoints.end(), std::back_inserter(newAllKeypoints));
909
std::swap(allKeypoints, newAllKeypoints);
912
nkeypoints = (int)allKeypoints.size();
919
copyVectorToUMat(umax, uumax);
921
uploadORBKeypoints(allKeypoints, ukeypoints_buf, ukeypoints);
922
useOCL = ocl_ICAngles(uimagePyramid, ulayerInfo, ukeypoints, uresponses, uumax,
923
nkeypoints, halfPatchSize);
927
CV_IMPL_ADD(CV_IMPL_OCL);
928
uresponses.copyTo(responses);
929
for( i = 0; i < nkeypoints; i++ )
930
allKeypoints[i].angle = responses.at<float>(i);
937
ICAngles(imagePyramid, layerInfo, allKeypoints, umax, halfPatchSize);
940
for( i = 0; i < nkeypoints; i++ )
942
float scale = layerScale[allKeypoints[i].octave];
943
allKeypoints[i].pt *= scale;
948
/** Compute the ORB_Impl features and descriptors on an image
949
* @param img the image to compute the features and descriptors on
950
* @param mask the mask to apply
951
* @param keypoints the resulting keypoints
952
* @param descriptors the resulting descriptors
953
* @param do_keypoints if true, the keypoints are computed, otherwise used as an input
954
* @param do_descriptors if true, also computes the descriptors
956
void ORB_Impl::detectAndCompute( InputArray _image, InputArray _mask,
957
std::vector<KeyPoint>& keypoints,
958
OutputArray _descriptors, bool useProvidedKeypoints )
960
CV_Assert(patchSize >= 2);
962
bool do_keypoints = !useProvidedKeypoints;
963
bool do_descriptors = _descriptors.needed();
965
if( (!do_keypoints && !do_descriptors) || _image.empty() )
969
const int HARRIS_BLOCK_SIZE = 9;
970
int halfPatchSize = patchSize / 2;
971
int border = std::max(edgeThreshold, std::max(halfPatchSize, HARRIS_BLOCK_SIZE/2))+1;
973
bool useOCL = ocl::useOpenCL();
975
Mat image = _image.getMat(), mask = _mask.getMat();
976
if( image.type() != CV_8UC1 )
977
cvtColor(_image, image, COLOR_BGR2GRAY);
979
int i, level, nLevels = this->nlevels, nkeypoints = (int)keypoints.size();
980
bool sortedByLevel = true;
984
// if we have pre-computed keypoints, they may use more levels than it is set in parameters
985
// !!!TODO!!! implement more correct method, independent from the used keypoint detector.
986
// Namely, the detector should provide correct size of each keypoint. Based on the keypoint size
987
// and the algorithm used (i.e. BRIEF, running on 31x31 patches) we should compute the approximate
988
// scale-factor that we need to apply. Then we should cluster all the computed scale-factors and
989
// for each cluster compute the corresponding image.
991
// In short, ultimately the descriptor should
992
// ignore octave parameter and deal only with the keypoint size.
994
for( i = 0; i < nkeypoints; i++ )
996
level = keypoints[i].octave;
997
CV_Assert(level >= 0);
998
if( i > 0 && level < keypoints[i-1].octave )
999
sortedByLevel = false;
1000
nLevels = std::max(nLevels, level);
1005
std::vector<Rect> layerInfo(nLevels);
1006
std::vector<int> layerOfs(nLevels);
1007
std::vector<float> layerScale(nLevels);
1008
Mat imagePyramid, maskPyramid;
1009
UMat uimagePyramid, ulayerInfo;
1011
int level_dy = image.rows + border*2;
1012
Point level_ofs(0,0);
1013
Size bufSize((image.cols + border*2 + 15) & -16, 0);
1015
for( level = 0; level < nLevels; level++ )
1017
float scale = getScale(level, firstLevel, scaleFactor);
1018
layerScale[level] = scale;
1019
Size sz(cvRound(image.cols/scale), cvRound(image.rows/scale));
1020
Size wholeSize(sz.width + border*2, sz.height + border*2);
1021
if( level_ofs.x + wholeSize.width > bufSize.width )
1023
level_ofs = Point(0, level_ofs.y + level_dy);
1024
level_dy = wholeSize.height;
1027
Rect linfo(level_ofs.x + border, level_ofs.y + border, sz.width, sz.height);
1028
layerInfo[level] = linfo;
1029
layerOfs[level] = linfo.y*bufSize.width + linfo.x;
1030
level_ofs.x += wholeSize.width;
1032
bufSize.height = level_ofs.y + level_dy;
1034
imagePyramid.create(bufSize, CV_8U);
1036
maskPyramid.create(bufSize, CV_8U);
1038
Mat prevImg = image, prevMask = mask;
1040
// Pre-compute the scale pyramids
1041
for (level = 0; level < nLevels; ++level)
1043
Rect linfo = layerInfo[level];
1044
Size sz(linfo.width, linfo.height);
1045
Size wholeSize(sz.width + border*2, sz.height + border*2);
1046
Rect wholeLinfo = Rect(linfo.x - border, linfo.y - border, wholeSize.width, wholeSize.height);
1047
Mat extImg = imagePyramid(wholeLinfo), extMask;
1048
Mat currImg = extImg(Rect(border, border, sz.width, sz.height)), currMask;
1052
extMask = maskPyramid(wholeLinfo);
1053
currMask = extMask(Rect(border, border, sz.width, sz.height));
1056
// Compute the resized image
1057
if( level != firstLevel )
1059
resize(prevImg, currImg, sz, 0, 0, INTER_LINEAR);
1062
resize(prevMask, currMask, sz, 0, 0, INTER_LINEAR);
1063
if( level > firstLevel )
1064
threshold(currMask, currMask, 254, 0, THRESH_TOZERO);
1067
copyMakeBorder(currImg, extImg, border, border, border, border,
1068
BORDER_REFLECT_101+BORDER_ISOLATED);
1070
copyMakeBorder(currMask, extMask, border, border, border, border,
1071
BORDER_CONSTANT+BORDER_ISOLATED);
1075
copyMakeBorder(image, extImg, border, border, border, border,
1076
BORDER_REFLECT_101);
1078
copyMakeBorder(mask, extMask, border, border, border, border,
1079
BORDER_CONSTANT+BORDER_ISOLATED);
1082
prevMask = currMask;
1086
copyVectorToUMat(layerOfs, ulayerInfo);
1091
imagePyramid.copyTo(uimagePyramid);
1093
// Get keypoints, those will be far enough from the border that no check will be required for the descriptor
1094
computeKeyPoints(imagePyramid, uimagePyramid, maskPyramid,
1095
layerInfo, ulayerInfo, layerScale, keypoints,
1096
nfeatures, scaleFactor, edgeThreshold, patchSize, scoreType, useOCL, fastThreshold);
1100
KeyPointsFilter::runByImageBorder(keypoints, image.size(), edgeThreshold);
1102
if( !sortedByLevel )
1104
std::vector<std::vector<KeyPoint> > allKeypoints(nLevels);
1105
nkeypoints = (int)keypoints.size();
1106
for( i = 0; i < nkeypoints; i++ )
1108
level = keypoints[i].octave;
1109
CV_Assert(0 <= level);
1110
allKeypoints[level].push_back(keypoints[i]);
1113
for( level = 0; level < nLevels; level++ )
1114
std::copy(allKeypoints[level].begin(), allKeypoints[level].end(), std::back_inserter(keypoints));
1118
if( do_descriptors )
1120
int dsize = descriptorSize();
1122
nkeypoints = (int)keypoints.size();
1123
if( nkeypoints == 0 )
1125
_descriptors.release();
1129
_descriptors.create(nkeypoints, dsize, CV_8U);
1130
std::vector<Point> pattern;
1132
const int npoints = 512;
1133
Point patternbuf[npoints];
1134
const Point* pattern0 = (const Point*)bit_pattern_31_;
1136
if( patchSize != 31 )
1138
pattern0 = patternbuf;
1139
makeRandomPattern(patchSize, patternbuf, npoints);
1142
CV_Assert( wta_k == 2 || wta_k == 3 || wta_k == 4 );
1145
std::copy(pattern0, pattern0 + npoints, std::back_inserter(pattern));
1148
int ntuples = descriptorSize()*4;
1149
initializeOrbPattern(pattern0, pattern, ntuples, wta_k, npoints);
1152
for( level = 0; level < nLevels; level++ )
1154
// preprocess the resized image
1155
Mat workingMat = imagePyramid(layerInfo[level]);
1157
//boxFilter(working_mat, working_mat, working_mat.depth(), Size(5,5), Point(-1,-1), true, BORDER_REFLECT_101);
1158
GaussianBlur(workingMat, workingMat, Size(7, 7), 2, 2, BORDER_REFLECT_101);
1164
imagePyramid.copyTo(uimagePyramid);
1165
std::vector<Vec4i> kptbuf;
1166
UMat ukeypoints, upattern;
1167
copyVectorToUMat(pattern, upattern);
1168
uploadORBKeypoints(keypoints, layerScale, kptbuf, ukeypoints);
1170
UMat udescriptors = _descriptors.getUMat();
1171
useOCL = ocl_computeOrbDescriptors(uimagePyramid, ulayerInfo,
1172
ukeypoints, udescriptors, upattern,
1173
nkeypoints, dsize, wta_k);
1176
CV_IMPL_ADD(CV_IMPL_OCL);
1183
Mat descriptors = _descriptors.getMat();
1184
computeOrbDescriptors(imagePyramid, layerInfo, layerScale,
1185
keypoints, descriptors, pattern, dsize, wta_k);
1190
Ptr<ORB> ORB::create(int nfeatures, float scaleFactor, int nlevels, int edgeThreshold,
1191
int firstLevel, int wta_k, int scoreType, int patchSize, int fastThreshold)
1193
return makePtr<ORB_Impl>(nfeatures, scaleFactor, nlevels, edgeThreshold,
1194
firstLevel, wta_k, scoreType, patchSize, fastThreshold);