Ask Your Question
1

FREAKs patternScale parameter tuning

asked 2012-12-20 09:53:35 -0600

jav_rock gravatar image

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 flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
-3

answered 2012-12-21 21:50:31 -0600

retu2367 gravatar image

updated 2012-12-21 22:07:12 -0600

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)
const double sigma[8] = {radius[0]/2.0, radius[1]/2.0, radius[2]/2.0,
                         radius[3]/2.0, radius[4]/2.0, radius[5]/2.0,
                         radius[6]/2.0, radius[6]/2.0
                        };
// 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)

edit flag offensive delete link more

Comments

2

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

SR gravatar imageSR ( 2012-12-22 07:12:42 -0600 )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?

Symon_85 gravatar imageSymon_85 ( 2014-10-16 10:46:08 -0600 )edit

Question Tools

Stats

Asked: 2012-12-20 09:53:35 -0600

Seen: 1,224 times

Last updated: Dec 21 '12