Skip to content

Commit 2c1f348

Browse files
committed
Merge pull request opencv#18037 from danielenricocahall:improve-brisk-init-perf
2 parents acc6189 + ac177b8 commit 2c1f348

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)