@@ -353,13 +353,30 @@ BRISK_Impl::generateKernel(const std::vector<float> &radiusList,
353
353
const int rings = (int )radiusList.size ();
354
354
CV_Assert (radiusList.size () != 0 && radiusList.size () == numberList.size ());
355
355
points_ = 0 ; // remember the total number of points
356
+ double sineThetaLookupTable[n_rot_];
357
+ double cosThetaLookupTable[n_rot_];
356
358
for (int ring = 0 ; ring < rings; ring++)
357
359
{
358
360
points_ += numberList[ring];
359
361
}
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
+ }
360
378
// set up the patterns
361
379
patternPoints_ = new BriskPatternPoint[points_ * scales_ * n_rot_];
362
- BriskPatternPoint* patternIterator = patternPoints_;
363
380
364
381
// define the scale discretization:
365
382
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,
370
387
371
388
const float sigma_scale = 1 .3f ;
372
389
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]));
400
403
}
401
404
// 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;
406
433
}
407
-
408
- // increment the iterator
409
- ++patternIterator;
410
- }
411
434
}
412
- }
413
435
}
414
436
415
437
// now also generate pairings
0 commit comments