# FREAKs patternScale parameter tuning

For rotated and scale dimages I just achieve good matching results using FREAK when adjusting the patternScale parameter and downsampled the traingin image like this:

pyrDown(training, training);

FREAK extractor(true, true, 40, 4);

extractor.compute( training, keypointsA, descriptorsA );
extractor.compute( img, keypointsB, descriptorsB );


Which is the relation of the patternScale parameter and the size of the training image? Is there a way to tune it for all cases of rotations and scalings?

edit retag close merge delete

Sort by ยป oldest newest most voted

Here a parts of the code that use the scale and image size Note the use off the " patternScale "

void FREAK::buildPattern() { if( patternScale == patternScale0 && nOctaves == nOctaves0 && !patternLookup.empty() ) return;

nOctaves0 = nOctaves;
patternScale0 = "***patternScale***";

patternLookup.resize(FREAK_NB_SCALES*FREAK_NB_ORIENTATION*FREAK_NB_POINTS);
double scaleStep = pow(2.0, (double)(nOctaves)/FREAK_NB_SCALES ); // 2 ^ ( (nOctaves-1) /nbScales)
double scalingFactor, alpha, beta, theta = 0;

// pattern definition, radius normalized to 1.0 (outer point position+sigma=1.0)
const int n[8] = {6,6,6,6,6,6,6,1}; // number of points on each concentric circle (from outer to inner)
const double bigR(2.0/3.0); // bigger radius
const double smallR(2.0/24.0); // smaller radius
const double unitSpace( (bigR-smallR)/21.0 ); // define spaces between concentric circles (from center to outer: 1,2,3,4,5,6)
// radii of the concentric cirles (from outer to inner)
const double radius[8] = {bigR, bigR-6*unitSpace, bigR-11*unitSpace, bigR-15*unitSpace, bigR-18*unitSpace, bigR-20*unitSpace, smallR, 0.0};
// sigma of pattern points (each group of 6 points on a concentric cirle has the same sigma)
};
// fill the lookup table
for( int scaleIdx=0; scaleIdx < FREAK_NB_SCALES; ++scaleIdx ) {
patternSizes[scaleIdx] = 0; // proper initialization
scalingFactor = pow(scaleStep,scaleIdx); //scale of the pattern, scaleStep ^ scaleIdx

for( int orientationIdx = 0; orientationIdx < FREAK_NB_ORIENTATION; ++orientationIdx ) {
theta = double(orientationIdx)* 2*CV_PI/double(FREAK_NB_ORIENTATION); // orientation of the pattern
int pointIdx = 0;

PatternPoint* patternLookupPtr = &patternLookup[0];
for( size_t i = 0; i < 8; ++i ) {
for( int k = 0 ; k < n[i]; ++k ) {
beta = CV_PI/n[i] * (i%2); // orientation offset so that groups of points on each circles are staggered
alpha = double(k)* 2*CV_PI/double(n[i])+beta+theta;

// add the point to the look-up table
PatternPoint& point = patternLookupPtr[ scaleIdx*FREAK_NB_ORIENTATION*FREAK_NB_POINTS+orientationIdx*FREAK_NB_POINTS+pointIdx ];
point.x = static_cast<float>(radius[i] * cos(alpha) * scalingFactor * "***patternScale***");
point.y = static_cast<float>(radius[i] * sin(alpha) * scalingFactor * "***patternScale***");
point.sigma = static_cast<float>(sigma[i] * scalingFactor * "***patternScale***");

// adapt the sizeList if necessary
const int sizeMax = static_cast<int>(ceil((radius[i]+sigma[i])*scalingFactor* "***patternScale***")) + 1;
if( patternSizes[scaleIdx] < sizeMax )
**patternSizes**[scaleIdx] = sizeMax;

++pointIdx;
}
}
}
}


Affter build the pattern a call off function computeImpl() is done to extract the descriptor

void FREAK::computeImpl( const Mat& image, std::vector<keypoint>& keypoints, Mat& descriptors ) {......

"According to the parameters setup in the constructor"

if( scaleNormalized ) { for( size_t k = keypoints.size(); k--; ) { //Is k non-zero? If so, decrement it and continue" kpScaleIdx[k] = max( (int)(log(keypoints[k].size/FREAK_SMALLEST_KP_SIZE)*sizeCst+0.5) ,0); if( kpScaleIdx[k] >= FREAK_NB_SCALES ) kpScaleIdx[k] = FREAK_NB_SCALES-1;

        if( keypoints[k].pt.x <= patternSizes[kpScaleIdx[k]] ||


" //check if the description at this specific position and scale fits inside the image " keypoints[k].pt.y <= patternSizes[kpScaleIdx[k]] || keypoints[k].pt.x >= "image.cols-patternSizes[kpScaleIdx[k]]" || keypoints[k].pt.y >= "image.rows-patternSizes[kpScaleIdx[k]]" ) { keypoints.erase(kpBegin+k); kpScaleIdx.erase(ScaleIdxBegin+k ...

more

2

This is not an answer. It is just a heap of code.

( 2012-12-22 07:12:42 -0500 )edit

The lack of documentation is very annoying. Let's assume I have a 64x64 patch already rotated and normalized and I want to compute a single FREAK descriptor using all the area... how to set patternScale? and keypoint size at the center of the patch?

( 2014-10-16 10:46:08 -0500 )edit

Official site

GitHub

Wiki

Documentation