Home | History | Annotate | Download | only in src
      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 
     35 /** Authors: Ethan Rublee, Vincent Rabaud, Gary Bradski */
     36 
     37 #include "precomp.hpp"
     38 #include "opencl_kernels_features2d.hpp"
     39 #include <iterator>
     40 
     41 #ifndef CV_IMPL_ADD
     42 #define CV_IMPL_ADD(x)
     43 #endif
     44 
     45 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     46 
     47 namespace cv
     48 {
     49 
     50 const float HARRIS_K = 0.04f;
     51 
     52 template<typename _Tp> inline void copyVectorToUMat(const std::vector<_Tp>& v, OutputArray um)
     53 {
     54     if(v.empty())
     55         um.release();
     56     else
     57         Mat(1, (int)(v.size()*sizeof(v[0])), CV_8U, (void*)&v[0]).copyTo(um);
     58 }
     59 
     60 static bool
     61 ocl_HarrisResponses(const UMat& imgbuf,
     62                     const UMat& layerinfo,
     63                     const UMat& keypoints,
     64                     UMat& responses,
     65                     int nkeypoints, int blockSize, float harris_k)
     66 {
     67     size_t globalSize[] = {nkeypoints};
     68 
     69     float scale = 1.f/((1 << 2) * blockSize * 255.f);
     70     float scale_sq_sq = scale * scale * scale * scale;
     71 
     72     ocl::Kernel hr_ker("ORB_HarrisResponses", ocl::features2d::orb_oclsrc,
     73                 format("-D ORB_RESPONSES -D blockSize=%d -D scale_sq_sq=%.12ef -D HARRIS_K=%.12ff", blockSize, scale_sq_sq, harris_k));
     74     if( hr_ker.empty() )
     75         return false;
     76 
     77     return hr_ker.args(ocl::KernelArg::ReadOnlyNoSize(imgbuf),
     78                 ocl::KernelArg::PtrReadOnly(layerinfo),
     79                 ocl::KernelArg::PtrReadOnly(keypoints),
     80                 ocl::KernelArg::PtrWriteOnly(responses),
     81                 nkeypoints).run(1, globalSize, 0, true);
     82 }
     83 
     84 static bool
     85 ocl_ICAngles(const UMat& imgbuf, const UMat& layerinfo,
     86              const UMat& keypoints, UMat& responses,
     87              const UMat& umax, int nkeypoints, int half_k)
     88 {
     89     size_t globalSize[] = {nkeypoints};
     90 
     91     ocl::Kernel icangle_ker("ORB_ICAngle", ocl::features2d::orb_oclsrc, "-D ORB_ANGLES");
     92     if( icangle_ker.empty() )
     93         return false;
     94 
     95     return icangle_ker.args(ocl::KernelArg::ReadOnlyNoSize(imgbuf),
     96                 ocl::KernelArg::PtrReadOnly(layerinfo),
     97                 ocl::KernelArg::PtrReadOnly(keypoints),
     98                 ocl::KernelArg::PtrWriteOnly(responses),
     99                 ocl::KernelArg::PtrReadOnly(umax),
    100                 nkeypoints, half_k).run(1, globalSize, 0, true);
    101 }
    102 
    103 
    104 static bool
    105 ocl_computeOrbDescriptors(const UMat& imgbuf, const UMat& layerInfo,
    106                           const UMat& keypoints, UMat& desc, const UMat& pattern,
    107                           int nkeypoints, int dsize, int wta_k)
    108 {
    109     size_t globalSize[] = {nkeypoints};
    110 
    111     ocl::Kernel desc_ker("ORB_computeDescriptor", ocl::features2d::orb_oclsrc,
    112                          format("-D ORB_DESCRIPTORS -D WTA_K=%d", wta_k));
    113     if( desc_ker.empty() )
    114         return false;
    115 
    116     return desc_ker.args(ocl::KernelArg::ReadOnlyNoSize(imgbuf),
    117                          ocl::KernelArg::PtrReadOnly(layerInfo),
    118                          ocl::KernelArg::PtrReadOnly(keypoints),
    119                          ocl::KernelArg::PtrWriteOnly(desc),
    120                          ocl::KernelArg::PtrReadOnly(pattern),
    121                          nkeypoints, dsize).run(1, globalSize, 0, true);
    122 }
    123 
    124 
    125 /**
    126  * Function that computes the Harris responses in a
    127  * blockSize x blockSize patch at given points in the image
    128  */
    129 static void
    130 HarrisResponses(const Mat& img, const std::vector<Rect>& layerinfo,
    131                 std::vector<KeyPoint>& pts, int blockSize, float harris_k)
    132 {
    133     CV_Assert( img.type() == CV_8UC1 && blockSize*blockSize <= 2048 );
    134 
    135     size_t ptidx, ptsize = pts.size();
    136 
    137     const uchar* ptr00 = img.ptr<uchar>();
    138     int step = (int)(img.step/img.elemSize1());
    139     int r = blockSize/2;
    140 
    141     float scale = 1.f/((1 << 2) * blockSize * 255.f);
    142     float scale_sq_sq = scale * scale * scale * scale;
    143 
    144     AutoBuffer<int> ofsbuf(blockSize*blockSize);
    145     int* ofs = ofsbuf;
    146     for( int i = 0; i < blockSize; i++ )
    147         for( int j = 0; j < blockSize; j++ )
    148             ofs[i*blockSize + j] = (int)(i*step + j);
    149 
    150     for( ptidx = 0; ptidx < ptsize; ptidx++ )
    151     {
    152         int x0 = cvRound(pts[ptidx].pt.x);
    153         int y0 = cvRound(pts[ptidx].pt.y);
    154         int z = pts[ptidx].octave;
    155 
    156         const uchar* ptr0 = ptr00 + (y0 - r + layerinfo[z].y)*step + x0 - r + layerinfo[z].x;
    157         int a = 0, b = 0, c = 0;
    158 
    159         for( int k = 0; k < blockSize*blockSize; k++ )
    160         {
    161             const uchar* ptr = ptr0 + ofs[k];
    162             int Ix = (ptr[1] - ptr[-1])*2 + (ptr[-step+1] - ptr[-step-1]) + (ptr[step+1] - ptr[step-1]);
    163             int Iy = (ptr[step] - ptr[-step])*2 + (ptr[step-1] - ptr[-step-1]) + (ptr[step+1] - ptr[-step+1]);
    164             a += Ix*Ix;
    165             b += Iy*Iy;
    166             c += Ix*Iy;
    167         }
    168         pts[ptidx].response = ((float)a * b - (float)c * c -
    169                                harris_k * ((float)a + b) * ((float)a + b))*scale_sq_sq;
    170     }
    171 }
    172 
    173 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    174 
    175 static void ICAngles(const Mat& img, const std::vector<Rect>& layerinfo,
    176                      std::vector<KeyPoint>& pts, const std::vector<int> & u_max, int half_k)
    177 {
    178     int step = (int)img.step1();
    179     size_t ptidx, ptsize = pts.size();
    180 
    181     for( ptidx = 0; ptidx < ptsize; ptidx++ )
    182     {
    183         const Rect& layer = layerinfo[pts[ptidx].octave];
    184         const uchar* center = &img.at<uchar>(cvRound(pts[ptidx].pt.y) + layer.y, cvRound(pts[ptidx].pt.x) + layer.x);
    185 
    186         int m_01 = 0, m_10 = 0;
    187 
    188         // Treat the center line differently, v=0
    189         for (int u = -half_k; u <= half_k; ++u)
    190             m_10 += u * center[u];
    191 
    192         // Go line by line in the circular patch
    193         for (int v = 1; v <= half_k; ++v)
    194         {
    195             // Proceed over the two lines
    196             int v_sum = 0;
    197             int d = u_max[v];
    198             for (int u = -d; u <= d; ++u)
    199             {
    200                 int val_plus = center[u + v*step], val_minus = center[u - v*step];
    201                 v_sum += (val_plus - val_minus);
    202                 m_10 += u * (val_plus + val_minus);
    203             }
    204             m_01 += v * v_sum;
    205         }
    206 
    207         pts[ptidx].angle = fastAtan2((float)m_01, (float)m_10);
    208     }
    209 }
    210 
    211 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    212 
    213 static void
    214 computeOrbDescriptors( const Mat& imagePyramid, const std::vector<Rect>& layerInfo,
    215                        const std::vector<float>& layerScale, std::vector<KeyPoint>& keypoints,
    216                        Mat& descriptors, const std::vector<Point>& _pattern, int dsize, int wta_k )
    217 {
    218     int step = (int)imagePyramid.step;
    219     int j, i, nkeypoints = (int)keypoints.size();
    220 
    221     for( j = 0; j < nkeypoints; j++ )
    222     {
    223         const KeyPoint& kpt = keypoints[j];
    224         const Rect& layer = layerInfo[kpt.octave];
    225         float scale = 1.f/layerScale[kpt.octave];
    226         float angle = kpt.angle;
    227 
    228         angle *= (float)(CV_PI/180.f);
    229         float a = (float)cos(angle), b = (float)sin(angle);
    230 
    231         const uchar* center = &imagePyramid.at<uchar>(cvRound(kpt.pt.y*scale) + layer.y,
    232                                                       cvRound(kpt.pt.x*scale) + layer.x);
    233         float x, y;
    234         int ix, iy;
    235         const Point* pattern = &_pattern[0];
    236         uchar* desc = descriptors.ptr<uchar>(j);
    237 
    238     #if 1
    239         #define GET_VALUE(idx) \
    240                (x = pattern[idx].x*a - pattern[idx].y*b, \
    241                 y = pattern[idx].x*b + pattern[idx].y*a, \
    242                 ix = cvRound(x), \
    243                 iy = cvRound(y), \
    244                 *(center + iy*step + ix) )
    245     #else
    246         #define GET_VALUE(idx) \
    247             (x = pattern[idx].x*a - pattern[idx].y*b, \
    248             y = pattern[idx].x*b + pattern[idx].y*a, \
    249             ix = cvFloor(x), iy = cvFloor(y), \
    250             x -= ix, y -= iy, \
    251             cvRound(center[iy*step + ix]*(1-x)*(1-y) + center[(iy+1)*step + ix]*(1-x)*y + \
    252                     center[iy*step + ix+1]*x*(1-y) + center[(iy+1)*step + ix+1]*x*y))
    253     #endif
    254 
    255         if( wta_k == 2 )
    256         {
    257             for (i = 0; i < dsize; ++i, pattern += 16)
    258             {
    259                 int t0, t1, val;
    260                 t0 = GET_VALUE(0); t1 = GET_VALUE(1);
    261                 val = t0 < t1;
    262                 t0 = GET_VALUE(2); t1 = GET_VALUE(3);
    263                 val |= (t0 < t1) << 1;
    264                 t0 = GET_VALUE(4); t1 = GET_VALUE(5);
    265                 val |= (t0 < t1) << 2;
    266                 t0 = GET_VALUE(6); t1 = GET_VALUE(7);
    267                 val |= (t0 < t1) << 3;
    268                 t0 = GET_VALUE(8); t1 = GET_VALUE(9);
    269                 val |= (t0 < t1) << 4;
    270                 t0 = GET_VALUE(10); t1 = GET_VALUE(11);
    271                 val |= (t0 < t1) << 5;
    272                 t0 = GET_VALUE(12); t1 = GET_VALUE(13);
    273                 val |= (t0 < t1) << 6;
    274                 t0 = GET_VALUE(14); t1 = GET_VALUE(15);
    275                 val |= (t0 < t1) << 7;
    276 
    277                 desc[i] = (uchar)val;
    278             }
    279         }
    280         else if( wta_k == 3 )
    281         {
    282             for (i = 0; i < dsize; ++i, pattern += 12)
    283             {
    284                 int t0, t1, t2, val;
    285                 t0 = GET_VALUE(0); t1 = GET_VALUE(1); t2 = GET_VALUE(2);
    286                 val = t2 > t1 ? (t2 > t0 ? 2 : 0) : (t1 > t0);
    287 
    288                 t0 = GET_VALUE(3); t1 = GET_VALUE(4); t2 = GET_VALUE(5);
    289                 val |= (t2 > t1 ? (t2 > t0 ? 2 : 0) : (t1 > t0)) << 2;
    290 
    291                 t0 = GET_VALUE(6); t1 = GET_VALUE(7); t2 = GET_VALUE(8);
    292                 val |= (t2 > t1 ? (t2 > t0 ? 2 : 0) : (t1 > t0)) << 4;
    293 
    294                 t0 = GET_VALUE(9); t1 = GET_VALUE(10); t2 = GET_VALUE(11);
    295                 val |= (t2 > t1 ? (t2 > t0 ? 2 : 0) : (t1 > t0)) << 6;
    296 
    297                 desc[i] = (uchar)val;
    298             }
    299         }
    300         else if( wta_k == 4 )
    301         {
    302             for (i = 0; i < dsize; ++i, pattern += 16)
    303             {
    304                 int t0, t1, t2, t3, u, v, k, val;
    305                 t0 = GET_VALUE(0); t1 = GET_VALUE(1);
    306                 t2 = GET_VALUE(2); t3 = GET_VALUE(3);
    307                 u = 0, v = 2;
    308                 if( t1 > t0 ) t0 = t1, u = 1;
    309                 if( t3 > t2 ) t2 = t3, v = 3;
    310                 k = t0 > t2 ? u : v;
    311                 val = k;
    312 
    313                 t0 = GET_VALUE(4); t1 = GET_VALUE(5);
    314                 t2 = GET_VALUE(6); t3 = GET_VALUE(7);
    315                 u = 0, v = 2;
    316                 if( t1 > t0 ) t0 = t1, u = 1;
    317                 if( t3 > t2 ) t2 = t3, v = 3;
    318                 k = t0 > t2 ? u : v;
    319                 val |= k << 2;
    320 
    321                 t0 = GET_VALUE(8); t1 = GET_VALUE(9);
    322                 t2 = GET_VALUE(10); t3 = GET_VALUE(11);
    323                 u = 0, v = 2;
    324                 if( t1 > t0 ) t0 = t1, u = 1;
    325                 if( t3 > t2 ) t2 = t3, v = 3;
    326                 k = t0 > t2 ? u : v;
    327                 val |= k << 4;
    328 
    329                 t0 = GET_VALUE(12); t1 = GET_VALUE(13);
    330                 t2 = GET_VALUE(14); t3 = GET_VALUE(15);
    331                 u = 0, v = 2;
    332                 if( t1 > t0 ) t0 = t1, u = 1;
    333                 if( t3 > t2 ) t2 = t3, v = 3;
    334                 k = t0 > t2 ? u : v;
    335                 val |= k << 6;
    336 
    337                 desc[i] = (uchar)val;
    338             }
    339         }
    340         else
    341             CV_Error( Error::StsBadSize, "Wrong wta_k. It can be only 2, 3 or 4." );
    342         #undef GET_VALUE
    343     }
    344 }
    345 
    346 
    347 static void initializeOrbPattern( const Point* pattern0, std::vector<Point>& pattern, int ntuples, int tupleSize, int poolSize )
    348 {
    349     RNG rng(0x12345678);
    350     int i, k, k1;
    351     pattern.resize(ntuples*tupleSize);
    352 
    353     for( i = 0; i < ntuples; i++ )
    354     {
    355         for( k = 0; k < tupleSize; k++ )
    356         {
    357             for(;;)
    358             {
    359                 int idx = rng.uniform(0, poolSize);
    360                 Point pt = pattern0[idx];
    361                 for( k1 = 0; k1 < k; k1++ )
    362                     if( pattern[tupleSize*i + k1] == pt )
    363                         break;
    364                 if( k1 == k )
    365                 {
    366                     pattern[tupleSize*i + k] = pt;
    367                     break;
    368                 }
    369             }
    370         }
    371     }
    372 }
    373 
    374 static int bit_pattern_31_[256*4] =
    375 {
    376     8,-3, 9,5/*mean (0), correlation (0)*/,
    377     4,2, 7,-12/*mean (1.12461e-05), correlation (0.0437584)*/,
    378     -11,9, -8,2/*mean (3.37382e-05), correlation (0.0617409)*/,
    379     7,-12, 12,-13/*mean (5.62303e-05), correlation (0.0636977)*/,
    380     2,-13, 2,12/*mean (0.000134953), correlation (0.085099)*/,
    381     1,-7, 1,6/*mean (0.000528565), correlation (0.0857175)*/,
    382     -2,-10, -2,-4/*mean (0.0188821), correlation (0.0985774)*/,
    383     -13,-13, -11,-8/*mean (0.0363135), correlation (0.0899616)*/,
    384     -13,-3, -12,-9/*mean (0.121806), correlation (0.099849)*/,
    385     10,4, 11,9/*mean (0.122065), correlation (0.093285)*/,
    386     -13,-8, -8,-9/*mean (0.162787), correlation (0.0942748)*/,
    387     -11,7, -9,12/*mean (0.21561), correlation (0.0974438)*/,
    388     7,7, 12,6/*mean (0.160583), correlation (0.130064)*/,
    389     -4,-5, -3,0/*mean (0.228171), correlation (0.132998)*/,
    390     -13,2, -12,-3/*mean (0.00997526), correlation (0.145926)*/,
    391     -9,0, -7,5/*mean (0.198234), correlation (0.143636)*/,
    392     12,-6, 12,-1/*mean (0.0676226), correlation (0.16689)*/,
    393     -3,6, -2,12/*mean (0.166847), correlation (0.171682)*/,
    394     -6,-13, -4,-8/*mean (0.101215), correlation (0.179716)*/,
    395     11,-13, 12,-8/*mean (0.200641), correlation (0.192279)*/,
    396     4,7, 5,1/*mean (0.205106), correlation (0.186848)*/,
    397     5,-3, 10,-3/*mean (0.234908), correlation (0.192319)*/,
    398     3,-7, 6,12/*mean (0.0709964), correlation (0.210872)*/,
    399     -8,-7, -6,-2/*mean (0.0939834), correlation (0.212589)*/,
    400     -2,11, -1,-10/*mean (0.127778), correlation (0.20866)*/,
    401     -13,12, -8,10/*mean (0.14783), correlation (0.206356)*/,
    402     -7,3, -5,-3/*mean (0.182141), correlation (0.198942)*/,
    403     -4,2, -3,7/*mean (0.188237), correlation (0.21384)*/,
    404     -10,-12, -6,11/*mean (0.14865), correlation (0.23571)*/,
    405     5,-12, 6,-7/*mean (0.222312), correlation (0.23324)*/,
    406     5,-6, 7,-1/*mean (0.229082), correlation (0.23389)*/,
    407     1,0, 4,-5/*mean (0.241577), correlation (0.215286)*/,
    408     9,11, 11,-13/*mean (0.00338507), correlation (0.251373)*/,
    409     4,7, 4,12/*mean (0.131005), correlation (0.257622)*/,
    410     2,-1, 4,4/*mean (0.152755), correlation (0.255205)*/,
    411     -4,-12, -2,7/*mean (0.182771), correlation (0.244867)*/,
    412     -8,-5, -7,-10/*mean (0.186898), correlation (0.23901)*/,
    413     4,11, 9,12/*mean (0.226226), correlation (0.258255)*/,
    414     0,-8, 1,-13/*mean (0.0897886), correlation (0.274827)*/,
    415     -13,-2, -8,2/*mean (0.148774), correlation (0.28065)*/,
    416     -3,-2, -2,3/*mean (0.153048), correlation (0.283063)*/,
    417     -6,9, -4,-9/*mean (0.169523), correlation (0.278248)*/,
    418     8,12, 10,7/*mean (0.225337), correlation (0.282851)*/,
    419     0,9, 1,3/*mean (0.226687), correlation (0.278734)*/,
    420     7,-5, 11,-10/*mean (0.00693882), correlation (0.305161)*/,
    421     -13,-6, -11,0/*mean (0.0227283), correlation (0.300181)*/,
    422     10,7, 12,1/*mean (0.125517), correlation (0.31089)*/,
    423     -6,-3, -6,12/*mean (0.131748), correlation (0.312779)*/,
    424     10,-9, 12,-4/*mean (0.144827), correlation (0.292797)*/,
    425     -13,8, -8,-12/*mean (0.149202), correlation (0.308918)*/,
    426     -13,0, -8,-4/*mean (0.160909), correlation (0.310013)*/,
    427     3,3, 7,8/*mean (0.177755), correlation (0.309394)*/,
    428     5,7, 10,-7/*mean (0.212337), correlation (0.310315)*/,
    429     -1,7, 1,-12/*mean (0.214429), correlation (0.311933)*/,
    430     3,-10, 5,6/*mean (0.235807), correlation (0.313104)*/,
    431     2,-4, 3,-10/*mean (0.00494827), correlation (0.344948)*/,
    432     -13,0, -13,5/*mean (0.0549145), correlation (0.344675)*/,
    433     -13,-7, -12,12/*mean (0.103385), correlation (0.342715)*/,
    434     -13,3, -11,8/*mean (0.134222), correlation (0.322922)*/,
    435     -7,12, -4,7/*mean (0.153284), correlation (0.337061)*/,
    436     6,-10, 12,8/*mean (0.154881), correlation (0.329257)*/,
    437     -9,-1, -7,-6/*mean (0.200967), correlation (0.33312)*/,
    438     -2,-5, 0,12/*mean (0.201518), correlation (0.340635)*/,
    439     -12,5, -7,5/*mean (0.207805), correlation (0.335631)*/,
    440     3,-10, 8,-13/*mean (0.224438), correlation (0.34504)*/,
    441     -7,-7, -4,5/*mean (0.239361), correlation (0.338053)*/,
    442     -3,-2, -1,-7/*mean (0.240744), correlation (0.344322)*/,
    443     2,9, 5,-11/*mean (0.242949), correlation (0.34145)*/,
    444     -11,-13, -5,-13/*mean (0.244028), correlation (0.336861)*/,
    445     -1,6, 0,-1/*mean (0.247571), correlation (0.343684)*/,
    446     5,-3, 5,2/*mean (0.000697256), correlation (0.357265)*/,
    447     -4,-13, -4,12/*mean (0.00213675), correlation (0.373827)*/,
    448     -9,-6, -9,6/*mean (0.0126856), correlation (0.373938)*/,
    449     -12,-10, -8,-4/*mean (0.0152497), correlation (0.364237)*/,
    450     10,2, 12,-3/*mean (0.0299933), correlation (0.345292)*/,
    451     7,12, 12,12/*mean (0.0307242), correlation (0.366299)*/,
    452     -7,-13, -6,5/*mean (0.0534975), correlation (0.368357)*/,
    453     -4,9, -3,4/*mean (0.099865), correlation (0.372276)*/,
    454     7,-1, 12,2/*mean (0.117083), correlation (0.364529)*/,
    455     -7,6, -5,1/*mean (0.126125), correlation (0.369606)*/,
    456     -13,11, -12,5/*mean (0.130364), correlation (0.358502)*/,
    457     -3,7, -2,-6/*mean (0.131691), correlation (0.375531)*/,
    458     7,-8, 12,-7/*mean (0.160166), correlation (0.379508)*/,
    459     -13,-7, -11,-12/*mean (0.167848), correlation (0.353343)*/,
    460     1,-3, 12,12/*mean (0.183378), correlation (0.371916)*/,
    461     2,-6, 3,0/*mean (0.228711), correlation (0.371761)*/,
    462     -4,3, -2,-13/*mean (0.247211), correlation (0.364063)*/,
    463     -1,-13, 1,9/*mean (0.249325), correlation (0.378139)*/,
    464     7,1, 8,-6/*mean (0.000652272), correlation (0.411682)*/,
    465     1,-1, 3,12/*mean (0.00248538), correlation (0.392988)*/,
    466     9,1, 12,6/*mean (0.0206815), correlation (0.386106)*/,
    467     -1,-9, -1,3/*mean (0.0364485), correlation (0.410752)*/,
    468     -13,-13, -10,5/*mean (0.0376068), correlation (0.398374)*/,
    469     7,7, 10,12/*mean (0.0424202), correlation (0.405663)*/,
    470     12,-5, 12,9/*mean (0.0942645), correlation (0.410422)*/,
    471     6,3, 7,11/*mean (0.1074), correlation (0.413224)*/,
    472     5,-13, 6,10/*mean (0.109256), correlation (0.408646)*/,
    473     2,-12, 2,3/*mean (0.131691), correlation (0.416076)*/,
    474     3,8, 4,-6/*mean (0.165081), correlation (0.417569)*/,
    475     2,6, 12,-13/*mean (0.171874), correlation (0.408471)*/,
    476     9,-12, 10,3/*mean (0.175146), correlation (0.41296)*/,
    477     -8,4, -7,9/*mean (0.183682), correlation (0.402956)*/,
    478     -11,12, -4,-6/*mean (0.184672), correlation (0.416125)*/,
    479     1,12, 2,-8/*mean (0.191487), correlation (0.386696)*/,
    480     6,-9, 7,-4/*mean (0.192668), correlation (0.394771)*/,
    481     2,3, 3,-2/*mean (0.200157), correlation (0.408303)*/,
    482     6,3, 11,0/*mean (0.204588), correlation (0.411762)*/,
    483     3,-3, 8,-8/*mean (0.205904), correlation (0.416294)*/,
    484     7,8, 9,3/*mean (0.213237), correlation (0.409306)*/,
    485     -11,-5, -6,-4/*mean (0.243444), correlation (0.395069)*/,
    486     -10,11, -5,10/*mean (0.247672), correlation (0.413392)*/,
    487     -5,-8, -3,12/*mean (0.24774), correlation (0.411416)*/,
    488     -10,5, -9,0/*mean (0.00213675), correlation (0.454003)*/,
    489     8,-1, 12,-6/*mean (0.0293635), correlation (0.455368)*/,
    490     4,-6, 6,-11/*mean (0.0404971), correlation (0.457393)*/,
    491     -10,12, -8,7/*mean (0.0481107), correlation (0.448364)*/,
    492     4,-2, 6,7/*mean (0.050641), correlation (0.455019)*/,
    493     -2,0, -2,12/*mean (0.0525978), correlation (0.44338)*/,
    494     -5,-8, -5,2/*mean (0.0629667), correlation (0.457096)*/,
    495     7,-6, 10,12/*mean (0.0653846), correlation (0.445623)*/,
    496     -9,-13, -8,-8/*mean (0.0858749), correlation (0.449789)*/,
    497     -5,-13, -5,-2/*mean (0.122402), correlation (0.450201)*/,
    498     8,-8, 9,-13/*mean (0.125416), correlation (0.453224)*/,
    499     -9,-11, -9,0/*mean (0.130128), correlation (0.458724)*/,
    500     1,-8, 1,-2/*mean (0.132467), correlation (0.440133)*/,
    501     7,-4, 9,1/*mean (0.132692), correlation (0.454)*/,
    502     -2,1, -1,-4/*mean (0.135695), correlation (0.455739)*/,
    503     11,-6, 12,-11/*mean (0.142904), correlation (0.446114)*/,
    504     -12,-9, -6,4/*mean (0.146165), correlation (0.451473)*/,
    505     3,7, 7,12/*mean (0.147627), correlation (0.456643)*/,
    506     5,5, 10,8/*mean (0.152901), correlation (0.455036)*/,
    507     0,-4, 2,8/*mean (0.167083), correlation (0.459315)*/,
    508     -9,12, -5,-13/*mean (0.173234), correlation (0.454706)*/,
    509     0,7, 2,12/*mean (0.18312), correlation (0.433855)*/,
    510     -1,2, 1,7/*mean (0.185504), correlation (0.443838)*/,
    511     5,11, 7,-9/*mean (0.185706), correlation (0.451123)*/,
    512     3,5, 6,-8/*mean (0.188968), correlation (0.455808)*/,
    513     -13,-4, -8,9/*mean (0.191667), correlation (0.459128)*/,
    514     -5,9, -3,-3/*mean (0.193196), correlation (0.458364)*/,
    515     -4,-7, -3,-12/*mean (0.196536), correlation (0.455782)*/,
    516     6,5, 8,0/*mean (0.1972), correlation (0.450481)*/,
    517     -7,6, -6,12/*mean (0.199438), correlation (0.458156)*/,
    518     -13,6, -5,-2/*mean (0.211224), correlation (0.449548)*/,
    519     1,-10, 3,10/*mean (0.211718), correlation (0.440606)*/,
    520     4,1, 8,-4/*mean (0.213034), correlation (0.443177)*/,
    521     -2,-2, 2,-13/*mean (0.234334), correlation (0.455304)*/,
    522     2,-12, 12,12/*mean (0.235684), correlation (0.443436)*/,
    523     -2,-13, 0,-6/*mean (0.237674), correlation (0.452525)*/,
    524     4,1, 9,3/*mean (0.23962), correlation (0.444824)*/,
    525     -6,-10, -3,-5/*mean (0.248459), correlation (0.439621)*/,
    526     -3,-13, -1,1/*mean (0.249505), correlation (0.456666)*/,
    527     7,5, 12,-11/*mean (0.00119208), correlation (0.495466)*/,
    528     4,-2, 5,-7/*mean (0.00372245), correlation (0.484214)*/,
    529     -13,9, -9,-5/*mean (0.00741116), correlation (0.499854)*/,
    530     7,1, 8,6/*mean (0.0208952), correlation (0.499773)*/,
    531     7,-8, 7,6/*mean (0.0220085), correlation (0.501609)*/,
    532     -7,-4, -7,1/*mean (0.0233806), correlation (0.496568)*/,
    533     -8,11, -7,-8/*mean (0.0236505), correlation (0.489719)*/,
    534     -13,6, -12,-8/*mean (0.0268781), correlation (0.503487)*/,
    535     2,4, 3,9/*mean (0.0323324), correlation (0.501938)*/,
    536     10,-5, 12,3/*mean (0.0399235), correlation (0.494029)*/,
    537     -6,-5, -6,7/*mean (0.0420153), correlation (0.486579)*/,
    538     8,-3, 9,-8/*mean (0.0548021), correlation (0.484237)*/,
    539     2,-12, 2,8/*mean (0.0616622), correlation (0.496642)*/,
    540     -11,-2, -10,3/*mean (0.0627755), correlation (0.498563)*/,
    541     -12,-13, -7,-9/*mean (0.0829622), correlation (0.495491)*/,
    542     -11,0, -10,-5/*mean (0.0843342), correlation (0.487146)*/,
    543     5,-3, 11,8/*mean (0.0929937), correlation (0.502315)*/,
    544     -2,-13, -1,12/*mean (0.113327), correlation (0.48941)*/,
    545     -1,-8, 0,9/*mean (0.132119), correlation (0.467268)*/,
    546     -13,-11, -12,-5/*mean (0.136269), correlation (0.498771)*/,
    547     -10,-2, -10,11/*mean (0.142173), correlation (0.498714)*/,
    548     -3,9, -2,-13/*mean (0.144141), correlation (0.491973)*/,
    549     2,-3, 3,2/*mean (0.14892), correlation (0.500782)*/,
    550     -9,-13, -4,0/*mean (0.150371), correlation (0.498211)*/,
    551     -4,6, -3,-10/*mean (0.152159), correlation (0.495547)*/,
    552     -4,12, -2,-7/*mean (0.156152), correlation (0.496925)*/,
    553     -6,-11, -4,9/*mean (0.15749), correlation (0.499222)*/,
    554     6,-3, 6,11/*mean (0.159211), correlation (0.503821)*/,
    555     -13,11, -5,5/*mean (0.162427), correlation (0.501907)*/,
    556     11,11, 12,6/*mean (0.16652), correlation (0.497632)*/,
    557     7,-5, 12,-2/*mean (0.169141), correlation (0.484474)*/,
    558     -1,12, 0,7/*mean (0.169456), correlation (0.495339)*/,
    559     -4,-8, -3,-2/*mean (0.171457), correlation (0.487251)*/,
    560     -7,1, -6,7/*mean (0.175), correlation (0.500024)*/,
    561     -13,-12, -8,-13/*mean (0.175866), correlation (0.497523)*/,
    562     -7,-2, -6,-8/*mean (0.178273), correlation (0.501854)*/,
    563     -8,5, -6,-9/*mean (0.181107), correlation (0.494888)*/,
    564     -5,-1, -4,5/*mean (0.190227), correlation (0.482557)*/,
    565     -13,7, -8,10/*mean (0.196739), correlation (0.496503)*/,
    566     1,5, 5,-13/*mean (0.19973), correlation (0.499759)*/,
    567     1,0, 10,-13/*mean (0.204465), correlation (0.49873)*/,
    568     9,12, 10,-1/*mean (0.209334), correlation (0.49063)*/,
    569     5,-8, 10,-9/*mean (0.211134), correlation (0.503011)*/,
    570     -1,11, 1,-13/*mean (0.212), correlation (0.499414)*/,
    571     -9,-3, -6,2/*mean (0.212168), correlation (0.480739)*/,
    572     -1,-10, 1,12/*mean (0.212731), correlation (0.502523)*/,
    573     -13,1, -8,-10/*mean (0.21327), correlation (0.489786)*/,
    574     8,-11, 10,-6/*mean (0.214159), correlation (0.488246)*/,
    575     2,-13, 3,-6/*mean (0.216993), correlation (0.50287)*/,
    576     7,-13, 12,-9/*mean (0.223639), correlation (0.470502)*/,
    577     -10,-10, -5,-7/*mean (0.224089), correlation (0.500852)*/,
    578     -10,-8, -8,-13/*mean (0.228666), correlation (0.502629)*/,
    579     4,-6, 8,5/*mean (0.22906), correlation (0.498305)*/,
    580     3,12, 8,-13/*mean (0.233378), correlation (0.503825)*/,
    581     -4,2, -3,-3/*mean (0.234323), correlation (0.476692)*/,
    582     5,-13, 10,-12/*mean (0.236392), correlation (0.475462)*/,
    583     4,-13, 5,-1/*mean (0.236842), correlation (0.504132)*/,
    584     -9,9, -4,3/*mean (0.236977), correlation (0.497739)*/,
    585     0,3, 3,-9/*mean (0.24314), correlation (0.499398)*/,
    586     -12,1, -6,1/*mean (0.243297), correlation (0.489447)*/,
    587     3,2, 4,-8/*mean (0.00155196), correlation (0.553496)*/,
    588     -10,-10, -10,9/*mean (0.00239541), correlation (0.54297)*/,
    589     8,-13, 12,12/*mean (0.0034413), correlation (0.544361)*/,
    590     -8,-12, -6,-5/*mean (0.003565), correlation (0.551225)*/,
    591     2,2, 3,7/*mean (0.00835583), correlation (0.55285)*/,
    592     10,6, 11,-8/*mean (0.00885065), correlation (0.540913)*/,
    593     6,8, 8,-12/*mean (0.0101552), correlation (0.551085)*/,
    594     -7,10, -6,5/*mean (0.0102227), correlation (0.533635)*/,
    595     -3,-9, -3,9/*mean (0.0110211), correlation (0.543121)*/,
    596     -1,-13, -1,5/*mean (0.0113473), correlation (0.550173)*/,
    597     -3,-7, -3,4/*mean (0.0140913), correlation (0.554774)*/,
    598     -8,-2, -8,3/*mean (0.017049), correlation (0.55461)*/,
    599     4,2, 12,12/*mean (0.01778), correlation (0.546921)*/,
    600     2,-5, 3,11/*mean (0.0224022), correlation (0.549667)*/,
    601     6,-9, 11,-13/*mean (0.029161), correlation (0.546295)*/,
    602     3,-1, 7,12/*mean (0.0303081), correlation (0.548599)*/,
    603     11,-1, 12,4/*mean (0.0355151), correlation (0.523943)*/,
    604     -3,0, -3,6/*mean (0.0417904), correlation (0.543395)*/,
    605     4,-11, 4,12/*mean (0.0487292), correlation (0.542818)*/,
    606     2,-4, 2,1/*mean (0.0575124), correlation (0.554888)*/,
    607     -10,-6, -8,1/*mean (0.0594242), correlation (0.544026)*/,
    608     -13,7, -11,1/*mean (0.0597391), correlation (0.550524)*/,
    609     -13,12, -11,-13/*mean (0.0608974), correlation (0.55383)*/,
    610     6,0, 11,-13/*mean (0.065126), correlation (0.552006)*/,
    611     0,-1, 1,4/*mean (0.074224), correlation (0.546372)*/,
    612     -13,3, -9,-2/*mean (0.0808592), correlation (0.554875)*/,
    613     -9,8, -6,-3/*mean (0.0883378), correlation (0.551178)*/,
    614     -13,-6, -8,-2/*mean (0.0901035), correlation (0.548446)*/,
    615     5,-9, 8,10/*mean (0.0949843), correlation (0.554694)*/,
    616     2,7, 3,-9/*mean (0.0994152), correlation (0.550979)*/,
    617     -1,-6, -1,-1/*mean (0.10045), correlation (0.552714)*/,
    618     9,5, 11,-2/*mean (0.100686), correlation (0.552594)*/,
    619     11,-3, 12,-8/*mean (0.101091), correlation (0.532394)*/,
    620     3,0, 3,5/*mean (0.101147), correlation (0.525576)*/,
    621     -1,4, 0,10/*mean (0.105263), correlation (0.531498)*/,
    622     3,-6, 4,5/*mean (0.110785), correlation (0.540491)*/,
    623     -13,0, -10,5/*mean (0.112798), correlation (0.536582)*/,
    624     5,8, 12,11/*mean (0.114181), correlation (0.555793)*/,
    625     8,9, 9,-6/*mean (0.117431), correlation (0.553763)*/,
    626     7,-4, 8,-12/*mean (0.118522), correlation (0.553452)*/,
    627     -10,4, -10,9/*mean (0.12094), correlation (0.554785)*/,
    628     7,3, 12,4/*mean (0.122582), correlation (0.555825)*/,
    629     9,-7, 10,-2/*mean (0.124978), correlation (0.549846)*/,
    630     7,0, 12,-2/*mean (0.127002), correlation (0.537452)*/,
    631     -1,-6, 0,-11/*mean (0.127148), correlation (0.547401)*/
    632 };
    633 
    634 
    635 static void makeRandomPattern(int patchSize, Point* pattern, int npoints)
    636 {
    637     RNG rng(0x34985739); // we always start with a fixed seed,
    638                          // to make patterns the same on each run
    639     for( int i = 0; i < npoints; i++ )
    640     {
    641         pattern[i].x = rng.uniform(-patchSize/2, patchSize/2+1);
    642         pattern[i].y = rng.uniform(-patchSize/2, patchSize/2+1);
    643     }
    644 }
    645 
    646 
    647 static inline float getScale(int level, int firstLevel, double scaleFactor)
    648 {
    649     return (float)std::pow(scaleFactor, (double)(level - firstLevel));
    650 }
    651 
    652 
    653 class ORB_Impl : public ORB
    654 {
    655 public:
    656     explicit ORB_Impl(int _nfeatures, float _scaleFactor, int _nlevels, int _edgeThreshold,
    657              int _firstLevel, int _WTA_K, int _scoreType, int _patchSize, int _fastThreshold) :
    658         nfeatures(_nfeatures), scaleFactor(_scaleFactor), nlevels(_nlevels),
    659         edgeThreshold(_edgeThreshold), firstLevel(_firstLevel), wta_k(_WTA_K),
    660         scoreType(_scoreType), patchSize(_patchSize), fastThreshold(_fastThreshold)
    661     {}
    662 
    663     void setMaxFeatures(int maxFeatures) { nfeatures = maxFeatures; }
    664     int getMaxFeatures() const { return nfeatures; }
    665 
    666     void setScaleFactor(double scaleFactor_) { scaleFactor = scaleFactor_; }
    667     double getScaleFactor() const { return scaleFactor; }
    668 
    669     void setNLevels(int nlevels_) { nlevels = nlevels_; }
    670     int getNLevels() const { return nlevels; }
    671 
    672     void setEdgeThreshold(int edgeThreshold_) { edgeThreshold = edgeThreshold_; }
    673     int getEdgeThreshold() const { return edgeThreshold; }
    674 
    675     void setFirstLevel(int firstLevel_) { firstLevel = firstLevel_; }
    676     int getFirstLevel() const { return firstLevel; }
    677 
    678     void setWTA_K(int wta_k_) { wta_k = wta_k_; }
    679     int getWTA_K() const { return wta_k; }
    680 
    681     void setScoreType(int scoreType_) { scoreType = scoreType_; }
    682     int getScoreType() const { return scoreType; }
    683 
    684     void setPatchSize(int patchSize_) { patchSize = patchSize_; }
    685     int getPatchSize() const { return patchSize; }
    686 
    687     void setFastThreshold(int fastThreshold_) { fastThreshold = fastThreshold_; }
    688     int getFastThreshold() const { return fastThreshold; }
    689 
    690     // returns the descriptor size in bytes
    691     int descriptorSize() const;
    692     // returns the descriptor type
    693     int descriptorType() const;
    694     // returns the default norm type
    695     int defaultNorm() const;
    696 
    697     // Compute the ORB_Impl features and descriptors on an image
    698     void detectAndCompute( InputArray image, InputArray mask, std::vector<KeyPoint>& keypoints,
    699                      OutputArray descriptors, bool useProvidedKeypoints=false );
    700 
    701 protected:
    702 
    703     int nfeatures;
    704     double scaleFactor;
    705     int nlevels;
    706     int edgeThreshold;
    707     int firstLevel;
    708     int wta_k;
    709     int scoreType;
    710     int patchSize;
    711     int fastThreshold;
    712 };
    713 
    714 int ORB_Impl::descriptorSize() const
    715 {
    716     return kBytes;
    717 }
    718 
    719 int ORB_Impl::descriptorType() const
    720 {
    721     return CV_8U;
    722 }
    723 
    724 int ORB_Impl::defaultNorm() const
    725 {
    726     return NORM_HAMMING;
    727 }
    728 
    729 static void uploadORBKeypoints(const std::vector<KeyPoint>& src, std::vector<Vec3i>& buf, OutputArray dst)
    730 {
    731     size_t i, n = src.size();
    732     buf.resize(std::max(buf.size(), n));
    733     for( i = 0; i < n; i++ )
    734         buf[i] = Vec3i(cvRound(src[i].pt.x), cvRound(src[i].pt.y), src[i].octave);
    735     copyVectorToUMat(buf, dst);
    736 }
    737 
    738 typedef union if32_t
    739 {
    740     int i;
    741     float f;
    742 }
    743 if32_t;
    744 
    745 static void uploadORBKeypoints(const std::vector<KeyPoint>& src,
    746                                const std::vector<float>& layerScale,
    747                                std::vector<Vec4i>& buf, OutputArray dst)
    748 {
    749     size_t i, n = src.size();
    750     buf.resize(std::max(buf.size(), n));
    751     for( i = 0; i < n; i++ )
    752     {
    753         int z = src[i].octave;
    754         float scale = 1.f/layerScale[z];
    755         if32_t angle;
    756         angle.f = src[i].angle;
    757         buf[i] = Vec4i(cvRound(src[i].pt.x*scale), cvRound(src[i].pt.y*scale), z, angle.i);
    758     }
    759     copyVectorToUMat(buf, dst);
    760 }
    761 
    762 
    763 /** Compute the ORB_Impl keypoints on an image
    764  * @param image_pyramid the image pyramid to compute the features and descriptors on
    765  * @param mask_pyramid the masks to apply at every level
    766  * @param keypoints the resulting keypoints, clustered per level
    767  */
    768 static void computeKeyPoints(const Mat& imagePyramid,
    769                              const UMat& uimagePyramid,
    770                              const Mat& maskPyramid,
    771                              const std::vector<Rect>& layerInfo,
    772                              const UMat& ulayerInfo,
    773                              const std::vector<float>& layerScale,
    774                              std::vector<KeyPoint>& allKeypoints,
    775                              int nfeatures, double scaleFactor,
    776                              int edgeThreshold, int patchSize, int scoreType,
    777                              bool useOCL, int fastThreshold  )
    778 {
    779     int i, nkeypoints, level, nlevels = (int)layerInfo.size();
    780     std::vector<int> nfeaturesPerLevel(nlevels);
    781 
    782     // fill the extractors and descriptors for the corresponding scales
    783     float factor = (float)(1.0 / scaleFactor);
    784     float ndesiredFeaturesPerScale = nfeatures*(1 - factor)/(1 - (float)std::pow((double)factor, (double)nlevels));
    785 
    786     int sumFeatures = 0;
    787     for( level = 0; level < nlevels-1; level++ )
    788     {
    789         nfeaturesPerLevel[level] = cvRound(ndesiredFeaturesPerScale);
    790         sumFeatures += nfeaturesPerLevel[level];
    791         ndesiredFeaturesPerScale *= factor;
    792     }
    793     nfeaturesPerLevel[nlevels-1] = std::max(nfeatures - sumFeatures, 0);
    794 
    795     // Make sure we forget about what is too close to the boundary
    796     //edge_threshold_ = std::max(edge_threshold_, patch_size_/2 + kKernelWidth / 2 + 2);
    797 
    798     // pre-compute the end of a row in a circular patch
    799     int halfPatchSize = patchSize / 2;
    800     std::vector<int> umax(halfPatchSize + 2);
    801 
    802     int v, v0, vmax = cvFloor(halfPatchSize * std::sqrt(2.f) / 2 + 1);
    803     int vmin = cvCeil(halfPatchSize * std::sqrt(2.f) / 2);
    804     for (v = 0; v <= vmax; ++v)
    805         umax[v] = cvRound(std::sqrt((double)halfPatchSize * halfPatchSize - v * v));
    806 
    807     // Make sure we are symmetric
    808     for (v = halfPatchSize, v0 = 0; v >= vmin; --v)
    809     {
    810         while (umax[v0] == umax[v0 + 1])
    811             ++v0;
    812         umax[v] = v0;
    813         ++v0;
    814     }
    815 
    816     allKeypoints.clear();
    817     std::vector<KeyPoint> keypoints;
    818     std::vector<int> counters(nlevels);
    819     keypoints.reserve(nfeaturesPerLevel[0]*2);
    820 
    821     for( level = 0; level < nlevels; level++ )
    822     {
    823         int featuresNum = nfeaturesPerLevel[level];
    824         Mat img = imagePyramid(layerInfo[level]);
    825         Mat mask = maskPyramid.empty() ? Mat() : maskPyramid(layerInfo[level]);
    826 
    827         // Detect FAST features, 20 is a good threshold
    828         {
    829         Ptr<FastFeatureDetector> fd = FastFeatureDetector::create(fastThreshold, true);
    830         fd->detect(img, keypoints, mask);
    831         }
    832 
    833         // Remove keypoints very close to the border
    834         KeyPointsFilter::runByImageBorder(keypoints, img.size(), edgeThreshold);
    835 
    836         // Keep more points than necessary as FAST does not give amazing corners
    837         KeyPointsFilter::retainBest(keypoints, scoreType == ORB_Impl::HARRIS_SCORE ? 2 * featuresNum : featuresNum);
    838 
    839         nkeypoints = (int)keypoints.size();
    840         counters[level] = nkeypoints;
    841 
    842         float sf = layerScale[level];
    843         for( i = 0; i < nkeypoints; i++ )
    844         {
    845             keypoints[i].octave = level;
    846             keypoints[i].size = patchSize*sf;
    847         }
    848 
    849         std::copy(keypoints.begin(), keypoints.end(), std::back_inserter(allKeypoints));
    850     }
    851 
    852     std::vector<Vec3i> ukeypoints_buf;
    853 
    854     nkeypoints = (int)allKeypoints.size();
    855     if(nkeypoints == 0)
    856     {
    857         return;
    858     }
    859     Mat responses;
    860     UMat ukeypoints, uresponses(1, nkeypoints, CV_32F);
    861 
    862     // Select best features using the Harris cornerness (better scoring than FAST)
    863     if( scoreType == ORB_Impl::HARRIS_SCORE )
    864     {
    865         if( useOCL )
    866         {
    867             uploadORBKeypoints(allKeypoints, ukeypoints_buf, ukeypoints);
    868             useOCL = ocl_HarrisResponses( uimagePyramid, ulayerInfo, ukeypoints,
    869                                           uresponses, nkeypoints, 7, HARRIS_K );
    870             if( useOCL )
    871             {
    872                 CV_IMPL_ADD(CV_IMPL_OCL);
    873                 uresponses.copyTo(responses);
    874                 for( i = 0; i < nkeypoints; i++ )
    875                     allKeypoints[i].response = responses.at<float>(i);
    876             }
    877         }
    878 
    879         if( !useOCL )
    880             HarrisResponses(imagePyramid, layerInfo, allKeypoints, 7, HARRIS_K);
    881 
    882         std::vector<KeyPoint> newAllKeypoints;
    883         newAllKeypoints.reserve(nfeaturesPerLevel[0]*nlevels);
    884 
    885         int offset = 0;
    886         for( level = 0; level < nlevels; level++ )
    887         {
    888             int featuresNum = nfeaturesPerLevel[level];
    889             nkeypoints = counters[level];
    890             keypoints.resize(nkeypoints);
    891             std::copy(allKeypoints.begin() + offset,
    892                       allKeypoints.begin() + offset + nkeypoints,
    893                       keypoints.begin());
    894             offset += nkeypoints;
    895 
    896             //cull to the final desired level, using the new Harris scores.
    897             KeyPointsFilter::retainBest(keypoints, featuresNum);
    898 
    899             std::copy(keypoints.begin(), keypoints.end(), std::back_inserter(newAllKeypoints));
    900         }
    901         std::swap(allKeypoints, newAllKeypoints);
    902     }
    903 
    904     nkeypoints = (int)allKeypoints.size();
    905     if( useOCL )
    906     {
    907         UMat uumax;
    908         if( useOCL )
    909             copyVectorToUMat(umax, uumax);
    910 
    911         uploadORBKeypoints(allKeypoints, ukeypoints_buf, ukeypoints);
    912         useOCL = ocl_ICAngles(uimagePyramid, ulayerInfo, ukeypoints, uresponses, uumax,
    913                               nkeypoints, halfPatchSize);
    914 
    915         if( useOCL )
    916         {
    917             CV_IMPL_ADD(CV_IMPL_OCL);
    918             uresponses.copyTo(responses);
    919             for( i = 0; i < nkeypoints; i++ )
    920                 allKeypoints[i].angle = responses.at<float>(i);
    921         }
    922     }
    923 
    924     if( !useOCL )
    925     {
    926         ICAngles(imagePyramid, layerInfo, allKeypoints, umax, halfPatchSize);
    927     }
    928 
    929     for( i = 0; i < nkeypoints; i++ )
    930     {
    931         float scale = layerScale[allKeypoints[i].octave];
    932         allKeypoints[i].pt *= scale;
    933     }
    934 }
    935 
    936 
    937 /** Compute the ORB_Impl features and descriptors on an image
    938  * @param img the image to compute the features and descriptors on
    939  * @param mask the mask to apply
    940  * @param keypoints the resulting keypoints
    941  * @param descriptors the resulting descriptors
    942  * @param do_keypoints if true, the keypoints are computed, otherwise used as an input
    943  * @param do_descriptors if true, also computes the descriptors
    944  */
    945 void ORB_Impl::detectAndCompute( InputArray _image, InputArray _mask,
    946                                  std::vector<KeyPoint>& keypoints,
    947                                  OutputArray _descriptors, bool useProvidedKeypoints )
    948 {
    949     CV_Assert(patchSize >= 2);
    950 
    951     bool do_keypoints = !useProvidedKeypoints;
    952     bool do_descriptors = _descriptors.needed();
    953 
    954     if( (!do_keypoints && !do_descriptors) || _image.empty() )
    955         return;
    956 
    957     //ROI handling
    958     const int HARRIS_BLOCK_SIZE = 9;
    959     int halfPatchSize = patchSize / 2;
    960     int border = std::max(edgeThreshold, std::max(halfPatchSize, HARRIS_BLOCK_SIZE/2))+1;
    961 
    962     bool useOCL = ocl::useOpenCL();
    963 
    964     Mat image = _image.getMat(), mask = _mask.getMat();
    965     if( image.type() != CV_8UC1 )
    966         cvtColor(_image, image, COLOR_BGR2GRAY);
    967 
    968     int i, level, nLevels = this->nlevels, nkeypoints = (int)keypoints.size();
    969     bool sortedByLevel = true;
    970 
    971     if( !do_keypoints )
    972     {
    973         // if we have pre-computed keypoints, they may use more levels than it is set in parameters
    974         // !!!TODO!!! implement more correct method, independent from the used keypoint detector.
    975         // Namely, the detector should provide correct size of each keypoint. Based on the keypoint size
    976         // and the algorithm used (i.e. BRIEF, running on 31x31 patches) we should compute the approximate
    977         // scale-factor that we need to apply. Then we should cluster all the computed scale-factors and
    978         // for each cluster compute the corresponding image.
    979         //
    980         // In short, ultimately the descriptor should
    981         // ignore octave parameter and deal only with the keypoint size.
    982         nLevels = 0;
    983         for( i = 0; i < nkeypoints; i++ )
    984         {
    985             level = keypoints[i].octave;
    986             CV_Assert(level >= 0);
    987             if( i > 0 && level < keypoints[i-1].octave )
    988                 sortedByLevel = false;
    989             nLevels = std::max(nLevels, level);
    990         }
    991         nLevels++;
    992     }
    993 
    994     std::vector<Rect> layerInfo(nLevels);
    995     std::vector<int> layerOfs(nLevels);
    996     std::vector<float> layerScale(nLevels);
    997     Mat imagePyramid, maskPyramid;
    998     UMat uimagePyramid, ulayerInfo;
    999 
   1000     int level_dy = image.rows + border*2;
   1001     Point level_ofs(0,0);
   1002     Size bufSize((image.cols + border*2 + 15) & -16, 0);
   1003 
   1004     for( level = 0; level < nLevels; level++ )
   1005     {
   1006         float scale = getScale(level, firstLevel, scaleFactor);
   1007         layerScale[level] = scale;
   1008         Size sz(cvRound(image.cols/scale), cvRound(image.rows/scale));
   1009         Size wholeSize(sz.width + border*2, sz.height + border*2);
   1010         if( level_ofs.x + wholeSize.width > bufSize.width )
   1011         {
   1012             level_ofs = Point(0, level_ofs.y + level_dy);
   1013             level_dy = wholeSize.height;
   1014         }
   1015 
   1016         Rect linfo(level_ofs.x + border, level_ofs.y + border, sz.width, sz.height);
   1017         layerInfo[level] = linfo;
   1018         layerOfs[level] = linfo.y*bufSize.width + linfo.x;
   1019         level_ofs.x += wholeSize.width;
   1020     }
   1021     bufSize.height = level_ofs.y + level_dy;
   1022 
   1023     imagePyramid.create(bufSize, CV_8U);
   1024     if( !mask.empty() )
   1025         maskPyramid.create(bufSize, CV_8U);
   1026 
   1027     Mat prevImg = image, prevMask = mask;
   1028 
   1029     // Pre-compute the scale pyramids
   1030     for (level = 0; level < nLevels; ++level)
   1031     {
   1032         Rect linfo = layerInfo[level];
   1033         Size sz(linfo.width, linfo.height);
   1034         Size wholeSize(sz.width + border*2, sz.height + border*2);
   1035         Rect wholeLinfo = Rect(linfo.x - border, linfo.y - border, wholeSize.width, wholeSize.height);
   1036         Mat extImg = imagePyramid(wholeLinfo), extMask;
   1037         Mat currImg = extImg(Rect(border, border, sz.width, sz.height)), currMask;
   1038 
   1039         if( !mask.empty() )
   1040         {
   1041             extMask = maskPyramid(wholeLinfo);
   1042             currMask = extMask(Rect(border, border, sz.width, sz.height));
   1043         }
   1044 
   1045         // Compute the resized image
   1046         if( level != firstLevel )
   1047         {
   1048             resize(prevImg, currImg, sz, 0, 0, INTER_LINEAR);
   1049             if( !mask.empty() )
   1050             {
   1051                 resize(prevMask, currMask, sz, 0, 0, INTER_LINEAR);
   1052                 if( level > firstLevel )
   1053                     threshold(currMask, currMask, 254, 0, THRESH_TOZERO);
   1054             }
   1055 
   1056             copyMakeBorder(currImg, extImg, border, border, border, border,
   1057                            BORDER_REFLECT_101+BORDER_ISOLATED);
   1058             if (!mask.empty())
   1059                 copyMakeBorder(currMask, extMask, border, border, border, border,
   1060                                BORDER_CONSTANT+BORDER_ISOLATED);
   1061         }
   1062         else
   1063         {
   1064             copyMakeBorder(image, extImg, border, border, border, border,
   1065                            BORDER_REFLECT_101);
   1066             if( !mask.empty() )
   1067                 copyMakeBorder(mask, extMask, border, border, border, border,
   1068                                BORDER_CONSTANT+BORDER_ISOLATED);
   1069         }
   1070         prevImg = currImg;
   1071         prevMask = currMask;
   1072     }
   1073 
   1074     if( useOCL )
   1075         copyVectorToUMat(layerOfs, ulayerInfo);
   1076 
   1077     if( do_keypoints )
   1078     {
   1079         if( useOCL )
   1080             imagePyramid.copyTo(uimagePyramid);
   1081 
   1082         // Get keypoints, those will be far enough from the border that no check will be required for the descriptor
   1083         computeKeyPoints(imagePyramid, uimagePyramid, maskPyramid,
   1084                          layerInfo, ulayerInfo, layerScale, keypoints,
   1085                          nfeatures, scaleFactor, edgeThreshold, patchSize, scoreType, useOCL, fastThreshold);
   1086     }
   1087     else
   1088     {
   1089         KeyPointsFilter::runByImageBorder(keypoints, image.size(), edgeThreshold);
   1090 
   1091         if( !sortedByLevel )
   1092         {
   1093             std::vector<std::vector<KeyPoint> > allKeypoints(nLevels);
   1094             nkeypoints = (int)keypoints.size();
   1095             for( i = 0; i < nkeypoints; i++ )
   1096             {
   1097                 level = keypoints[i].octave;
   1098                 CV_Assert(0 <= level);
   1099                 allKeypoints[level].push_back(keypoints[i]);
   1100             }
   1101             keypoints.clear();
   1102             for( level = 0; level < nLevels; level++ )
   1103                 std::copy(allKeypoints[level].begin(), allKeypoints[level].end(), std::back_inserter(keypoints));
   1104         }
   1105     }
   1106 
   1107     if( do_descriptors )
   1108     {
   1109         int dsize = descriptorSize();
   1110 
   1111         nkeypoints = (int)keypoints.size();
   1112         if( nkeypoints == 0 )
   1113         {
   1114             _descriptors.release();
   1115             return;
   1116         }
   1117 
   1118         _descriptors.create(nkeypoints, dsize, CV_8U);
   1119         std::vector<Point> pattern;
   1120 
   1121         const int npoints = 512;
   1122         Point patternbuf[npoints];
   1123         const Point* pattern0 = (const Point*)bit_pattern_31_;
   1124 
   1125         if( patchSize != 31 )
   1126         {
   1127             pattern0 = patternbuf;
   1128             makeRandomPattern(patchSize, patternbuf, npoints);
   1129         }
   1130 
   1131         CV_Assert( wta_k == 2 || wta_k == 3 || wta_k == 4 );
   1132 
   1133         if( wta_k == 2 )
   1134             std::copy(pattern0, pattern0 + npoints, std::back_inserter(pattern));
   1135         else
   1136         {
   1137             int ntuples = descriptorSize()*4;
   1138             initializeOrbPattern(pattern0, pattern, ntuples, wta_k, npoints);
   1139         }
   1140 
   1141         for( level = 0; level < nLevels; level++ )
   1142         {
   1143             // preprocess the resized image
   1144             Mat workingMat = imagePyramid(layerInfo[level]);
   1145 
   1146             //boxFilter(working_mat, working_mat, working_mat.depth(), Size(5,5), Point(-1,-1), true, BORDER_REFLECT_101);
   1147             GaussianBlur(workingMat, workingMat, Size(7, 7), 2, 2, BORDER_REFLECT_101);
   1148         }
   1149 
   1150         if( useOCL )
   1151         {
   1152             imagePyramid.copyTo(uimagePyramid);
   1153             std::vector<Vec4i> kptbuf;
   1154             UMat ukeypoints, upattern;
   1155             copyVectorToUMat(pattern, upattern);
   1156             uploadORBKeypoints(keypoints, layerScale, kptbuf, ukeypoints);
   1157 
   1158             UMat udescriptors = _descriptors.getUMat();
   1159             useOCL = ocl_computeOrbDescriptors(uimagePyramid, ulayerInfo,
   1160                                                ukeypoints, udescriptors, upattern,
   1161                                                nkeypoints, dsize, wta_k);
   1162             if(useOCL)
   1163             {
   1164                 CV_IMPL_ADD(CV_IMPL_OCL);
   1165             }
   1166         }
   1167 
   1168         if( !useOCL )
   1169         {
   1170             Mat descriptors = _descriptors.getMat();
   1171             computeOrbDescriptors(imagePyramid, layerInfo, layerScale,
   1172                                   keypoints, descriptors, pattern, dsize, wta_k);
   1173         }
   1174     }
   1175 }
   1176 
   1177 Ptr<ORB> ORB::create(int nfeatures, float scaleFactor, int nlevels, int edgeThreshold,
   1178            int firstLevel, int wta_k, int scoreType, int patchSize, int fastThreshold)
   1179 {
   1180     return makePtr<ORB_Impl>(nfeatures, scaleFactor, nlevels, edgeThreshold,
   1181                              firstLevel, wta_k, scoreType, patchSize, fastThreshold);
   1182 }
   1183 
   1184 }
   1185