fixed bug in ORB_GPU, behavior in the absence of keypoints found (Bug #1831)
authorVladislav Vinogradov <no@email>
Tue, 24 Apr 2012 13:18:34 +0000 (13:18 +0000)
committerVladislav Vinogradov <no@email>
Tue, 24 Apr 2012 13:18:34 +0000 (13:18 +0000)
modules/gpu/src/orb.cpp

index f290a2c..f49caf0 100644 (file)
@@ -63,7 +63,7 @@ void cv::gpu::ORB_GPU::mergeKeyPoints(GpuMat&) { throw_nogpu(); }
 \r
 #else /* !defined (HAVE_CUDA) */\r
 \r
-namespace cv { namespace gpu { namespace device \r
+namespace cv { namespace gpu { namespace device\r
 {\r
     namespace orb\r
     {\r
@@ -345,8 +345,8 @@ namespace
         9,-7, 10,-2/*mean (0.124978), correlation (0.549846)*/,\r
         7,0, 12,-2/*mean (0.127002), correlation (0.537452)*/,\r
         -1,-6, 0,-11/*mean (0.127148), correlation (0.547401)*/\r
-    };    \r
\r
+    };\r
+\r
     void initializeOrbPattern(const Point* pattern0, Mat& pattern, int ntuples, int tupleSize, int poolSize)\r
     {\r
         RNG rng(0x12345678);\r
@@ -356,7 +356,7 @@ namespace
 \r
         int* pattern_x_ptr = pattern.ptr<int>(0);\r
         int* pattern_y_ptr = pattern.ptr<int>(1);\r
-        \r
+\r
         for (int i = 0; i < ntuples; i++)\r
         {\r
             for (int k = 0; k < tupleSize; k++)\r
@@ -386,8 +386,8 @@ namespace
     {\r
         // we always start with a fixed seed,\r
         // to make patterns the same on each run\r
-        RNG rng(0x34985739); \r
-                             \r
+        RNG rng(0x34985739);\r
+\r
         for (int i = 0; i < npoints; i++)\r
         {\r
             pattern[i].x = rng.uniform(-patchSize / 2, patchSize / 2 + 1);\r
@@ -400,11 +400,11 @@ cv::gpu::ORB_GPU::ORB_GPU(int nFeatures, float scaleFactor, int nLevels, int edg
     nFeatures_(nFeatures), scaleFactor_(scaleFactor), nLevels_(nLevels), edgeThreshold_(edgeThreshold), firstLevel_(firstLevel), WTA_K_(WTA_K),\r
     scoreType_(scoreType), patchSize_(patchSize),\r
     fastDetector_(DEFAULT_FAST_THRESHOLD)\r
-{    \r
+{\r
     // fill the extractors and descriptors for the corresponding scales\r
     float factor = 1.0f / scaleFactor_;\r
     float n_desired_features_per_scale = nFeatures_ * (1.0f - factor) / (1.0f - std::pow(factor, nLevels_));\r
-    \r
+\r
     n_features_per_level_.resize(nLevels_);\r
     size_t sum_n_features = 0;\r
     for (int level = 0; level < nLevels_ - 1; ++level)\r
@@ -420,7 +420,7 @@ cv::gpu::ORB_GPU::ORB_GPU(int nFeatures, float scaleFactor, int nLevels, int edg
     vector<int> u_max(half_patch_size + 1);\r
     for (int v = 0; v <= half_patch_size * std::sqrt(2.f) / 2 + 1; ++v)\r
         u_max[v] = cvRound(std::sqrt(static_cast<float>(half_patch_size * half_patch_size - v * v)));\r
-    \r
+\r
     // Make sure we are symmetric\r
     for (int v = half_patch_size, v_0 = 0; v >= half_patch_size * std::sqrt(2.f) / 2; --v)\r
     {\r
@@ -431,7 +431,7 @@ cv::gpu::ORB_GPU::ORB_GPU(int nFeatures, float scaleFactor, int nLevels, int edg
     }\r
     CV_Assert(u_max.size() < 32);\r
     cv::gpu::device::orb::loadUMax(&u_max[0], static_cast<int>(u_max.size()));\r
-    \r
+\r
     // Calc pattern\r
     const int npoints = 512;\r
     Point pattern_buf[npoints];\r
@@ -441,15 +441,15 @@ cv::gpu::ORB_GPU::ORB_GPU(int nFeatures, float scaleFactor, int nLevels, int edg
         pattern0 = pattern_buf;\r
         makeRandomPattern(patchSize_, pattern_buf, npoints);\r
     }\r
-    \r
-    CV_Assert(WTA_K_ == 2 || WTA_K_ == 3 || WTA_K_ == 4);    \r
+\r
+    CV_Assert(WTA_K_ == 2 || WTA_K_ == 3 || WTA_K_ == 4);\r
 \r
     Mat h_pattern;\r
 \r
     if (WTA_K_ == 2)\r
     {\r
         h_pattern.create(2, npoints, CV_32SC1);\r
-        \r
+\r
         int* pattern_x_ptr = h_pattern.ptr<int>(0);\r
         int* pattern_y_ptr = h_pattern.ptr<int>(1);\r
 \r
@@ -466,7 +466,7 @@ cv::gpu::ORB_GPU::ORB_GPU(int nFeatures, float scaleFactor, int nLevels, int edg
     }\r
 \r
     pattern_.upload(h_pattern);\r
-    \r
+\r
     blurFilter = createGaussianFilter_GPU(CV_8UC1, Size(7, 7), 2, 2, BORDER_REFLECT_101);\r
 \r
     blurForDescriptor = false;\r
@@ -497,7 +497,7 @@ void cv::gpu::ORB_GPU::buildScalePyramids(const GpuMat& image, const GpuMat& mas
         ensureSizeIsEnough(sz, image.type(), imagePyr_[level]);\r
         ensureSizeIsEnough(sz, CV_8UC1, maskPyr_[level]);\r
         maskPyr_[level].setTo(Scalar::all(255));\r
-        \r
+\r
         // Compute the resized image\r
         if (level != firstLevel_)\r
         {\r
@@ -544,7 +544,7 @@ namespace
         //this is only necessary if the keypoints size is greater than the number of desired points.\r
         if (count > n_points)\r
         {\r
-            if (n_points == 0) \r
+            if (n_points == 0)\r
             {\r
                 keypoints.release();\r
                 return;\r
@@ -563,18 +563,24 @@ void cv::gpu::ORB_GPU::computeKeyPointsPyramid()
 \r
     keyPointsPyr_.resize(nLevels_);\r
     keyPointsCount_.resize(nLevels_);\r
-    \r
+\r
     for (int level = 0; level < nLevels_; ++level)\r
     {\r
         keyPointsCount_[level] = fastDetector_.calcKeyPointsLocation(imagePyr_[level], maskPyr_[level]);\r
 \r
+        if (keyPointsCount_[level] == 0)\r
+            continue;\r
+\r
         ensureSizeIsEnough(3, keyPointsCount_[level], CV_32FC1, keyPointsPyr_[level]);\r
 \r
         GpuMat fastKpRange = keyPointsPyr_[level].rowRange(0, 2);\r
         keyPointsCount_[level] = fastDetector_.getKeyPoints(fastKpRange);\r
 \r
+        if (keyPointsCount_[level] == 0)\r
+            continue;\r
+\r
         int n_features = static_cast<int>(n_features_per_level_[level]);\r
-        \r
+\r
         if (scoreType_ == ORB::HARRIS_SCORE)\r
         {\r
             // Keep more points than necessary as FAST does not give amazing corners\r
@@ -582,7 +588,7 @@ void cv::gpu::ORB_GPU::computeKeyPointsPyramid()
 \r
             // Compute the Harris cornerness (better scoring than FAST)\r
             HarrisResponses_gpu(imagePyr_[level], keyPointsPyr_[level].ptr<short2>(0), keyPointsPyr_[level].ptr<float>(1), keyPointsCount_[level], 7, HARRIS_K, 0);\r
-        }        \r
+        }\r
 \r
         //cull to the final desired level, using the new Harris scores or the original FAST scores.\r
         cull(keyPointsPyr_[level], keyPointsCount_[level], n_features);\r
@@ -612,7 +618,10 @@ void cv::gpu::ORB_GPU::computeDescriptors(GpuMat& descriptors)
     int offset = 0;\r
 \r
     for (int level = 0; level < nLevels_; ++level)\r
-    {       \r
+    {\r
+        if (keyPointsCount_[level] == 0)\r
+            continue;\r
+\r
         GpuMat descRange = descriptors.rowRange(offset, offset + keyPointsCount_[level]);\r
 \r
         if (blurForDescriptor)\r
@@ -622,7 +631,7 @@ void cv::gpu::ORB_GPU::computeDescriptors(GpuMat& descriptors)
             blurFilter->apply(imagePyr_[level], buf_, Rect(0, 0, imagePyr_[level].cols, imagePyr_[level].rows));\r
         }\r
 \r
-        computeOrbDescriptor_gpu(blurForDescriptor ? buf_ : imagePyr_[level], keyPointsPyr_[level].ptr<short2>(0), keyPointsPyr_[level].ptr<float>(2), \r
+        computeOrbDescriptor_gpu(blurForDescriptor ? buf_ : imagePyr_[level], keyPointsPyr_[level].ptr<short2>(0), keyPointsPyr_[level].ptr<float>(2),\r
             keyPointsCount_[level], pattern_.ptr<int>(0), pattern_.ptr<int>(1), descRange, descriptorSize(), WTA_K_, 0);\r
 \r
         offset += keyPointsCount_[level];\r
@@ -647,20 +656,23 @@ void cv::gpu::ORB_GPU::mergeKeyPoints(GpuMat& keypoints)
     ensureSizeIsEnough(ROWS_COUNT, nAllkeypoints, CV_32FC1, keypoints);\r
 \r
     int offset = 0;\r
-    \r
+\r
     for (int level = 0; level < nLevels_; ++level)\r
     {\r
+        if (keyPointsCount_[level] == 0)\r
+            continue;\r
+\r
         float sf = getScale(scaleFactor_, firstLevel_, level);\r
 \r
-        GpuMat keyPointsRange = keypoints.colRange(offset, offset + keyPointsCount_[level]);        \r
-        \r
+        GpuMat keyPointsRange = keypoints.colRange(offset, offset + keyPointsCount_[level]);\r
+\r
         float locScale = level != firstLevel_ ? sf : 1.0f;\r
 \r
         mergeLocation_gpu(keyPointsPyr_[level].ptr<short2>(0), keyPointsRange.ptr<float>(0), keyPointsRange.ptr<float>(1), keyPointsCount_[level], locScale, 0);\r
 \r
         GpuMat range = keyPointsRange.rowRange(2, 4);\r
         keyPointsPyr_[level](Range(1, 3), Range(0, keyPointsCount_[level])).copyTo(range);\r
-        \r
+\r
         keyPointsRange.row(4).setTo(Scalar::all(level));\r
         keyPointsRange.row(5).setTo(Scalar::all(patchSize_ * sf));\r
 \r