Ask Your Question

Revision history [back]

Here a parts of the code that use the scale and image size

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 is done to extra 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);
        }
    }
}
else {
    const int scIdx = max( (int)(1.0986122886681*sizeCst+0.5) ,0);
    for( size_t k = keypoints.size(); k--; ) {
        kpScaleIdx[k] = scIdx; **// equivalent to the formule when the scale is normalized with a constant size of keypoints[k].size=3*SMALLEST_KP_SIZE**

        if( kpScaleIdx[k] >= FREAK_NB_SCALES ) {
            kpScaleIdx[k] = FREAK_NB_SCALES-1;
        }
        if( keypoints[k].pt.x <= patternSizes[kpScaleIdx[k]] ||
            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);
        }
    }
}


    for( size_t k = keypoints.size(); k--; ) {
        // estimate orientation (gradient)
        if( !orientationNormalized ) {
            thetaIdx = 0; // assign 0° to all keypoints
            keypoints[k].angle = 0.0;
        }
        else {
            // get the points intensity value in the un-rotated pattern
            for( int i = FREAK_NB_POINTS; i--; ) {
                pointsValue[i] = meanIntensity(image, imgIntegral, keypoints[k].pt.x,keypoints[k].pt.y, kpScaleIdx[k], 0, i);
            }
            direction0 = 0;
            direction1 = 0;
            for( int m = 45; m--; ) {
                //iterate through the orientation pairs
                const int delta = (pointsValue[ orientationPairs[m].i ]-pointsValue[ orientationPairs[m].j ]);
                direction0 += delta*(orientationPairs[m].weight_dx)/2048;
                direction1 += delta*(orientationPairs[m].weight_dy)/2048;
            }

            keypoints[k].angle = static_cast<float>(atan2((float)direction1,(float)direction0)*(180.0/CV_PI));//estimate orientation
            thetaIdx = int(FREAK_NB_ORIENTATION*keypoints[k].angle*(1/360.0)+0.5);
            if( thetaIdx < 0 )
                thetaIdx += FREAK_NB_ORIENTATION;

            if( thetaIdx >= FREAK_NB_ORIENTATION )
                thetaIdx -= FREAK_NB_ORIENTATION;
        }
        // extract descriptor at the computed orientation
        for( int i = FREAK_NB_POINTS; i--; ) {
            pointsValue[i] = meanIntensity(image, imgIntegral, keypoints[k].pt.x,keypoints[k].pt.y, kpScaleIdx[k], thetaIdx, i);
        }

I hope this helps

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

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

nOctaves0 = nOctaves;
patternScale0 = **patternScale**;
"***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**);
***patternScale***);
                point.y = static_cast<float>(radius[i] * sin(alpha) * scalingFactor * **patternScale**);
***patternScale***);
                point.sigma = static_cast<float>(sigma[i] * scalingFactor * **patternScale**);
***patternScale***);

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

                ++pointIdx;
            }
        }
    }
}

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

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

According "According to the parameters setup in the constructorconstructor"

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 image " keypoints[k].pt.y <= patternSizes[kpScaleIdx[k]] || keypoints[k].pt.x >= **image.cols-patternSizes**[kpScaleIdx[k]] image.cols-patternSizes[kpScaleIdx[k]] || keypoints[k].pt.y >= **image.rows-patternSizes**[kpScaleIdx[k]] image.rows-patternSizes[kpScaleIdx[k]] ) { keypoints.erase(kpBegin+k); kpScaleIdx.erase(ScaleIdxBegin+k); } } } else { const int scIdx = max( (int)(1.0986122886681*sizeCst+0.5) (int)(1.0986122886681sizeCst+0.5) ,0); for( size_t k = keypoints.size(); k--; ) { kpScaleIdx[k] = scIdx; **// equivalent "//equivalent to the formule when the scale is normalized with a constant size of keypoints[k].size=3*SMALLEST_KP_SIZE** // keypoints[k].size=3SMALLEST_KP_SIZE** kpScaleIdx[k] = scIdx;

        if( kpScaleIdx[k] >= FREAK_NB_SCALES ) {
            kpScaleIdx[k] = FREAK_NB_SCALES-1;
        }
        if( keypoints[k].pt.x <= patternSizes[kpScaleIdx[k]] ||
            keypoints[k].pt.y <= patternSizes[kpScaleIdx[k]] ||
            keypoints[k].pt.x >= **image.cols-patternSizes**[kpScaleIdx[k]] ||
 " **image.cols-patternSizes** [kpScaleIdx[k]] ||"
            keypoints[k].pt.y >= **image.rows-patternSizes**[kpScaleIdx[k]]
 "  **image.rows-patternSizes**[kpScaleIdx[k]]"
           ) {
            keypoints.erase(kpBegin+k);
            kpScaleIdx.erase(ScaleIdxBegin+k);
        }
    }
}


    for( size_t k = keypoints.size(); k--; ) {
        // estimate orientation (gradient)
        if( !orientationNormalized ) {
            thetaIdx = 0; // assign 0° to all keypoints
            keypoints[k].angle = 0.0;
        }
        else {
            // get the points intensity value in the un-rotated pattern
            for( int i = FREAK_NB_POINTS; i--; ) {
                pointsValue[i] = meanIntensity(image, imgIntegral, keypoints[k].pt.x,keypoints[k].pt.y, kpScaleIdx[k], 0, i);
            }
            direction0 = 0;
            direction1 = 0;
            for( int m = 45; m--; ) {
                //iterate through the orientation pairs
                const int delta = (pointsValue[ orientationPairs[m].i ]-pointsValue[ orientationPairs[m].j ]);
                direction0 += delta*(orientationPairs[m].weight_dx)/2048;
                direction1 += delta*(orientationPairs[m].weight_dy)/2048;
            }

            keypoints[k].angle = static_cast<float>(atan2((float)direction1,(float)direction0)*(180.0/CV_PI));//estimate orientation
            thetaIdx = int(FREAK_NB_ORIENTATION*keypoints[k].angle*(1/360.0)+0.5);
            if( thetaIdx < 0 )
                thetaIdx += FREAK_NB_ORIENTATION;

            if( thetaIdx >= FREAK_NB_ORIENTATION )
                thetaIdx -= FREAK_NB_ORIENTATION;
        }
        // extract descriptor at the computed orientation
        for( int i = FREAK_NB_POINTS; i--; ) {
            pointsValue[i] = meanIntensity(image, imgIntegral, keypoints[k].pt.x,keypoints[k].pt.y, kpScaleIdx[k], thetaIdx, i);
        }

I hope this helps

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***);
"***patternScale***");
                point.y = static_cast<float>(radius[i] * sin(alpha) * scalingFactor * ***patternScale***);
"***patternScale***");
                point.sigma = static_cast<float>(sigma[i] * scalingFactor * ***patternScale***);
"***patternScale***");

                // adapt the sizeList if necessary
                const int sizeMax = static_cast<int>(ceil((radius[i]+sigma[i])*scalingFactor* ***patternScale***)) "***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]] [kpScaleIdx[k]]" || keypoints[k].pt.y >= "image.rows-patternSizes[kpScaleIdx[k]] [kpScaleIdx[k]]" ) { keypoints.erase(kpBegin+k); kpScaleIdx.erase(ScaleIdxBegin+k); } } } else { const int scIdx = max( (int)(1.0986122886681sizeCst+0.5) ,0); for( size_t k = keypoints.size(); k--; ) { "//equivalent to the formule when the scale is normalized with a constant size of // keypoints[k].size=3SMALLEST_KP_SIZE** kpScaleIdx[k] = scIdx;

        if( kpScaleIdx[k] >= FREAK_NB_SCALES ) {
            kpScaleIdx[k] = FREAK_NB_SCALES-1;
        }
        if( keypoints[k].pt.x <= patternSizes[kpScaleIdx[k]] ||
            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);
        }
    }
}


    for( size_t k = keypoints.size(); k--; ) {
        // estimate orientation (gradient)
        if( !orientationNormalized ) {
            thetaIdx = 0; // assign 0° to all keypoints
            keypoints[k].angle = 0.0;
        }
        else {
            // get the points intensity value in the un-rotated pattern
            for( int i = FREAK_NB_POINTS; i--; ) {
                pointsValue[i] = meanIntensity(image, imgIntegral, keypoints[k].pt.x,keypoints[k].pt.y, kpScaleIdx[k], 0, i);
            }
            direction0 = 0;
            direction1 = 0;
            for( int m = 45; m--; ) {
                //iterate through the orientation pairs
                const int delta = (pointsValue[ orientationPairs[m].i ]-pointsValue[ orientationPairs[m].j ]);
                direction0 += delta*(orientationPairs[m].weight_dx)/2048;
                direction1 += delta*(orientationPairs[m].weight_dy)/2048;
            }

            keypoints[k].angle = static_cast<float>(atan2((float)direction1,(float)direction0)*(180.0/CV_PI));//estimate orientation
            thetaIdx = int(FREAK_NB_ORIENTATION*keypoints[k].angle*(1/360.0)+0.5);
            if( thetaIdx < 0 )
                thetaIdx += FREAK_NB_ORIENTATION;

            if( thetaIdx >= FREAK_NB_ORIENTATION )
                thetaIdx -= FREAK_NB_ORIENTATION;
        }
        // extract descriptor at the computed orientation
        for( int i = FREAK_NB_POINTS; i--; ) {
            pointsValue[i] = meanIntensity(image, imgIntegral, keypoints[k].pt.x,keypoints[k].pt.y, kpScaleIdx[k], thetaIdx, i);
        }

I hope this helps