From 49515434413b50054fb6f7535f0f8dfa63e78ff9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96zg=C3=BCr=20Can?= Date: Thu, 19 May 2016 19:59:41 +0300 Subject: [PATCH] Fix issue #6473 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enable "useProvidedKeypoints" flag on cuda::ORB's detectAndCompute function in order to able to describe provided keypoints. * additional author : Ender Tunç resolves #6473 * Enable "useProvidedKeypoints" flag on cuda::ORB's detectAndCompute function in order to able to describe provided keypoints. Update for using 'const' reference to avoid array copy on each iteration. resolves #6473 Update for 'const' reference to avoid array copy on each iteration. --- modules/cudafeatures2d/src/orb.cpp | 86 +++++++++++++++++++++++++----- 1 file changed, 74 insertions(+), 12 deletions(-) diff --git a/modules/cudafeatures2d/src/orb.cpp b/modules/cudafeatures2d/src/orb.cpp index 615ccc8db..41a431d55 100644 --- a/modules/cudafeatures2d/src/orb.cpp +++ b/modules/cudafeatures2d/src/orb.cpp @@ -570,30 +570,92 @@ namespace blurFilter_ = cuda::createGaussianFilter(CV_8UC1, -1, Size(7, 7), 2, 2, BORDER_REFLECT_101); } + static float getScale(float scaleFactor, int firstLevel, int level) + { + return pow(scaleFactor, level - firstLevel); + } + void ORB_Impl::detectAndCompute(InputArray _image, InputArray _mask, std::vector& keypoints, OutputArray _descriptors, bool useProvidedKeypoints) { - CV_Assert( useProvidedKeypoints == false ); + using namespace cv::cuda::device::orb; + if (useProvidedKeypoints) + { + d_keypoints_.release(); + keyPointsPyr_.clear(); - detectAndComputeAsync(_image, _mask, d_keypoints_, _descriptors, false, Stream::Null()); - convert(d_keypoints_, keypoints); + int j, level, nkeypoints = (int)keypoints.size(); + nLevels_ = 0; + for( j = 0; j < nkeypoints; j++ ) + { + level = keypoints[j].octave; + CV_Assert(level >= 0); + nLevels_ = std::max(nLevels_, level); + } + nLevels_ ++; + std::vector > oKeypoints(nLevels_); + for( j = 0; j < nkeypoints; j++ ) + { + level = keypoints[j].octave; + oKeypoints[level].push_back(keypoints[j]); + } + if (!keypoints.empty()) + { + keyPointsPyr_.resize(nLevels_); + keyPointsCount_.resize(nLevels_); + int t; + for(t = 0; t < nLevels_; t++) { + const std::vector& ks = oKeypoints[t]; + if (!ks.empty()){ + + Mat h_keypoints(ROWS_COUNT, static_cast(ks.size()), CV_32FC1); + + float sf = getScale(scaleFactor_, firstLevel_, t); + float locScale = t != firstLevel_ ? sf : 1.0f; + float scale = 1.f/locScale; + + short2* x_loc_row = h_keypoints.ptr(0); + float* x_kp_hessian = h_keypoints.ptr(1); + float* x_kp_dir = h_keypoints.ptr(2); + + for (size_t i = 0, size = ks.size(); i < size; ++i) + { + const KeyPoint& kp = ks[i]; + x_kp_hessian[i] = kp.response; + x_loc_row[i].x = cvRound(kp.pt.x * scale); + x_loc_row[i].y = cvRound(kp.pt.y * scale); + x_kp_dir[i] = kp.angle; + + } + + keyPointsPyr_[t].upload(h_keypoints.rowRange(0,3)); + keyPointsCount_[t] = h_keypoints.cols; + } + } + } + } + + detectAndComputeAsync(_image, _mask, d_keypoints_, _descriptors, useProvidedKeypoints, Stream::Null()); + + if (!useProvidedKeypoints) { + convert(d_keypoints_, keypoints); + } } void ORB_Impl::detectAndComputeAsync(InputArray _image, InputArray _mask, OutputArray _keypoints, OutputArray _descriptors, bool useProvidedKeypoints, Stream& stream) { - CV_Assert( useProvidedKeypoints == false ); - buildScalePyramids(_image, _mask, stream); - computeKeyPointsPyramid(stream); + if (!useProvidedKeypoints) + { + computeKeyPointsPyramid(stream); + } if (_descriptors.needed()) { computeDescriptors(_descriptors, stream); } - mergeKeyPoints(_keypoints, stream); - } - - static float getScale(float scaleFactor, int firstLevel, int level) - { - return pow(scaleFactor, level - firstLevel); + if (!useProvidedKeypoints) + { + mergeKeyPoints(_keypoints, stream); + } } void ORB_Impl::buildScalePyramids(InputArray _image, InputArray _mask, Stream& stream)