From 205022ceee2ad9a7fa3f77b5fc0bfd8457a36f2a Mon Sep 17 00:00:00 2001 From: Vitaly Tuzov Date: Thu, 25 Jan 2018 15:23:59 +0300 Subject: [PATCH] Fixed issue in ORB detection if firstLevel property is set above 0 --- modules/features2d/include/opencv2/features2d.hpp | 5 +++-- modules/features2d/src/orb.cpp | 12 ++++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/modules/features2d/include/opencv2/features2d.hpp b/modules/features2d/include/opencv2/features2d.hpp index 82d76c40a3..6a3405f23c 100644 --- a/modules/features2d/include/opencv2/features2d.hpp +++ b/modules/features2d/include/opencv2/features2d.hpp @@ -304,10 +304,11 @@ public: will mean that to cover certain scale range you will need more pyramid levels and so the speed will suffer. @param nlevels The number of pyramid levels. The smallest level will have linear size equal to - input_image_linear_size/pow(scaleFactor, nlevels). + input_image_linear_size/pow(scaleFactor, nlevels - firstLevel). @param edgeThreshold This is size of the border where the features are not detected. It should roughly match the patchSize parameter. - @param firstLevel It should be 0 in the current implementation. + @param firstLevel The level of pytramid to put source image to. Previous layers are filled + with upscaled source image. @param WTA_K The number of points that produce each element of the oriented BRIEF descriptor. The default value 2 means the BRIEF where we take a random point pair and compare their brightnesses, so we get 0/1 response. Other possible values are 3 and 4. For example, 3 means that we take 3 diff --git a/modules/features2d/src/orb.cpp b/modules/features2d/src/orb.cpp index 899d173acf..6a4fad7fdf 100644 --- a/modules/features2d/src/orb.cpp +++ b/modules/features2d/src/orb.cpp @@ -673,7 +673,7 @@ public: void setEdgeThreshold(int edgeThreshold_) { edgeThreshold = edgeThreshold_; } int getEdgeThreshold() const { return edgeThreshold; } - void setFirstLevel(int firstLevel_) { firstLevel = firstLevel_; } + void setFirstLevel(int firstLevel_) { CV_Assert(firstLevel >= 0); firstLevel = firstLevel_; } int getFirstLevel() const { return firstLevel; } void setWTA_K(int wta_k_) { wta_k = wta_k_; } @@ -1014,7 +1014,7 @@ void ORB_Impl::detectAndCompute( InputArray _image, InputArray _mask, int level_dy = image.rows + border*2; Point level_ofs(0,0); - Size bufSize((image.cols + border*2 + 15) & -16, 0); + Size bufSize((cvRound(image.cols/getScale(0, firstLevel, scaleFactor)) + border*2 + 15) & -16, 0); for( level = 0; level < nLevels; level++ ) { @@ -1082,8 +1082,11 @@ void ORB_Impl::detectAndCompute( InputArray _image, InputArray _mask, copyMakeBorder(mask, extMask, border, border, border, border, BORDER_CONSTANT+BORDER_ISOLATED); } - prevImg = currImg; - prevMask = currMask; + if (level > firstLevel) + { + prevImg = currImg; + prevMask = currMask; + } } if( useOCL ) @@ -1194,6 +1197,7 @@ void ORB_Impl::detectAndCompute( InputArray _image, InputArray _mask, Ptr ORB::create(int nfeatures, float scaleFactor, int nlevels, int edgeThreshold, int firstLevel, int wta_k, int scoreType, int patchSize, int fastThreshold) { + CV_Assert(firstLevel >= 0); return makePtr(nfeatures, scaleFactor, nlevels, edgeThreshold, firstLevel, wta_k, scoreType, patchSize, fastThreshold); }