-
Notifications
You must be signed in to change notification settings - Fork 5.9k
Add BAD descriptor to xfeatures2d module #3277
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
c06a527
530ccb0
5bfc751
309d91f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| // This file is part of OpenCV project. | ||
| // It is subject to the license terms in the LICENSE file found in the top-level directory | ||
| // of this distribution and at http://opencv.org/license.html. | ||
| #include "perf_precomp.hpp" | ||
|
|
||
| namespace opencv_test { namespace { | ||
|
|
||
| typedef perf::TestBaseWithParam<std::string> teblid; | ||
|
|
||
| #define TEBLID_IMAGES \ | ||
| "cv/detectors_descriptors_evaluation/images_datasets/leuven/img1.png",\ | ||
| "stitching/a3.png" | ||
|
|
||
| #ifdef OPENCV_ENABLE_NONFREE | ||
| PERF_TEST_P(teblid, extract, testing::Values(TEBLID_IMAGES)) | ||
| { | ||
| string filename = getDataPath(GetParam()); | ||
| Mat frame = imread(filename, IMREAD_GRAYSCALE); | ||
| ASSERT_FALSE(frame.empty()) << "Unable to load source image " << filename; | ||
|
|
||
| Mat mask; | ||
| declare.in(frame).time(90); | ||
|
|
||
| Ptr<SURF> detector = SURF::create(); | ||
| vector<KeyPoint> points; | ||
| detector->detect(frame, points, mask); | ||
|
|
||
| Ptr<TEBLID> descriptor = TEBLID::create(6.25f); | ||
| cv::Mat descriptors; | ||
| TEST_CYCLE() descriptor->compute(frame, points, descriptors); | ||
|
|
||
| SANITY_CHECK_NOTHING(); | ||
| } | ||
| #endif // NONFREE | ||
|
|
||
| }} // namespace |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -30,8 +30,15 @@ struct ABWLParams | |
| { | ||
| int x1, y1, x2, y2, boxRadius, th; | ||
| }; | ||
| // Same as previous with floating point threshold | ||
| struct ABWLParamsFloatTh | ||
| { | ||
| int x1, y1, x2, y2, boxRadius; | ||
| float th; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should keep integer-based computation of original BEBLID. Could you please add separate struct type with floats? (and change BEBLID computation to use params from template type)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you very much @alalek for your feedback. You are right. It is a better idea to preserve the original structure for BEBLID. In my last commit, I added a new ABWLParamsFloatTh for the new descriptor and undo the changes to the original ABWLParams. I also made BEBLID_Impl a templated class that can be used with both structs. |
||
| }; | ||
|
|
||
| // BEBLID implementation | ||
| template <class WeakLearnerT> | ||
| class BEBLID_Impl CV_FINAL: public BEBLID | ||
| { | ||
| public: | ||
|
|
@@ -55,15 +62,51 @@ class BEBLID_Impl CV_FINAL: public BEBLID | |
| void compute(InputArray image, vector<KeyPoint> &keypoints, OutputArray descriptors) CV_OVERRIDE; | ||
|
|
||
| private: | ||
| std::vector<ABWLParams> wl_params_; | ||
| std::vector<WeakLearnerT> wl_params_; | ||
| float scale_factor_; | ||
| cv::Size patch_size_; | ||
|
|
||
| void computeBEBLID(const cv::Mat &integralImg, | ||
| const std::vector<cv::KeyPoint> &keypoints, | ||
| cv::Mat &descriptors); | ||
| void computeBoxDiffsDescriptor(const cv::Mat &integralImg, | ||
| const std::vector<cv::KeyPoint> &keypoints, | ||
| cv::Mat &descriptors); | ||
| }; // END BEBLID_Impl CLASS | ||
|
|
||
|
|
||
| // TEBLID implementation | ||
| class TEBLID_Impl CV_FINAL: public TEBLID | ||
| { | ||
| public: | ||
|
|
||
| // constructor | ||
| explicit TEBLID_Impl(float scale_factor, int n_bits = TEBLID::SIZE_256_BITS) : impl(scale_factor, n_bits){} | ||
|
|
||
| // destructor | ||
| ~TEBLID_Impl() CV_OVERRIDE = default; | ||
|
|
||
| // returns the descriptor length in bytes | ||
| int descriptorSize() const CV_OVERRIDE { return impl.descriptorSize(); } | ||
|
|
||
| // returns the descriptor type | ||
| int descriptorType() const CV_OVERRIDE { return impl.descriptorType(); } | ||
|
|
||
| // returns the default norm type | ||
| int defaultNorm() const CV_OVERRIDE { return impl.defaultNorm(); } | ||
|
|
||
| // compute descriptors given keypoints | ||
| void compute(InputArray image, vector<KeyPoint> &keypoints, OutputArray descriptors) CV_OVERRIDE | ||
| { | ||
| impl.compute(image, keypoints, descriptors); | ||
| } | ||
|
|
||
| private: | ||
| BEBLID_Impl<ABWLParamsFloatTh> impl; | ||
| }; // END TEBLID_Impl CLASS | ||
|
|
||
| Ptr<TEBLID> TEBLID::create(float scale_factor, int n_bits) | ||
| { | ||
| return makePtr<TEBLID_Impl>(scale_factor, n_bits); | ||
| } | ||
|
|
||
| /** | ||
| * @brief Function that determines if a keypoint is close to the image border. | ||
| * @param kp The detected keypoint | ||
|
|
@@ -100,8 +143,9 @@ static inline bool isKeypointInTheBorder(const cv::KeyPoint &kp, | |
| * @param scaleFactor A scale factor that magnifies the measurement functions w.r.t. the keypoint. | ||
| * @param patchSize The size of the normalized patch where the measurement functions were learnt. | ||
| */ | ||
| static inline void rectifyABWL(const std::vector<ABWLParams> &wlPatchParams, | ||
| std::vector<ABWLParams> &wlImageParams, | ||
| template< typename WeakLearnerT> | ||
| static inline void rectifyABWL(const std::vector<WeakLearnerT> &wlPatchParams, | ||
| std::vector<WeakLearnerT> &wlImageParams, | ||
| const cv::KeyPoint &kp, | ||
| float scaleFactor = 1, | ||
| const cv::Size &patchSize = cv::Size(32, 32)) | ||
|
|
@@ -151,7 +195,8 @@ static inline void rectifyABWL(const std::vector<ABWLParams> &wlPatchParams, | |
| * @param integralImage The integral image used to compute the average gray value in the square regions. | ||
| * @return The difference of gray level in the two squares defined by wlImageParams | ||
| */ | ||
| static inline float computeABWLResponse(const ABWLParams &wlImageParams, | ||
| template <typename WeakLearnerT> | ||
| static inline float computeABWLResponse(const WeakLearnerT &wlImageParams, | ||
| const cv::Mat &integralImage) | ||
| { | ||
| CV_DbgAssert(!integralImage.empty()); | ||
|
|
@@ -239,7 +284,8 @@ static inline float computeABWLResponse(const ABWLParams &wlImageParams, | |
| } | ||
|
|
||
| // descriptor computation using keypoints | ||
| void BEBLID_Impl::compute(InputArray _image, vector<KeyPoint> &keypoints, OutputArray _descriptors) | ||
| template <class WeakLearnerT> | ||
| void BEBLID_Impl<WeakLearnerT>::compute(InputArray _image, vector<KeyPoint> &keypoints, OutputArray _descriptors) | ||
| { | ||
| Mat image = _image.getMat(); | ||
|
|
||
|
|
@@ -281,27 +327,54 @@ void BEBLID_Impl::compute(InputArray _image, vector<KeyPoint> &keypoints, Output | |
| CV_DbgAssert(descriptors.type() == CV_8UC1); | ||
|
|
||
| // Compute the BEBLID descriptors | ||
| computeBEBLID(integralImg, keypoints, descriptors); | ||
| computeBoxDiffsDescriptor(integralImg, keypoints, descriptors); | ||
| } | ||
|
|
||
| // constructor | ||
| BEBLID_Impl::BEBLID_Impl(float scale_factor, int n_bits) | ||
| template <class WeakLearnerT> | ||
| BEBLID_Impl<WeakLearnerT>::BEBLID_Impl(float scale_factor, int n_bits) | ||
| : scale_factor_(scale_factor), patch_size_(32, 32) | ||
| { | ||
| #include "beblid.p512.hpp" | ||
| #include "beblid.p256.hpp" | ||
| if (n_bits == SIZE_512_BITS) | ||
| wl_params_.assign(wl_params_512, wl_params_512 + sizeof(wl_params_512) / sizeof(wl_params_512[0])); | ||
| else if(n_bits == SIZE_256_BITS) | ||
| wl_params_.assign(wl_params_256, wl_params_256 + sizeof(wl_params_256) / sizeof(wl_params_256[0])); | ||
| WeakLearnerT * begin_ptr, * end_ptr; | ||
| if (n_bits == BEBLID::SIZE_512_BITS) | ||
| { | ||
| #include "beblid.p512.hpp" | ||
| begin_ptr = (WeakLearnerT *) std::begin(beblid_wl_params_512); | ||
| end_ptr = (WeakLearnerT *) std::end(beblid_wl_params_512); | ||
|
||
| } | ||
| else if(n_bits == BEBLID::SIZE_256_BITS) | ||
| { | ||
| #include "beblid.p256.hpp" | ||
| begin_ptr = (WeakLearnerT *) std::begin(beblid_wl_params_256); | ||
| end_ptr = (WeakLearnerT *) std::end(beblid_wl_params_256); | ||
| } | ||
| else if (n_bits == TEBLID::SIZE_512_BITS) | ||
| { | ||
| #include "teblid.p512.hpp" | ||
|
|
||
| begin_ptr = (WeakLearnerT *) std::begin(teblid_wl_params_512); | ||
| end_ptr = (WeakLearnerT *) std::end(teblid_wl_params_512); | ||
| } | ||
| else if(n_bits == TEBLID::SIZE_256_BITS) | ||
| { | ||
| #include "teblid.p256.hpp" | ||
|
|
||
| begin_ptr = (WeakLearnerT *) std::begin(teblid_wl_params_256); | ||
| end_ptr = (WeakLearnerT *) std::end(teblid_wl_params_256); | ||
| } | ||
| else | ||
| CV_Error(Error::StsBadArg, "n_wls should be either SIZE_512_BITS or SIZE_256_BITS"); | ||
| { | ||
| CV_Error(Error::StsBadArg, "n_bits should be either TEBLID::SIZE_512_BITS, TEBLID::SIZE_256_BITS, " | ||
| "BEBLID::SIZE_512_BITS or BEBLID::SIZE_256_BITS"); | ||
| } | ||
| wl_params_.assign(begin_ptr, end_ptr); | ||
| } | ||
|
|
||
| // Internal function that implements the core of BEBLID descriptor | ||
| void BEBLID_Impl::computeBEBLID(const cv::Mat &integralImg, | ||
| const std::vector<cv::KeyPoint> &keypoints, | ||
| cv::Mat &descriptors) | ||
| template<class WeakLearnerT> | ||
| void BEBLID_Impl<WeakLearnerT>::computeBoxDiffsDescriptor(const cv::Mat &integralImg, | ||
| const std::vector<cv::KeyPoint> &keypoints, | ||
| cv::Mat &descriptors) | ||
| { | ||
| CV_DbgAssert(!integralImg.empty()); | ||
| CV_DbgAssert(size_t(descriptors.rows) == keypoints.size()); | ||
|
|
@@ -316,13 +389,13 @@ void BEBLID_Impl::computeBEBLID(const cv::Mat &integralImg, | |
| #endif | ||
| { | ||
| // Get a pointer to the first element in the range | ||
| ABWLParams *wl; | ||
| WeakLearnerT *wl; | ||
| float responseFun; | ||
| int areaResponseFun, kpIdx; | ||
| size_t wlIdx; | ||
| int box1x1, box1y1, box1x2, box1y2, box2x1, box2y1, box2x2, box2y2, bit_idx, side; | ||
| uchar byte = 0; | ||
| std::vector<ABWLParams> imgWLParams(wl_params_.size()); | ||
| std::vector<WeakLearnerT> imgWLParams(wl_params_.size()); | ||
| uchar *d = &descriptors.at<uchar>(range.start, 0); | ||
|
|
||
| for (kpIdx = range.start; kpIdx < range.end; kpIdx++) | ||
|
|
@@ -397,7 +470,7 @@ void BEBLID_Impl::computeBEBLID(const cv::Mat &integralImg, | |
|
|
||
| Ptr<BEBLID> BEBLID::create(float scale_factor, int n_bits) | ||
| { | ||
| return makePtr<BEBLID_Impl>(scale_factor, n_bits); | ||
| return makePtr<BEBLID_Impl<ABWLParams>>(scale_factor, n_bits); | ||
| } | ||
| } // END NAMESPACE XFEATURES2D | ||
| } // END NAMESPACE CV | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you please use this link? https://github.com/opencv/opencv/blob/4.x/samples/cpp/tutorial_code/features2D/AKAZE_match.cpp
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!