Skip to content

Commit 660cf2e

Browse files
committed
Changing BAD name by TEBLID and using int threshold again for BEBLID
1 parent c06a527 commit 660cf2e

File tree

9 files changed

+67
-50
lines changed

9 files changed

+67
-50
lines changed

modules/xfeatures2d/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ Extra 2D Features Framework
55
2. Non-free 2D feature algorithms
66

77
Extra 2D Features Framework containing experimental and non-free 2D feature detector/descriptor algorithms:
8-
SURF, BRIEF, Censure, Freak, LUCID, Daisy, BEBLID, BAD, Self-similar.
8+
SURF, BRIEF, Censure, Freak, LUCID, Daisy, BEBLID, TEBLID, Self-similar.

modules/xfeatures2d/doc/xfeatures2d.bib

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ @article{Suarez2020BEBLID
154154
author = {Iago Su\'arez and Ghesn Sfeir and Jos\'e M. Buenaposada and Luis Baumela},
155155
}
156156

157-
@article{Suarez2021BAD,
157+
@article{Suarez2021TEBLID,
158158
title = {Revisiting Binary Local Image Description for Resource Limited Devices},
159159
journal = {IEEE Robotics and Automation Letters},
160160
volume = {6},

modules/xfeatures2d/include/opencv2/xfeatures2d.hpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -224,17 +224,18 @@ class CV_EXPORTS_W BEBLID : public Feature2D
224224
CV_WRAP static Ptr<BEBLID> create(float scale_factor, int n_bits = BEBLID::SIZE_512_BITS);
225225
};
226226

227-
/** @brief Class implementing BAD (Box Average Difference Descriptor),
228-
* described in @cite Suarez2021BAD .
227+
/** @brief Class implementing TEBLID (Triplet-based Efficient Binary Local Image Descriptor),
228+
* described in @cite Suarez2021TEBLID.
229229
230-
BAD \cite Suarez2021BAD is an improvement over BEBLID \cite Suarez2020BEBLID, that uses triplet loss,
230+
TEBLID stands for Triplet-based Efficient Binary Local Image Descriptor, although originally it was called BAD
231+
\cite Suarez2021TEBLID. It is an improvement over BEBLID \cite Suarez2020BEBLID, that uses triplet loss,
231232
hard negative mining, and anchor swap to improve the image matching results.
232233
It is able to describe keypoints from any detector just by changing the scale_factor parameter.
233-
BAD is as efficient as ORB, BEBLID or BRISK, but the triplet-based training objective selected more
234+
TEBLID is as efficient as ORB, BEBLID or BRISK, but the triplet-based training objective selected more
234235
discriminative features that explain the accuracy gain. It is also more compact than BEBLID,
235236
when running the [AKAZE example](https://raw.githubusercontent.com/opencv/opencv/master/samples/cpp/tutorial_code/features2D/AKAZE_match.cpp)
236237
with 10000 keypoints detected by ORB, BEBLID obtains 561 inliers (75%) with 512 bits, whereas
237-
BAD obtains 621 (75.2%) with 256 bits. ORB obtains only 493 inliers (63%).
238+
TEBLID obtains 621 (75.2%) with 256 bits. ORB obtains only 493 inliers (63%).
238239
239240
If you find this code useful, please add a reference to the following paper:
240241
<BLOCKQUOTE> Iago Suárez, José M. Buenaposada, and Luis Baumela.
@@ -243,7 +244,7 @@ IEEE Robotics and Automation Letters, vol. 6, no. 4, pp. 8317-8324, Oct. 2021. <
243244
244245
The descriptor was trained in Liberty split of the UBC datasets \cite winder2007learning .
245246
*/
246-
class CV_EXPORTS_W BAD : public Feature2D
247+
class CV_EXPORTS_W TEBLID : public Feature2D
247248
{
248249
public:
249250
/**
@@ -254,16 +255,16 @@ class CV_EXPORTS_W BAD : public Feature2D
254255
{
255256
SIZE_256_BITS = 102, SIZE_512_BITS = 103,
256257
};
257-
/** @brief Creates the BAD descriptor.
258+
/** @brief Creates the TEBLID descriptor.
258259
@param scale_factor Adjust the sampling window around detected keypoints:
259260
- <b> 1.00f </b> should be the scale for ORB keypoints
260261
- <b> 6.75f </b> should be the scale for SIFT detected keypoints
261262
- <b> 6.25f </b> is default and fits for KAZE, SURF detected keypoints
262263
- <b> 5.00f </b> should be the scale for AKAZE, MSD, AGAST, FAST, BRISK keypoints
263264
@param n_bits Determine the number of bits in the descriptor. Should be either
264-
BAD::SIZE_256_BITS or BAD::SIZE_512_BITS.
265+
TEBLID::SIZE_256_BITS or TEBLID::SIZE_512_BITS.
265266
*/
266-
CV_WRAP static Ptr<BAD> create(float scale_factor, int n_bits = BAD::SIZE_256_BITS);
267+
CV_WRAP static Ptr<TEBLID> create(float scale_factor, int n_bits = TEBLID::SIZE_256_BITS);
267268
};
268269

269270
/** @brief Class implementing DAISY descriptor, described in @cite Tola10

modules/xfeatures2d/perf/perf_bad.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ PERF_TEST_P(bad, extract, testing::Values(BAD_IMAGES))
2525
vector<KeyPoint> points;
2626
detector->detect(frame, points, mask);
2727

28-
Ptr<BAD> descriptor = BAD::create(6.25f);
28+
Ptr<TEBLID> descriptor = TEBLID::create(6.25f);
2929
cv::Mat descriptors;
3030
TEST_CYCLE() descriptor->compute(frame, points, descriptors);
3131

modules/xfeatures2d/src/bad.p256.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010

1111
// ABWLParams: x1, y1, x2, y2, boxRadius, th
1212

13-
// Pre-trained parameters of BAD-256 trained in Liberty data set. 10K triplets are sampled per iteration. Each triplet
13+
// Pre-trained parameters of TEBLID-256 trained in Liberty data set. 10K triplets are sampled per iteration. Each triplet
1414
// contains an anchor patch, a positive and a negative, selected as the hardest among 256 random negatives.
15-
static const ABWLParams bad_params_256[] = {
15+
static const ABWLParamsFloatTh bad_params_256[] = {
1616
{25, 14, 13, 15, 6, 21.65}, {16, 15, 14, 11, 1, 5.65}, {14, 14, 7, 8, 6, 4.95},
1717
{10, 9, 6, 20, 6, 2.45}, {13, 26, 13, 19, 5, 2.25}, {19, 14, 19, 5, 4, 0.85},
1818
{16, 19, 15, 13, 2, 3.35}, {26, 26, 21, 12, 5, 1.75}, {18, 23, 15, 20, 2, 4.55},

modules/xfeatures2d/src/bad.p512.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010

1111
// ABWLParams: x1, y1, x2, y2, boxRadius, th
1212

13-
// Pre-trained parameters of BAD-512 trained in Liberty data set. 10K triplets are sampled per iteration. Each triplet
13+
// Pre-trained parameters of TEBLID-512 trained in Liberty data set. 10K triplets are sampled per iteration. Each triplet
1414
// contains an anchor patch, a positive and a negative, selected as the hardest among 256 random negatives.
15-
static const ABWLParams bad_params_512[] = {
15+
static const ABWLParamsFloatTh bad_params_512[] = {
1616
{17, 18, 12, 15, 2, 14.45}, {13, 14, 5, 7, 5, 4.15}, {21, 16, 16, 14, 1, 7.75},
1717
{27, 11, 18, 20, 3, 9.65}, {17, 13, 16, 19, 2, 2.25}, {18, 24, 18, 16, 5, 0.15},
1818
{12, 11, 10, 25, 6, 0.45}, {14, 17, 14, 13, 1, -0.95}, {7, 4, 4, 15, 4, 3.65},

modules/xfeatures2d/src/beblid.cpp

Lines changed: 48 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,18 @@ namespace xfeatures2d
2727

2828
// Struct containing the 6 parameters that define an Average Box weak-learner
2929
struct ABWLParams
30+
{
31+
int x1, y1, x2, y2, boxRadius, th;
32+
};
33+
// Same as previous with floating point threshold
34+
struct ABWLParamsFloatTh
3035
{
3136
int x1, y1, x2, y2, boxRadius;
3237
float th;
3338
};
3439

3540
// BEBLID implementation
41+
template <class WeakLearnerT>
3642
class BEBLID_Impl CV_FINAL: public BEBLID
3743
{
3844
public:
@@ -56,26 +62,26 @@ class BEBLID_Impl CV_FINAL: public BEBLID
5662
void compute(InputArray image, vector<KeyPoint> &keypoints, OutputArray descriptors) CV_OVERRIDE;
5763

5864
private:
59-
std::vector<ABWLParams> wl_params_;
65+
std::vector<WeakLearnerT> wl_params_;
6066
float scale_factor_;
6167
cv::Size patch_size_;
6268

63-
void computeBEBLID(const cv::Mat &integralImg,
64-
const std::vector<cv::KeyPoint> &keypoints,
65-
cv::Mat &descriptors);
69+
void computeBoxDiffsDescriptor(const cv::Mat &integralImg,
70+
const std::vector<cv::KeyPoint> &keypoints,
71+
cv::Mat &descriptors);
6672
}; // END BEBLID_Impl CLASS
6773

6874

69-
// BAD implementation
70-
class BAD_Impl CV_FINAL: public BAD
75+
// TEBLID implementation
76+
class TEBLID_Impl CV_FINAL: public TEBLID
7177
{
7278
public:
7379

7480
// constructor
75-
explicit BAD_Impl(float scale_factor, int n_bits = BAD::SIZE_256_BITS) : impl(scale_factor, n_bits){}
81+
explicit TEBLID_Impl(float scale_factor, int n_bits = TEBLID::SIZE_256_BITS) : impl(scale_factor, n_bits){}
7682

7783
// destructor
78-
~BAD_Impl() CV_OVERRIDE = default;
84+
~TEBLID_Impl() CV_OVERRIDE = default;
7985

8086
// returns the descriptor length in bytes
8187
int descriptorSize() const CV_OVERRIDE { return impl.descriptorSize(); }
@@ -93,12 +99,12 @@ class BAD_Impl CV_FINAL: public BAD
9399
}
94100

95101
private:
96-
BEBLID_Impl impl;
97-
}; // END BAD_Impl CLASS
102+
BEBLID_Impl<ABWLParamsFloatTh> impl;
103+
}; // END TEBLID_Impl CLASS
98104

99-
Ptr<BAD> BAD::create(float scale_factor, int n_bits)
105+
Ptr<TEBLID> TEBLID::create(float scale_factor, int n_bits)
100106
{
101-
return makePtr<BAD_Impl>(scale_factor, n_bits);
107+
return makePtr<TEBLID_Impl>(scale_factor, n_bits);
102108
}
103109

104110
/**
@@ -137,8 +143,9 @@ static inline bool isKeypointInTheBorder(const cv::KeyPoint &kp,
137143
* @param scaleFactor A scale factor that magnifies the measurement functions w.r.t. the keypoint.
138144
* @param patchSize The size of the normalized patch where the measurement functions were learnt.
139145
*/
140-
static inline void rectifyABWL(const std::vector<ABWLParams> &wlPatchParams,
141-
std::vector<ABWLParams> &wlImageParams,
146+
template< typename WeakLearnerT>
147+
static inline void rectifyABWL(const std::vector<WeakLearnerT> &wlPatchParams,
148+
std::vector<WeakLearnerT> &wlImageParams,
142149
const cv::KeyPoint &kp,
143150
float scaleFactor = 1,
144151
const cv::Size &patchSize = cv::Size(32, 32))
@@ -188,7 +195,8 @@ static inline void rectifyABWL(const std::vector<ABWLParams> &wlPatchParams,
188195
* @param integralImage The integral image used to compute the average gray value in the square regions.
189196
* @return The difference of gray level in the two squares defined by wlImageParams
190197
*/
191-
static inline float computeABWLResponse(const ABWLParams &wlImageParams,
198+
template <typename WeakLearnerT>
199+
static inline float computeABWLResponse(const WeakLearnerT &wlImageParams,
192200
const cv::Mat &integralImage)
193201
{
194202
CV_DbgAssert(!integralImage.empty());
@@ -276,7 +284,8 @@ static inline float computeABWLResponse(const ABWLParams &wlImageParams,
276284
}
277285

278286
// descriptor computation using keypoints
279-
void BEBLID_Impl::compute(InputArray _image, vector<KeyPoint> &keypoints, OutputArray _descriptors)
287+
template <class WeakLearnerT>
288+
void BEBLID_Impl<WeakLearnerT>::compute(InputArray _image, vector<KeyPoint> &keypoints, OutputArray _descriptors)
280289
{
281290
Mat image = _image.getMat();
282291

@@ -318,45 +327,52 @@ void BEBLID_Impl::compute(InputArray _image, vector<KeyPoint> &keypoints, Output
318327
CV_DbgAssert(descriptors.type() == CV_8UC1);
319328

320329
// Compute the BEBLID descriptors
321-
computeBEBLID(integralImg, keypoints, descriptors);
330+
computeBoxDiffsDescriptor(integralImg, keypoints, descriptors);
322331
}
323332

324333
// constructor
325-
BEBLID_Impl::BEBLID_Impl(float scale_factor, int n_bits)
334+
template <class WeakLearnerT>
335+
BEBLID_Impl<WeakLearnerT>::BEBLID_Impl(float scale_factor, int n_bits)
326336
: scale_factor_(scale_factor), patch_size_(32, 32)
327337
{
338+
WeakLearnerT * begin_ptr, * end_ptr;
328339
if (n_bits == BEBLID::SIZE_512_BITS)
329340
{
330341
#include "beblid.p512.hpp"
331-
wl_params_.assign(wl_params_512, wl_params_512 + sizeof(wl_params_512) / sizeof(wl_params_512[0]));
342+
begin_ptr = (WeakLearnerT *) std::begin(wl_params_512);
343+
end_ptr = (WeakLearnerT *) std::end(wl_params_512);
332344
}
333345
else if(n_bits == BEBLID::SIZE_256_BITS)
334346
{
335347
#include "beblid.p256.hpp"
336-
wl_params_.assign(wl_params_256, wl_params_256 + sizeof(wl_params_256) / sizeof(wl_params_256[0]));
348+
begin_ptr = (WeakLearnerT *) std::begin(wl_params_256);
349+
end_ptr = (WeakLearnerT *) std::end(wl_params_256);
337350
}
338-
else if (n_bits == BAD::SIZE_512_BITS)
351+
else if (n_bits == TEBLID::SIZE_512_BITS)
339352
{
340353
#include "bad.p512.hpp"
341-
wl_params_.assign(bad_params_512, bad_params_512 + sizeof(bad_params_512) / sizeof(bad_params_512[0]));
354+
begin_ptr = (WeakLearnerT *) std::begin(bad_params_512);
355+
end_ptr = (WeakLearnerT *) std::end(bad_params_512);
342356
}
343-
else if(n_bits == BAD::SIZE_256_BITS)
357+
else if(n_bits == TEBLID::SIZE_256_BITS)
344358
{
345359
#include "bad.p256.hpp"
346-
wl_params_.assign(bad_params_256, bad_params_256 + sizeof(bad_params_256) / sizeof(bad_params_256[0]));
360+
begin_ptr = (WeakLearnerT *) std::begin(bad_params_256);
361+
end_ptr = (WeakLearnerT *) std::end(bad_params_256);
347362
}
348363
else
349364
{
350-
CV_Error(Error::StsBadArg, "n_bits should be either BAD::SIZE_512_BITS, BAD::SIZE_256_BITS, "
365+
CV_Error(Error::StsBadArg, "n_bits should be either TEBLID::SIZE_512_BITS, TEBLID::SIZE_256_BITS, "
351366
"BEBLID::SIZE_512_BITS or BEBLID::SIZE_256_BITS");
352367
}
353-
368+
wl_params_.assign(begin_ptr, end_ptr);
354369
}
355370

356371
// Internal function that implements the core of BEBLID descriptor
357-
void BEBLID_Impl::computeBEBLID(const cv::Mat &integralImg,
358-
const std::vector<cv::KeyPoint> &keypoints,
359-
cv::Mat &descriptors)
372+
template<class WeakLearnerT>
373+
void BEBLID_Impl<WeakLearnerT>::computeBoxDiffsDescriptor(const cv::Mat &integralImg,
374+
const std::vector<cv::KeyPoint> &keypoints,
375+
cv::Mat &descriptors)
360376
{
361377
CV_DbgAssert(!integralImg.empty());
362378
CV_DbgAssert(size_t(descriptors.rows) == keypoints.size());
@@ -371,13 +387,13 @@ void BEBLID_Impl::computeBEBLID(const cv::Mat &integralImg,
371387
#endif
372388
{
373389
// Get a pointer to the first element in the range
374-
ABWLParams *wl;
390+
WeakLearnerT *wl;
375391
float responseFun;
376392
int areaResponseFun, kpIdx;
377393
size_t wlIdx;
378394
int box1x1, box1y1, box1x2, box1y2, box2x1, box2y1, box2x2, box2y2, bit_idx, side;
379395
uchar byte = 0;
380-
std::vector<ABWLParams> imgWLParams(wl_params_.size());
396+
std::vector<WeakLearnerT> imgWLParams(wl_params_.size());
381397
uchar *d = &descriptors.at<uchar>(range.start, 0);
382398

383399
for (kpIdx = range.start; kpIdx < range.end; kpIdx++)
@@ -452,7 +468,7 @@ void BEBLID_Impl::computeBEBLID(const cv::Mat &integralImg,
452468

453469
Ptr<BEBLID> BEBLID::create(float scale_factor, int n_bits)
454470
{
455-
return makePtr<BEBLID_Impl>(scale_factor, n_bits);
471+
return makePtr<BEBLID_Impl<ABWLParams>>(scale_factor, n_bits);
456472
}
457473
} // END NAMESPACE XFEATURES2D
458474
} // END NAMESPACE CV

modules/xfeatures2d/test/test_features2d.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ TEST(Features2d_DescriptorExtractor_BEBLID, regression )
195195
TEST(Features2d_DescriptorExtractor_BAD, regression )
196196
{
197197
CV_DescriptorExtractorTest<Hamming> test("descriptor-bad", 1,
198-
BAD::create(6.75));
198+
TEBLID::create(6.75));
199199
test.safe_run();
200200
}
201201

modules/xfeatures2d/test/test_rotation_and_scale_invariance.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ INSTANTIATE_TEST_CASE_P(BEBLID, DescriptorRotationInvariance, Values(
3535
));
3636

3737
INSTANTIATE_TEST_CASE_P(BAD, DescriptorRotationInvariance, Values(
38-
make_tuple(IMAGE_TSUKUBA, SIFT::create(), BAD::create(6.75), 0.98f)
38+
make_tuple(IMAGE_TSUKUBA, SIFT::create(), TEBLID::create(6.75), 0.98f)
3939
));
4040

4141
INSTANTIATE_TEST_CASE_P(DAISY, DescriptorRotationInvariance, Values(

0 commit comments

Comments
 (0)