Skip to content

Commit ac177b8

Browse files
Improve initialization performance of Brisk
reformatting Improve initialization performance of Brisk fix formatting Improve initialization performance of Brisk formatting Improve initialization performance of Brisk make a lookup table for ring use cosine/sine lookup table for theta in brisk and utilize trig identity fix ring lookup table use cosine/sine lookup table for theta in brisk and utilize trig identity formatting use cosine/sine lookup table for theta in brisk and utilize trig identity move scale radius product to ring loop to ensure it's not recomputed for each rot revert change move scale radius product to ring loop to ensure it's not recomputed for each rot remove rings lookup table move scale radius product to ring loop to ensure it's not recomputed for each rot fix formatting of for loop move scale radius product to ring loop to ensure it's not recomputed for each rot use sine/cosine approximations for brisk lookup table. add documentation for sine/cosine lookup tables Improve initialization performance of BRISK
1 parent 793e7c0 commit ac177b8

File tree

1 file changed

+59
-37
lines changed

1 file changed

+59
-37
lines changed

modules/features2d/src/brisk.cpp

Lines changed: 59 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -353,13 +353,30 @@ BRISK_Impl::generateKernel(const std::vector<float> &radiusList,
353353
const int rings = (int)radiusList.size();
354354
CV_Assert(radiusList.size() != 0 && radiusList.size() == numberList.size());
355355
points_ = 0; // remember the total number of points
356+
double sineThetaLookupTable[n_rot_];
357+
double cosThetaLookupTable[n_rot_];
356358
for (int ring = 0; ring < rings; ring++)
357359
{
358360
points_ += numberList[ring];
359361
}
362+
363+
// using a sine/cosine approximation for the lookup table
364+
// utilizes the trig identities:
365+
// sin(a + b) = sin(a)cos(b) + cos(a)sin(b)
366+
// cos(a + b) = cos(a)cos(b) - sin(a)sin(b)
367+
// and the fact that sin(0) = 0, cos(0) = 1
368+
double cosval = 1., sinval = 0.;
369+
double dcos = cos(2*CV_PI/double(n_rot_)), dsin = sin(2*CV_PI/double(n_rot_));
370+
for( size_t rot = 0; rot < n_rot_; ++rot)
371+
{
372+
sineThetaLookupTable[rot] = sinval;
373+
cosThetaLookupTable[rot] = cosval;
374+
double t = sinval*dcos + cosval*dsin;
375+
cosval = cosval*dcos - sinval*dsin;
376+
sinval = t;
377+
}
360378
// set up the patterns
361379
patternPoints_ = new BriskPatternPoint[points_ * scales_ * n_rot_];
362-
BriskPatternPoint* patternIterator = patternPoints_;
363380

364381
// define the scale discretization:
365382
static const float lb_scale = (float)(std::log(scalerange_) / std::log(2.0));
@@ -370,46 +387,51 @@ BRISK_Impl::generateKernel(const std::vector<float> &radiusList,
370387

371388
const float sigma_scale = 1.3f;
372389

373-
for (unsigned int scale = 0; scale < scales_; ++scale)
374-
{
375-
scaleList_[scale] = (float)std::pow((double) 2.0, (double) (scale * lb_scale_step));
376-
sizeList_[scale] = 0;
377-
378-
// generate the pattern points look-up
379-
double alpha, theta;
380-
for (size_t rot = 0; rot < n_rot_; ++rot)
381-
{
382-
theta = double(rot) * 2 * CV_PI / double(n_rot_); // this is the rotation of the feature
383-
for (int ring = 0; ring < rings; ++ring)
384-
{
385-
for (int num = 0; num < numberList[ring]; ++num)
386-
{
387-
// the actual coordinates on the circle
388-
alpha = (double(num)) * 2 * CV_PI / double(numberList[ring]);
389-
patternIterator->x = (float)(scaleList_[scale] * radiusList[ring] * cos(alpha + theta)); // feature rotation plus angle of the point
390-
patternIterator->y = (float)(scaleList_[scale] * radiusList[ring] * sin(alpha + theta));
391-
// and the gaussian kernel sigma
392-
if (ring == 0)
393-
{
394-
patternIterator->sigma = sigma_scale * scaleList_[scale] * 0.5f;
395-
}
396-
else
397-
{
398-
patternIterator->sigma = (float)(sigma_scale * scaleList_[scale] * (double(radiusList[ring]))
399-
* sin(CV_PI / numberList[ring]));
390+
for (unsigned int scale = 0; scale < scales_; ++scale) {
391+
scaleList_[scale] = (float) std::pow((double) 2.0, (double) (scale * lb_scale_step));
392+
sizeList_[scale] = 0;
393+
BriskPatternPoint *patternIteratorOuter = patternPoints_ + (scale * n_rot_ * points_);
394+
// generate the pattern points look-up
395+
for (int ring = 0; ring < rings; ++ring) {
396+
double scaleRadiusProduct = scaleList_[scale] * radiusList[ring];
397+
float patternSigma = 0.0f;
398+
if (ring == 0) {
399+
patternSigma = sigma_scale * scaleList_[scale] * 0.5f;
400+
} else {
401+
patternSigma = (float) (sigma_scale * scaleList_[scale] * (double(radiusList[ring]))
402+
* sin(CV_PI / numberList[ring]));
400403
}
401404
// adapt the sizeList if necessary
402-
const unsigned int size = cvCeil(((scaleList_[scale] * radiusList[ring]) + patternIterator->sigma)) + 1;
403-
if (sizeList_[scale] < size)
404-
{
405-
sizeList_[scale] = size;
405+
const unsigned int size = cvCeil(((scaleList_[scale] * radiusList[ring]) + patternSigma)) + 1;
406+
if (sizeList_[scale] < size) {
407+
sizeList_[scale] = size;
408+
}
409+
for (int num = 0; num < numberList[ring]; ++num) {
410+
BriskPatternPoint *patternIterator = patternIteratorOuter;
411+
double alpha = (double(num)) * 2 * CV_PI / double(numberList[ring]);
412+
double sine_alpha = sin(alpha);
413+
double cosine_alpha = cos(alpha);
414+
415+
for (size_t rot = 0; rot < n_rot_; ++rot) {
416+
double cosine_theta = cosThetaLookupTable[rot];
417+
double sine_theta = sineThetaLookupTable[rot];
418+
419+
// the actual coordinates on the circle
420+
// sin(a + b) = sin(a) cos(b) + cos(a) sin(b)
421+
// cos(a + b) = cos(a) cos(b) - sin(a) sin(b)
422+
patternIterator->x = (float) (scaleRadiusProduct *
423+
(cosine_theta * cosine_alpha -
424+
sine_theta * sine_alpha)); // feature rotation plus angle of the point
425+
patternIterator->y = (float) (scaleRadiusProduct *
426+
(sine_theta * cosine_alpha + cosine_theta * sine_alpha));
427+
patternIterator->sigma = patternSigma;
428+
// and the gaussian kernel sigma
429+
// increment the iterator
430+
patternIterator += points_;
431+
}
432+
++patternIteratorOuter;
406433
}
407-
408-
// increment the iterator
409-
++patternIterator;
410-
}
411434
}
412-
}
413435
}
414436

415437
// now also generate pairings

0 commit comments

Comments
 (0)