From 029a8c443a761fde35d1e6c246e7177e3de193f2 Mon Sep 17 00:00:00 2001 From: Ievgen Khvedchenia Date: Sat, 10 May 2014 20:57:37 +0300 Subject: [PATCH] Remove GSURF descriptor from KAZE algorithm --- .../doc/feature_detection_and_description.rst | 19 +- modules/features2d/include/opencv2/features2d.hpp | 8 +- modules/features2d/src/features2d_init.cpp | 1 - modules/features2d/src/kaze.cpp | 11 +- modules/features2d/src/kaze/KAZEConfig.h | 4 +- modules/features2d/src/kaze/KAZEFeatures.cpp | 693 +-------------------- modules/features2d/test/test_keypoints.cpp | 7 +- 7 files changed, 25 insertions(+), 718 deletions(-) diff --git a/modules/features2d/doc/feature_detection_and_description.rst b/modules/features2d/doc/feature_detection_and_description.rst index c3029a3..fa18d4e 100644 --- a/modules/features2d/doc/feature_detection_and_description.rst +++ b/modules/features2d/doc/feature_detection_and_description.rst @@ -256,29 +256,12 @@ KAZE Class implementing the KAZE keypoint detector and descriptor extractor, described in [ABD12]_. :: - class CV_EXPORTS_W KAZE : public Feature2D - { - public: - - /// KAZE Descriptor Type - enum DESCRIPTOR_TYPE { - DESCRIPTOR_MSURF = 1, - DESCRIPTOR_GSURF = 2 - }; - - CV_WRAP KAZE(); - explicit KAZE(DESCRIPTOR_TYPE descriptor_type, bool extended, bool upright); - - .... - }; - KAZE::KAZE ---------- The KAZE constructor -.. ocv:function:: KAZE::KAZE(DESCRIPTOR_TYPE descriptor_type, bool extended, bool upright) +.. ocv:function:: KAZE::KAZE(bool extended, bool upright) - :param descriptor_type: Type of the extracted descriptor. :param extended: Set to enable extraction of extended (128-byte) descriptor. :param upright: Set to enable use of upright descriptors (non rotation-invariant). diff --git a/modules/features2d/include/opencv2/features2d.hpp b/modules/features2d/include/opencv2/features2d.hpp index 90a0477..73bc460 100644 --- a/modules/features2d/include/opencv2/features2d.hpp +++ b/modules/features2d/include/opencv2/features2d.hpp @@ -893,14 +893,8 @@ KAZE implementation class CV_EXPORTS_W KAZE : public Feature2D { public: - /// AKAZE Descriptor Type - enum DESCRIPTOR_TYPE { - DESCRIPTOR_MSURF = 1, - DESCRIPTOR_GSURF = 2 - }; - CV_WRAP KAZE(); - explicit KAZE(DESCRIPTOR_TYPE descriptor_type, bool extended, bool upright); + CV_WRAP explicit KAZE(bool extended, bool upright); virtual ~KAZE(); diff --git a/modules/features2d/src/features2d_init.cpp b/modules/features2d/src/features2d_init.cpp index c036527..eb71456 100644 --- a/modules/features2d/src/features2d_init.cpp +++ b/modules/features2d/src/features2d_init.cpp @@ -126,7 +126,6 @@ CV_INIT_ALGORITHM(GFTTDetector, "Feature2D.GFTT", /////////////////////////////////////////////////////////////////////////////////////////////////////////// CV_INIT_ALGORITHM(KAZE, "Feature2D.KAZE", - obj.info()->addParam(obj, "descriptor", obj.descriptor); obj.info()->addParam(obj, "upright", obj.upright); obj.info()->addParam(obj, "extended", obj.extended)) diff --git a/modules/features2d/src/kaze.cpp b/modules/features2d/src/kaze.cpp index 646ee4b..88fb999 100644 --- a/modules/features2d/src/kaze.cpp +++ b/modules/features2d/src/kaze.cpp @@ -53,15 +53,13 @@ http://www.robesafe.com/personal/pablo.alcantarilla/papers/Alcantarilla12eccv.pd namespace cv { KAZE::KAZE() - : descriptor(DESCRIPTOR_MSURF) - , extended(false) + : extended(false) , upright(false) { } - KAZE::KAZE(DESCRIPTOR_TYPE _descriptor_type, bool _extended, bool _upright) - : descriptor(_descriptor_type) - , extended(_extended) + KAZE::KAZE(bool _extended, bool _upright) + : extended(_extended) , upright(_upright) { @@ -111,7 +109,6 @@ namespace cv KAZEOptions options; options.img_width = img.cols; options.img_height = img.rows; - options.descriptor = static_cast(descriptor); options.extended = extended; options.upright = upright; @@ -146,7 +143,6 @@ namespace cv KAZEOptions options; options.img_width = img.cols; options.img_height = img.rows; - options.descriptor = static_cast(descriptor); options.extended = extended; options.upright = upright; @@ -174,7 +170,6 @@ namespace cv KAZEOptions options; options.img_width = img.cols; options.img_height = img.rows; - options.descriptor = static_cast(descriptor); options.extended = extended; options.upright = upright; diff --git a/modules/features2d/src/kaze/KAZEConfig.h b/modules/features2d/src/kaze/KAZEConfig.h index b0e397d..988e247 100644 --- a/modules/features2d/src/kaze/KAZEConfig.h +++ b/modules/features2d/src/kaze/KAZEConfig.h @@ -22,8 +22,7 @@ struct KAZEOptions { }; KAZEOptions() - : descriptor(cv::KAZE::DESCRIPTOR_MSURF) - , diffusivity(PM_G2) + : diffusivity(PM_G2) , soffset(1.60f) , omax(4) @@ -46,7 +45,6 @@ struct KAZEOptions { { } - cv::KAZE::DESCRIPTOR_TYPE descriptor; DIFFUSIVITY_TYPE diffusivity; float soffset; diff --git a/modules/features2d/src/kaze/KAZEFeatures.cpp b/modules/features2d/src/kaze/KAZEFeatures.cpp index 51e3a93..634f68d 100644 --- a/modules/features2d/src/kaze/KAZEFeatures.cpp +++ b/modules/features2d/src/kaze/KAZEFeatures.cpp @@ -500,10 +500,10 @@ void KAZEFeatures::Do_Subpixel_Refinement(std::vector &kpts) { //************************************************************************************* //************************************************************************************* -class MSURF_Descriptor_Invoker : public cv::ParallelLoopBody +class KAZE_Descriptor_Invoker : public cv::ParallelLoopBody { public: - MSURF_Descriptor_Invoker(std::vector &kpts, cv::Mat &desc, std::vector& evolution, const KAZEOptions& _options) + KAZE_Descriptor_Invoker(std::vector &kpts, cv::Mat &desc, std::vector& evolution, const KAZEOptions& _options) : _kpts(&kpts) , _desc(&desc) , _evolution(&evolution) @@ -511,7 +511,7 @@ public: { } - virtual ~MSURF_Descriptor_Invoker() + virtual ~KAZE_Descriptor_Invoker() { } @@ -528,82 +528,26 @@ public: { kpts[i].angle = 0.0; if (options.extended) - Get_MSURF_Upright_Descriptor_128(kpts[i], desc.ptr((int)i)); + Get_KAZE_Upright_Descriptor_128(kpts[i], desc.ptr((int)i)); else - Get_MSURF_Upright_Descriptor_64(kpts[i], desc.ptr((int)i)); + Get_KAZE_Upright_Descriptor_64(kpts[i], desc.ptr((int)i)); } else { KAZEFeatures::Compute_Main_Orientation(kpts[i], evolution, options); if (options.extended) - Get_MSURF_Descriptor_128(kpts[i], desc.ptr((int)i)); + Get_KAZE_Descriptor_128(kpts[i], desc.ptr((int)i)); else - Get_MSURF_Descriptor_64(kpts[i], desc.ptr((int)i)); + Get_KAZE_Descriptor_64(kpts[i], desc.ptr((int)i)); } } } private: - void Get_MSURF_Upright_Descriptor_64(const cv::KeyPoint& kpt, float* desc) const; - void Get_MSURF_Descriptor_64(const cv::KeyPoint& kpt, float* desc) const; - void Get_MSURF_Upright_Descriptor_128(const cv::KeyPoint& kpt, float* desc) const; - void Get_MSURF_Descriptor_128(const cv::KeyPoint& kpt, float *desc) const; - - std::vector * _kpts; - cv::Mat * _desc; - std::vector * _evolution; - KAZEOptions options; -}; - -class GSURF_Descriptor_Invoker : public cv::ParallelLoopBody -{ -public: - GSURF_Descriptor_Invoker(std::vector &kpts, cv::Mat &desc, std::vector& evolution, const KAZEOptions& _options) - : _kpts(&kpts) - , _desc(&desc) - , _evolution(&evolution) - , options(_options) - { - } - - virtual ~GSURF_Descriptor_Invoker() - { - } - - void operator() (const cv::Range& range) const - { - std::vector &kpts = *_kpts; - cv::Mat &desc = *_desc; - std::vector &evolution = *_evolution; - - for (int i = range.start; i < range.end; i++) - { - kpts[i].angle = 0.0; - if (options.upright) - { - kpts[i].angle = 0.0; - if (options.extended) - Get_GSURF_Upright_Descriptor_128(kpts[i], desc.ptr((int)i)); - else - Get_GSURF_Upright_Descriptor_64(kpts[i], desc.ptr((int)i)); - } - else - { - KAZEFeatures::Compute_Main_Orientation(kpts[i], evolution, options); - - if (options.extended) - Get_GSURF_Descriptor_128(kpts[i], desc.ptr((int)i)); - else - Get_GSURF_Descriptor_64(kpts[i], desc.ptr((int)i)); - } - } - } - -private: - void Get_GSURF_Upright_Descriptor_64(const cv::KeyPoint& kpt, float* desc) const; - void Get_GSURF_Descriptor_64(const cv::KeyPoint& kpt, float *desc) const; - void Get_GSURF_Upright_Descriptor_128(const cv::KeyPoint& kpt, float* desc) const; - void Get_GSURF_Descriptor_128(const cv::KeyPoint& kpt, float* desc) const; + void Get_KAZE_Upright_Descriptor_64(const cv::KeyPoint& kpt, float* desc) const; + void Get_KAZE_Descriptor_64(const cv::KeyPoint& kpt, float* desc) const; + void Get_KAZE_Upright_Descriptor_128(const cv::KeyPoint& kpt, float* desc) const; + void Get_KAZE_Descriptor_128(const cv::KeyPoint& kpt, float *desc) const; std::vector * _kpts; cv::Mat * _desc; @@ -626,16 +570,7 @@ void KAZEFeatures::Feature_Description(std::vector &kpts, cv::Mat desc = Mat::zeros((int)kpts.size(), 64, CV_32FC1); } - switch (options.descriptor) - { - case cv::KAZE::DESCRIPTOR_MSURF: - cv::parallel_for_(cv::Range(0, (int)kpts.size()), MSURF_Descriptor_Invoker(kpts, desc, evolution_, options)); - break; - - case cv::KAZE::DESCRIPTOR_GSURF: - cv::parallel_for_(cv::Range(0, (int)kpts.size()), GSURF_Descriptor_Invoker(kpts, desc, evolution_, options)); - break; - }; + cv::parallel_for_(cv::Range(0, (int)kpts.size()), KAZE_Descriptor_Invoker(kpts, desc, evolution_, options)); } //************************************************************************************* @@ -728,7 +663,7 @@ void KAZEFeatures::Compute_Main_Orientation(cv::KeyPoint &kpt, const std::vector * from Agrawal et al., CenSurE: Center Surround Extremas for Realtime Feature Detection and Matching, * ECCV 2008 */ -void MSURF_Descriptor_Invoker::Get_MSURF_Upright_Descriptor_64(const cv::KeyPoint &kpt, float *desc) const +void KAZE_Descriptor_Invoker::Get_KAZE_Upright_Descriptor_64(const cv::KeyPoint &kpt, float *desc) const { float dx = 0.0, dy = 0.0, mdx = 0.0, mdy = 0.0, gauss_s1 = 0.0, gauss_s2 = 0.0; float rx = 0.0, ry = 0.0, len = 0.0, xf = 0.0, yf = 0.0, ys = 0.0, xs = 0.0; @@ -862,7 +797,7 @@ void MSURF_Descriptor_Invoker::Get_MSURF_Upright_Descriptor_64(const cv::KeyPoin * from Agrawal et al., CenSurE: Center Surround Extremas for Realtime Feature Detection and Matching, * ECCV 2008 */ -void MSURF_Descriptor_Invoker::Get_MSURF_Descriptor_64(const cv::KeyPoint &kpt, float *desc) const +void KAZE_Descriptor_Invoker::Get_KAZE_Descriptor_64(const cv::KeyPoint &kpt, float *desc) const { float dx = 0.0, dy = 0.0, mdx = 0.0, mdy = 0.0, gauss_s1 = 0.0, gauss_s2 = 0.0; float rx = 0.0, ry = 0.0, rrx = 0.0, rry = 0.0, len = 0.0, xf = 0.0, yf = 0.0, ys = 0.0, xs = 0.0; @@ -989,284 +924,6 @@ void MSURF_Descriptor_Invoker::Get_MSURF_Descriptor_64(const cv::KeyPoint &kpt, //************************************************************************************* /** - * @brief This method computes the upright G-SURF descriptor of the provided keypoint - * given the main orientation - * @param kpt Input keypoint - * @param desc Descriptor vector - * @note Rectangular grid of 20 s x 20 s. Descriptor Length 64. No additional - * G-SURF descriptor as described in Pablo F. Alcantarilla, Luis M. Bergasa and - * Andrew J. Davison, Gauge-SURF Descriptors, Image and Vision Computing 31(1), 2013 - */ -void GSURF_Descriptor_Invoker::Get_GSURF_Upright_Descriptor_64(const cv::KeyPoint &kpt, float *desc) const -{ - float dx = 0.0, dy = 0.0, mdx = 0.0, mdy = 0.0; - float rx = 0.0, ry = 0.0, rxx = 0.0, rxy = 0.0, ryy = 0.0, len = 0.0, xf = 0.0, yf = 0.0; - float sample_x = 0.0, sample_y = 0.0; - float fx = 0.0, fy = 0.0, res1 = 0.0, res2 = 0.0, res3 = 0.0, res4 = 0.0; - float lvv = 0.0, lww = 0.0, modg = 0.0; - int x1 = 0, y1 = 0, x2 = 0, y2 = 0, sample_step = 0, pattern_size = 0, dcount = 0; - int dsize = 0, scale = 0, level = 0; - - std::vector& evolution_ = *_evolution; - - // Set the descriptor size and the sample and pattern sizes - dsize = 64; - sample_step = 5; - pattern_size = 10; - - // Get the information from the keypoint - yf = kpt.pt.y; - xf = kpt.pt.x; - scale = fRound(kpt.size / 2.0f); - level = kpt.class_id; - - // Calculate descriptor for this interest point - for (int i = -pattern_size; i < pattern_size; i += sample_step) { - for (int j = -pattern_size; j < pattern_size; j += sample_step) { - - dx = dy = mdx = mdy = 0.0; - - for (int k = i; k < i + sample_step; k++) { - for (int l = j; l < j + sample_step; l++) { - - // Get the coordinates of the sample point on the rotated axis - sample_y = yf + l*scale; - sample_x = xf + k*scale; - - y1 = (int)(sample_y - 0.5f); - x1 = (int)(sample_x - 0.5f); - - checkDescriptorLimits(x1, y1, options.img_width, options.img_height); - - y2 = (int)(sample_y + 0.5f); - x2 = (int)(sample_x + 0.5f); - - checkDescriptorLimits(x2, y2, options.img_width, options.img_height); - - fx = sample_x - x1; - fy = sample_y - y1; - - res1 = *(evolution_[level].Lx.ptr(y1)+x1); - res2 = *(evolution_[level].Lx.ptr(y1)+x2); - res3 = *(evolution_[level].Lx.ptr(y2)+x1); - res4 = *(evolution_[level].Lx.ptr(y2)+x2); - rx = (1.0f - fx)*(1.0f - fy)*res1 + fx*(1.0f - fy)*res2 + (1.0f - fx)*fy*res3 + fx*fy*res4; - - res1 = *(evolution_[level].Ly.ptr(y1)+x1); - res2 = *(evolution_[level].Ly.ptr(y1)+x2); - res3 = *(evolution_[level].Ly.ptr(y2)+x1); - res4 = *(evolution_[level].Ly.ptr(y2)+x2); - ry = (1.0f - fx)*(1.0f - fy)*res1 + fx*(1.0f - fy)*res2 + (1.0f - fx)*fy*res3 + fx*fy*res4; - - modg = pow(rx, 2) + pow(ry, 2); - - if (modg != 0.0) { - - res1 = *(evolution_[level].Lxx.ptr(y1)+x1); - res2 = *(evolution_[level].Lxx.ptr(y1)+x2); - res3 = *(evolution_[level].Lxx.ptr(y2)+x1); - res4 = *(evolution_[level].Lxx.ptr(y2)+x2); - rxx = (1.0f - fx)*(1.0f - fy)*res1 + fx*(1.0f - fy)*res2 + (1.0f - fx)*fy*res3 + fx*fy*res4; - - res1 = *(evolution_[level].Lxy.ptr(y1)+x1); - res2 = *(evolution_[level].Lxy.ptr(y1)+x2); - res3 = *(evolution_[level].Lxy.ptr(y2)+x1); - res4 = *(evolution_[level].Lxy.ptr(y2)+x2); - rxy = (1.0f - fx)*(1.0f - fy)*res1 + fx*(1.0f - fy)*res2 + (1.0f - fx)*fy*res3 + fx*fy*res4; - - res1 = *(evolution_[level].Lyy.ptr(y1)+x1); - res2 = *(evolution_[level].Lyy.ptr(y1)+x2); - res3 = *(evolution_[level].Lyy.ptr(y2)+x1); - res4 = *(evolution_[level].Lyy.ptr(y2)+x2); - ryy = (1.0f - fx)*(1.0f - fy)*res1 + fx*(1.0f - fy)*res2 + (1.0f - fx)*fy*res3 + fx*fy*res4; - - // Lww = (Lx^2 * Lxx + 2*Lx*Lxy*Ly + Ly^2*Lyy) / (Lx^2 + Ly^2) - lww = (pow(rx, 2)*rxx + 2.0f*rx*rxy*ry + pow(ry, 2)*ryy) / (modg); - - // Lvv = (-2*Lx*Lxy*Ly + Lxx*Ly^2 + Lx^2*Lyy) / (Lx^2 + Ly^2) - lvv = (-2.0f*rx*rxy*ry + rxx*pow(ry, 2) + pow(rx, 2)*ryy) / (modg); - } - else { - lww = 0.0; - lvv = 0.0; - } - - // Sum the derivatives to the cumulative descriptor - dx += lww; - dy += lvv; - mdx += fabs(lww); - mdy += fabs(lvv); - } - } - - // Add the values to the descriptor vector - desc[dcount++] = dx; - desc[dcount++] = dy; - desc[dcount++] = mdx; - desc[dcount++] = mdy; - - // Store the current length^2 of the vector - len += dx*dx + dy*dy + mdx*mdx + mdy*mdy; - } - } - - // convert to unit vector - len = sqrt(len); - - for (int i = 0; i < dsize; i++) { - desc[i] /= len; - } - - if (options.use_clipping_normalilzation) { - clippingDescriptor(desc, dsize, options.clipping_normalization_niter, options.clipping_normalization_ratio); - } -} - -//************************************************************************************* -//************************************************************************************* - -/** - * @brief This method computes the G-SURF descriptor of the provided keypoint given the - * main orientation - * @param kpt Input keypoint - * @param desc Descriptor vector - * @note Rectangular grid of 20 s x 20 s. Descriptor Length 64. No additional - * G-SURF descriptor as described in Pablo F. Alcantarilla, Luis M. Bergasa and - * Andrew J. Davison, Gauge-SURF Descriptors, Image and Vision Computing 31(1), 2013 - */ -void GSURF_Descriptor_Invoker::Get_GSURF_Descriptor_64(const cv::KeyPoint &kpt, float *desc) const -{ - float dx = 0.0, dy = 0.0, mdx = 0.0, mdy = 0.0; - float rx = 0.0, ry = 0.0, rxx = 0.0, rxy = 0.0, ryy = 0.0, len = 0.0, xf = 0.0, yf = 0.0; - float sample_x = 0.0, sample_y = 0.0, co = 0.0, si = 0.0, angle = 0.0; - float fx = 0.0, fy = 0.0, res1 = 0.0, res2 = 0.0, res3 = 0.0, res4 = 0.0; - float lvv = 0.0, lww = 0.0, modg = 0.0; - int x1 = 0, y1 = 0, x2 = 0, y2 = 0, sample_step = 0, pattern_size = 0, dcount = 0; - int dsize = 0, scale = 0, level = 0; - - std::vector& evolution_ = *_evolution; - - // Set the descriptor size and the sample and pattern sizes - dsize = 64; - sample_step = 5; - pattern_size = 10; - - // Get the information from the keypoint - yf = kpt.pt.y; - xf = kpt.pt.x; - scale = fRound(kpt.size / 2.0f); - angle = kpt.angle; - level = kpt.class_id; - co = cos(angle); - si = sin(angle); - - // Calculate descriptor for this interest point - for (int i = -pattern_size; i < pattern_size; i += sample_step) { - for (int j = -pattern_size; j < pattern_size; j += sample_step) { - - dx = dy = mdx = mdy = 0.0; - - for (int k = i; k < i + sample_step; k++) { - for (int l = j; l < j + sample_step; l++) { - - // Get the coordinates of the sample point on the rotated axis - sample_y = yf + (l*scale*co + k*scale*si); - sample_x = xf + (-l*scale*si + k*scale*co); - - y1 = (int)(sample_y - 0.5f); - x1 = (int)(sample_x - 0.5f); - - checkDescriptorLimits(x1, y1, options.img_width, options.img_height); - - y2 = (int)(sample_y + 0.5f); - x2 = (int)(sample_x + 0.5f); - - checkDescriptorLimits(x2, y2, options.img_width, options.img_height); - - fx = sample_x - x1; - fy = sample_y - y1; - - res1 = *(evolution_[level].Lx.ptr(y1)+x1); - res2 = *(evolution_[level].Lx.ptr(y1)+x2); - res3 = *(evolution_[level].Lx.ptr(y2)+x1); - res4 = *(evolution_[level].Lx.ptr(y2)+x2); - rx = (1.0f - fx)*(1.0f - fy)*res1 + fx*(1.0f - fy)*res2 + (1.0f - fx)*fy*res3 + fx*fy*res4; - - res1 = *(evolution_[level].Ly.ptr(y1)+x1); - res2 = *(evolution_[level].Ly.ptr(y1)+x2); - res3 = *(evolution_[level].Ly.ptr(y2)+x1); - res4 = *(evolution_[level].Ly.ptr(y2)+x2); - ry = (1.0f - fx)*(1.0f - fy)*res1 + fx*(1.0f - fy)*res2 + (1.0f - fx)*fy*res3 + fx*fy*res4; - - modg = pow(rx, 2) + pow(ry, 2); - - if (modg != 0.0) { - - res1 = *(evolution_[level].Lxx.ptr(y1)+x1); - res2 = *(evolution_[level].Lxx.ptr(y1)+x2); - res3 = *(evolution_[level].Lxx.ptr(y2)+x1); - res4 = *(evolution_[level].Lxx.ptr(y2)+x2); - rxx = (1.0f - fx)*(1.0f - fy)*res1 + fx*(1.0f - fy)*res2 + (1.0f - fx)*fy*res3 + fx*fy*res4; - - res1 = *(evolution_[level].Lxy.ptr(y1)+x1); - res2 = *(evolution_[level].Lxy.ptr(y1)+x2); - res3 = *(evolution_[level].Lxy.ptr(y2)+x1); - res4 = *(evolution_[level].Lxy.ptr(y2)+x2); - rxy = (1.0f - fx)*(1.0f - fy)*res1 + fx*(1.0f - fy)*res2 + (1.0f - fx)*fy*res3 + fx*fy*res4; - - res1 = *(evolution_[level].Lyy.ptr(y1)+x1); - res2 = *(evolution_[level].Lyy.ptr(y1)+x2); - res3 = *(evolution_[level].Lyy.ptr(y2)+x1); - res4 = *(evolution_[level].Lyy.ptr(y2)+x2); - ryy = (1.0f - fx)*(1.0f - fy)*res1 + fx*(1.0f - fy)*res2 + (1.0f - fx)*fy*res3 + fx*fy*res4; - - // Lww = (Lx^2 * Lxx + 2*Lx*Lxy*Ly + Ly^2*Lyy) / (Lx^2 + Ly^2) - lww = (pow(rx, 2)*rxx + 2.0f*rx*rxy*ry + pow(ry, 2)*ryy) / (modg); - - // Lvv = (-2*Lx*Lxy*Ly + Lxx*Ly^2 + Lx^2*Lyy) / (Lx^2 + Ly^2) - lvv = (-2.0f*rx*rxy*ry + rxx*pow(ry, 2) + pow(rx, 2)*ryy) / (modg); - } - else { - lww = 0.0; - lvv = 0.0; - } - - // Sum the derivatives to the cumulative descriptor - dx += lww; - dy += lvv; - mdx += fabs(lww); - mdy += fabs(lvv); - } - } - - // Add the values to the descriptor vector - desc[dcount++] = dx; - desc[dcount++] = dy; - desc[dcount++] = mdx; - desc[dcount++] = mdy; - - // Store the current length^2 of the vector - len += dx*dx + dy*dy + mdx*mdx + mdy*mdy; - } - } - - // convert to unit vector - len = sqrt(len); - - for (int i = 0; i < dsize; i++) { - desc[i] /= len; - } - - if (options.use_clipping_normalilzation) { - clippingDescriptor(desc, dsize, options.clipping_normalization_niter, options.clipping_normalization_ratio); - } - -} - -//************************************************************************************* -//************************************************************************************* - -/** * @brief This method computes the extended upright descriptor (not rotation invariant) of * the provided keypoint * @param kpt Input keypoint @@ -1275,7 +932,7 @@ void GSURF_Descriptor_Invoker::Get_GSURF_Descriptor_64(const cv::KeyPoint &kpt, * from Agrawal et al., CenSurE: Center Surround Extremas for Realtime Feature Detection and Matching, * ECCV 2008 */ -void MSURF_Descriptor_Invoker::Get_MSURF_Upright_Descriptor_128(const cv::KeyPoint &kpt, float *desc) const +void KAZE_Descriptor_Invoker::Get_KAZE_Upright_Descriptor_128(const cv::KeyPoint &kpt, float *desc) const { float gauss_s1 = 0.0, gauss_s2 = 0.0; float rx = 0.0, ry = 0.0, len = 0.0, xf = 0.0, yf = 0.0, ys = 0.0, xs = 0.0; @@ -1433,7 +1090,7 @@ void MSURF_Descriptor_Invoker::Get_MSURF_Upright_Descriptor_128(const cv::KeyPoi * from Agrawal et al., CenSurE: Center Surround Extremas for Realtime Feature Detection and Matching, * ECCV 2008 */ -void MSURF_Descriptor_Invoker::Get_MSURF_Descriptor_128(const cv::KeyPoint &kpt, float *desc) const +void KAZE_Descriptor_Invoker::Get_KAZE_Descriptor_128(const cv::KeyPoint &kpt, float *desc) const { float gauss_s1 = 0.0, gauss_s2 = 0.0; float rx = 0.0, ry = 0.0, rrx = 0.0, rry = 0.0, len = 0.0, xf = 0.0, yf = 0.0, ys = 0.0, xs = 0.0; @@ -1588,322 +1245,6 @@ void MSURF_Descriptor_Invoker::Get_MSURF_Descriptor_128(const cv::KeyPoint &kpt, //************************************************************************************* /** - * @brief This method computes the G-SURF upright extended descriptor - * (no rotation invariant) of the provided keypoint - * @param kpt Input keypoint - * @param desc Descriptor vector - * @note Rectangular grid of 20 s x 20 s. Descriptor Length 128. No additional - * G-SURF descriptor as described in Pablo F. Alcantarilla, Luis M. Bergasa and - * Andrew J. Davison, Gauge-SURF Descriptors, Image and Vision Computing 31(1), 2013 - */ -void GSURF_Descriptor_Invoker::Get_GSURF_Upright_Descriptor_128(const cv::KeyPoint &kpt, float *desc) const -{ - float len = 0.0, xf = 0.0, yf = 0.0, sample_x = 0.0, sample_y = 0.0; - float rx = 0.0, ry = 0.0, rxx = 0.0, rxy = 0.0, ryy = 0.0, modg = 0.0; - float fx = 0.0, fy = 0.0, res1 = 0.0, res2 = 0.0, res3 = 0.0, res4 = 0.0; - float dxp = 0.0, dyp = 0.0, mdxp = 0.0, mdyp = 0.0; - float dxn = 0.0, dyn = 0.0, mdxn = 0.0, mdyn = 0.0, lvv = 0.0, lww = 0.0; - int x1 = 0, y1 = 0, x2 = 0, y2 = 0, sample_step = 0, pattern_size = 0, dcount = 0; - int dsize = 0, scale = 0, level = 0; - - std::vector& evolution_ = *_evolution; - - // Set the descriptor size and the sample and pattern sizes - dsize = 128; - sample_step = 5; - pattern_size = 10; - - // Get the information from the keypoint - yf = kpt.pt.y; - xf = kpt.pt.x; - scale = fRound(kpt.size / 2.0f); - level = kpt.class_id; - - // Calculate descriptor for this interest point - for (int i = -pattern_size; i < pattern_size; i += sample_step) { - for (int j = -pattern_size; j < pattern_size; j += sample_step) { - - dxp = dxn = mdxp = mdxn = 0.0; - dyp = dyn = mdyp = mdyn = 0.0; - - for (int k = i; k < i + sample_step; k++) { - for (int l = j; l < j + sample_step; l++) { - - sample_y = k*scale + yf; - sample_x = l*scale + xf; - - y1 = (int)(sample_y - 0.5f); - x1 = (int)(sample_x - 0.5f); - - checkDescriptorLimits(x1, y1, options.img_width, options.img_height); - - y2 = (int)(sample_y + 0.5f); - x2 = (int)(sample_x + 0.5f); - - checkDescriptorLimits(x2, y2, options.img_width, options.img_height); - - fx = sample_x - x1; - fy = sample_y - y1; - - res1 = *(evolution_[level].Lx.ptr(y1)+x1); - res2 = *(evolution_[level].Lx.ptr(y1)+x2); - res3 = *(evolution_[level].Lx.ptr(y2)+x1); - res4 = *(evolution_[level].Lx.ptr(y2)+x2); - rx = (1.0f - fx)*(1.0f - fy)*res1 + fx*(1.0f - fy)*res2 + (1.0f - fx)*fy*res3 + fx*fy*res4; - - res1 = *(evolution_[level].Ly.ptr(y1)+x1); - res2 = *(evolution_[level].Ly.ptr(y1)+x2); - res3 = *(evolution_[level].Ly.ptr(y2)+x1); - res4 = *(evolution_[level].Ly.ptr(y2)+x2); - ry = (1.0f - fx)*(1.0f - fy)*res1 + fx*(1.0f - fy)*res2 + (1.0f - fx)*fy*res3 + fx*fy*res4; - - modg = pow(rx, 2) + pow(ry, 2); - - if (modg != 0.0) { - - res1 = *(evolution_[level].Lxx.ptr(y1)+x1); - res2 = *(evolution_[level].Lxx.ptr(y1)+x2); - res3 = *(evolution_[level].Lxx.ptr(y2)+x1); - res4 = *(evolution_[level].Lxx.ptr(y2)+x2); - rxx = (1.0f - fx)*(1.0f - fy)*res1 + fx*(1.0f - fy)*res2 + (1.0f - fx)*fy*res3 + fx*fy*res4; - - res1 = *(evolution_[level].Lxy.ptr(y1)+x1); - res2 = *(evolution_[level].Lxy.ptr(y1)+x2); - res3 = *(evolution_[level].Lxy.ptr(y2)+x1); - res4 = *(evolution_[level].Lxy.ptr(y2)+x2); - rxy = (1.0f - fx)*(1.0f - fy)*res1 + fx*(1.0f - fy)*res2 + (1.0f - fx)*fy*res3 + fx*fy*res4; - - res1 = *(evolution_[level].Lyy.ptr(y1)+x1); - res2 = *(evolution_[level].Lyy.ptr(y1)+x2); - res3 = *(evolution_[level].Lyy.ptr(y2)+x1); - res4 = *(evolution_[level].Lyy.ptr(y2)+x2); - ryy = (1.0f - fx)*(1.0f - fy)*res1 + fx*(1.0f - fy)*res2 + (1.0f - fx)*fy*res3 + fx*fy*res4; - - // Lww = (Lx^2 * Lxx + 2*Lx*Lxy*Ly + Ly^2*Lyy) / (Lx^2 + Ly^2) - lww = (pow(rx, 2)*rxx + 2.0f*rx*rxy*ry + pow(ry, 2)*ryy) / (modg); - - // Lvv = (-2*Lx*Lxy*Ly + Lxx*Ly^2 + Lx^2*Lyy) / (Lx^2 + Ly^2) - lvv = (-2.0f*rx*rxy*ry + rxx*pow(ry, 2) + pow(rx, 2)*ryy) / (modg); - } - else { - lww = 0.0; - lvv = 0.0; - } - - // Sum the derivatives to the cumulative descriptor - if (lww >= 0.0) { - dxp += lvv; - mdxp += fabs(lvv); - } - else { - dxn += lvv; - mdxn += fabs(lvv); - } - - if (lvv >= 0.0) { - dyp += lww; - mdyp += fabs(lww); - } - else { - dyn += lww; - mdyn += fabs(lww); - } - } - } - - // Add the values to the descriptor vector - desc[dcount++] = dxp; - desc[dcount++] = dxn; - desc[dcount++] = mdxp; - desc[dcount++] = mdxn; - desc[dcount++] = dyp; - desc[dcount++] = dyn; - desc[dcount++] = mdyp; - desc[dcount++] = mdyn; - - // Store the current length^2 of the vector - len += dxp*dxp + dxn*dxn + mdxp*mdxp + mdxn*mdxn + - dyp*dyp + dyn*dyn + mdyp*mdyp + mdyn*mdyn; - } - } - - // convert to unit vector - len = sqrt(len); - - for (int i = 0; i < dsize; i++) { - desc[i] /= len; - } - - if (options.use_clipping_normalilzation) { - clippingDescriptor(desc, dsize, options.clipping_normalization_niter, options.clipping_normalization_ratio); - } -} - -//************************************************************************************* -//************************************************************************************* - -/** - * @brief This method computes the extended descriptor of the provided keypoint given the - * main orientation - * @param kpt Input keypoint - * @param desc Descriptor vector - * @note Rectangular grid of 20 s x 20 s. Descriptor Length 128. No additional - * G-SURF descriptor as described in Pablo F. Alcantarilla, Luis M. Bergasa and - * Andrew J. Davison, Gauge-SURF Descriptors, Image and Vision Computing 31(1), 2013 - */ -void GSURF_Descriptor_Invoker::Get_GSURF_Descriptor_128(const cv::KeyPoint &kpt, float *desc) const -{ - - float len = 0.0, xf = 0.0, yf = 0.0; - float rx = 0.0, ry = 0.0, rxx = 0.0, rxy = 0.0, ryy = 0.0; - float sample_x = 0.0, sample_y = 0.0, co = 0.0, si = 0.0, angle = 0.0; - float fx = 0.0, fy = 0.0, res1 = 0.0, res2 = 0.0, res3 = 0.0, res4 = 0.0; - float dxp = 0.0, dyp = 0.0, mdxp = 0.0, mdyp = 0.0; - float dxn = 0.0, dyn = 0.0, mdxn = 0.0, mdyn = 0.0; - float lvv = 0.0, lww = 0.0, modg = 0.0; - int x1 = 0, y1 = 0, x2 = 0, y2 = 0, sample_step = 0, pattern_size = 0, dcount = 0; - int dsize = 0, scale = 0, level = 0; - - std::vector& evolution_ = *_evolution; - - // Set the descriptor size and the sample and pattern sizes - dsize = 128; - sample_step = 5; - pattern_size = 10; - - // Get the information from the keypoint - yf = kpt.pt.y; - xf = kpt.pt.x; - scale = fRound(kpt.size / 2.0f); - angle = kpt.angle; - level = kpt.class_id; - co = cos(angle); - si = sin(angle); - - // Calculate descriptor for this interest point - for (int i = -pattern_size; i < pattern_size; i += sample_step) { - for (int j = -pattern_size; j < pattern_size; j += sample_step) { - - dxp = dxn = mdxp = mdxn = 0.0; - dyp = dyn = mdyp = mdyn = 0.0; - - for (int k = i; k < i + sample_step; k++) { - for (int l = j; l < j + sample_step; l++) { - - // Get the coordinates of the sample point on the rotated axis - sample_y = yf + (l*scale*co + k*scale*si); - sample_x = xf + (-l*scale*si + k*scale*co); - - y1 = (int)(sample_y - 0.5f); - x1 = (int)(sample_x - 0.5f); - - checkDescriptorLimits(x1, y1, options.img_width, options.img_height); - - y2 = (int)(sample_y + 0.5f); - x2 = (int)(sample_x + 0.5f); - - checkDescriptorLimits(x2, y2, options.img_width, options.img_height); - - fx = sample_x - x1; - fy = sample_y - y1; - - res1 = *(evolution_[level].Lx.ptr(y1)+x1); - res2 = *(evolution_[level].Lx.ptr(y1)+x2); - res3 = *(evolution_[level].Lx.ptr(y2)+x1); - res4 = *(evolution_[level].Lx.ptr(y2)+x2); - rx = (1.0f - fx)*(1.0f - fy)*res1 + fx*(1.0f - fy)*res2 + (1.0f - fx)*fy*res3 + fx*fy*res4; - - res1 = *(evolution_[level].Ly.ptr(y1)+x1); - res2 = *(evolution_[level].Ly.ptr(y1)+x2); - res3 = *(evolution_[level].Ly.ptr(y2)+x1); - res4 = *(evolution_[level].Ly.ptr(y2)+x2); - ry = (1.0f - fx)*(1.0f - fy)*res1 + fx*(1.0f - fy)*res2 + (1.0f - fx)*fy*res3 + fx*fy*res4; - - modg = pow(rx, 2) + pow(ry, 2); - - if (modg != 0.0) { - res1 = *(evolution_[level].Lxx.ptr(y1)+x1); - res2 = *(evolution_[level].Lxx.ptr(y1)+x2); - res3 = *(evolution_[level].Lxx.ptr(y2)+x1); - res4 = *(evolution_[level].Lxx.ptr(y2)+x2); - rxx = (1.0f - fx)*(1.0f - fy)*res1 + fx*(1.0f - fy)*res2 + (1.0f - fx)*fy*res3 + fx*fy*res4; - - res1 = *(evolution_[level].Lxy.ptr(y1)+x1); - res2 = *(evolution_[level].Lxy.ptr(y1)+x2); - res3 = *(evolution_[level].Lxy.ptr(y2)+x1); - res4 = *(evolution_[level].Lxy.ptr(y2)+x2); - rxy = (1.0f - fx)*(1.0f - fy)*res1 + fx*(1.0f - fy)*res2 + (1.0f - fx)*fy*res3 + fx*fy*res4; - - res1 = *(evolution_[level].Lyy.ptr(y1)+x1); - res2 = *(evolution_[level].Lyy.ptr(y1)+x2); - res3 = *(evolution_[level].Lyy.ptr(y2)+x1); - res4 = *(evolution_[level].Lyy.ptr(y2)+x2); - ryy = (1.0f - fx)*(1.0f - fy)*res1 + fx*(1.0f - fy)*res2 + (1.0f - fx)*fy*res3 + fx*fy*res4; - - // Lww = (Lx^2 * Lxx + 2*Lx*Lxy*Ly + Ly^2*Lyy) / (Lx^2 + Ly^2) - lww = (pow(rx, 2)*rxx + 2.0f*rx*rxy*ry + pow(ry, 2)*ryy) / (modg); - - // Lvv = (-2*Lx*Lxy*Ly + Lxx*Ly^2 + Lx^2*Lyy) / (Lx^2 + Ly^2) - lvv = (-2.0f*rx*rxy*ry + rxx*pow(ry, 2) + pow(rx, 2)*ryy) / (modg); - } - else { - lww = 0.0; - lvv = 0.0; - } - - // Sum the derivatives to the cumulative descriptor - if (lww >= 0.0) { - dxp += lvv; - mdxp += fabs(lvv); - } - else { - dxn += lvv; - mdxn += fabs(lvv); - } - - if (lvv >= 0.0) { - dyp += lww; - mdyp += fabs(lww); - } - else { - dyn += lww; - mdyn += fabs(lww); - } - } - } - - // Add the values to the descriptor vector - desc[dcount++] = dxp; - desc[dcount++] = dxn; - desc[dcount++] = mdxp; - desc[dcount++] = mdxn; - desc[dcount++] = dyp; - desc[dcount++] = dyn; - desc[dcount++] = mdyp; - desc[dcount++] = mdyn; - - // Store the current length^2 of the vector - len += dxp*dxp + dxn*dxn + mdxp*mdxp + mdxn*mdxn + - dyp*dyp + dyn*dyn + mdyp*mdyp + mdyn*mdyn; - } - } - - // convert to unit vector - len = sqrt(len); - - for (int i = 0; i < dsize; i++) { - desc[i] /= len; - } - - if (options.use_clipping_normalilzation) { - clippingDescriptor(desc, dsize, options.clipping_normalization_niter, options.clipping_normalization_ratio); - } -} - -//************************************************************************************* -//************************************************************************************* - -/** * @brief This method performs a scalar non-linear diffusion step using AOS schemes * @param Ld Image at a given evolution step * @param Ldprev Image at a previous evolution step @@ -1911,7 +1252,7 @@ void GSURF_Descriptor_Invoker::Get_GSURF_Descriptor_128(const cv::KeyPoint &kpt, * @param stepsize Stepsize for the nonlinear diffusion evolution * @note If c is constant, the diffusion will be linear * If c is a matrix of the same size as Ld, the diffusion will be nonlinear - * The stepsize can be arbitrarilly large + * The stepsize can be arbitrarily large */ void KAZEFeatures::AOS_Step_Scalar(cv::Mat &Ld, const cv::Mat &Ldprev, const cv::Mat &c, const float& stepsize) { diff --git a/modules/features2d/test/test_keypoints.cpp b/modules/features2d/test/test_keypoints.cpp index a14a9dd..2a7f24e 100644 --- a/modules/features2d/test/test_keypoints.cpp +++ b/modules/features2d/test/test_keypoints.cpp @@ -169,11 +169,8 @@ TEST(Features2d_Detector_Keypoints_Dense, validation) TEST(Features2d_Detector_Keypoints_KAZE, validation) { - CV_FeatureDetectorKeypointsTest test_gsurf(cv::Ptr(new cv::KAZE(cv::KAZE::DESCRIPTOR_GSURF, false, false))); - test_gsurf.safe_run(); - - CV_FeatureDetectorKeypointsTest test_msurf(cv::Ptr(new cv::KAZE(cv::KAZE::DESCRIPTOR_MSURF, false, false))); - test_msurf.safe_run(); + CV_FeatureDetectorKeypointsTest test(Algorithm::create("Feature2D.KAZE")); + test.safe_run(); } TEST(Features2d_Detector_Keypoints_AKAZE, validation) -- 2.7.4