172 lines
10 KiB
C++
172 lines
10 KiB
C++
static const float FREAK_LOG2 = 0.693147180559945;
|
|
static const int FREAK_NB_ORIENTATION = 256;
|
|
static const int NB_ORIENPAIRS = 45;
|
|
static const int FREAK_NB_POINTS = 43;
|
|
static const int FREAK_SMALLEST_KP_SIZE = 7; // smallest size of keypoints
|
|
static const int NB_PAIRS = 512;
|
|
static const int NB_SCALES = 64;
|
|
|
|
bool orientationNormalized = true;
|
|
bool scaleNormalized = true;
|
|
float patternScale = 22.0f;
|
|
int nOctaves = 4;
|
|
//float patternScale0 = 0.0;
|
|
//int nOctaves0 = 0;
|
|
bool extAll = false; // true if all pairs need to be extracted for pairs selection
|
|
//int* selectedPairs0;
|
|
|
|
float3 patternLookup[NB_SCALES * FREAK_NB_ORIENTATION * FREAK_NB_POINTS]; // look-up table for the pattern points (position+sigma of all points at all scales and orientation)
|
|
int patternSizes[NB_SCALES]; // size of the pattern at a specific scale (used to check if a point is within image boundaries)
|
|
uchar2 descriptionPairs[NB_PAIRS];
|
|
int4 orientationPairs[NB_ORIENPAIRS];
|
|
|
|
// default pairs
|
|
static const int FREAK_DEF_PAIRS[NB_PAIRS] =
|
|
{
|
|
404,431,818,511,181,52,311,874,774,543,719,230,417,205,11,
|
|
560,149,265,39,306,165,857,250,8,61,15,55,717,44,412,
|
|
592,134,761,695,660,782,625,487,549,516,271,665,762,392,178,
|
|
796,773,31,672,845,548,794,677,654,241,831,225,238,849,83,
|
|
691,484,826,707,122,517,583,731,328,339,571,475,394,472,580,
|
|
381,137,93,380,327,619,729,808,218,213,459,141,806,341,95,
|
|
382,568,124,750,193,749,706,843,79,199,317,329,768,198,100,
|
|
466,613,78,562,783,689,136,838,94,142,164,679,219,419,366,
|
|
418,423,77,89,523,259,683,312,555,20,470,684,123,458,453,833,
|
|
72,113,253,108,313,25,153,648,411,607,618,128,305,232,301,84,
|
|
56,264,371,46,407,360,38,99,176,710,114,578,66,372,653,
|
|
129,359,424,159,821,10,323,393,5,340,891,9,790,47,0,175,346,
|
|
236,26,172,147,574,561,32,294,429,724,755,398,787,288,299,
|
|
769,565,767,722,757,224,465,723,498,467,235,127,802,446,233,
|
|
544,482,800,318,16,532,801,441,554,173,60,530,713,469,30,
|
|
212,630,899,170,266,799,88,49,512,399,23,500,107,524,90,
|
|
194,143,135,192,206,345,148,71,119,101,563,870,158,254,214,
|
|
276,464,332,725,188,385,24,476,40,231,620,171,258,67,109,
|
|
844,244,187,388,701,690,50,7,850,479,48,522,22,154,12,659,
|
|
736,655,577,737,830,811,174,21,237,335,353,234,53,270,62,
|
|
182,45,177,245,812,673,355,556,612,166,204,54,248,365,226,
|
|
242,452,700,685,573,14,842,481,468,781,564,416,179,405,35,
|
|
819,608,624,367,98,643,448,2,460,676,440,240,130,146,184,
|
|
185,430,65,807,377,82,121,708,239,310,138,596,730,575,477,
|
|
851,797,247,27,85,586,307,779,326,494,856,324,827,96,748,
|
|
13,397,125,688,702,92,293,716,277,140,112,4,80,855,839,1,
|
|
413,347,584,493,289,696,19,751,379,76,73,115,6,590,183,734,
|
|
197,483,217,344,330,400,186,243,587,220,780,200,793,246,824,
|
|
41,735,579,81,703,322,760,720,139,480,490,91,814,813,163,
|
|
152,488,763,263,425,410,576,120,319,668,150,160,302,491,515,
|
|
260,145,428,97,251,395,272,252,18,106,358,854,485,144,550,
|
|
131,133,378,68,102,104,58,361,275,209,697,582,338,742,589,
|
|
325,408,229,28,304,191,189,110,126,486,211,547,533,70,215,
|
|
670,249,36,581,389,605,331,518,442,822
|
|
};
|
|
|
|
float scaleStep = pow(2.0, (float)(nOctaves)/FREAK_NB_SCALES ); // 2 ^ ( (nOctaves-1) /nbScales)
|
|
|
|
const int n[8] = {6, 6, 6, 6, 6, 6, 6, 1}; // number of points on each concentric circle (from outer to inner)
|
|
const float bigR = (float)(2.0 / 3.0); // bigger radius
|
|
const float smallR = (float)(2.0 / 24.0); // smaller radius
|
|
const float unitSpace = (float)((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 float 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 float 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};
|
|
|
|
for( int scaleIdx=0; scaleIdx < NB_SCALES; ++scaleIdx )
|
|
{
|
|
patternSizes[scaleIdx] = 0; // proper initialization
|
|
float scalingFactor = pow(scaleStep,scaleIdx); //scale of the pattern, scaleStep ^ scaleIdx
|
|
|
|
for( int orientationIdx = 0; orientationIdx < FREAK_NB_ORIENTATION; ++orientationIdx )
|
|
{
|
|
int pointIdx = 0;
|
|
|
|
for( size_t i = 0; i < 8; ++i )
|
|
{
|
|
for( int k = 0 ; k < n[i]; ++k )
|
|
{
|
|
float alpha = (float)(k) * 2 * (float)3.141592653589793238462643383279502884197169399375 / (float)(n[i])
|
|
+ ((float)3.141592653589793238462643383279502884197169399375 / n[i] * ( i % 2 )/*beta*/)
|
|
+ ((float)(orientationIdx * 2 * (float)3.141592653589793238462643383279502884197169399375 / (float)(FREAK_NB_ORIENTATION)) /* theta*/);
|
|
|
|
// add the point to the look-up table
|
|
float3* point = patternLookup[ scaleIdx * FREAK_NB_ORIENTATION * FREAK_NB_POINTS + orientationIdx * FREAK_NB_POINTS + pointIdx];
|
|
point->x = (float)(radius[i] * cos(alpha) * scalingFactor * patternScale); //x
|
|
point->y = (float)(radius[i] * sin(alpha) * scalingFactor * patternScale); //y
|
|
point->z = (float)(sigma[i] * scalingFactor * patternScale); //sigma
|
|
|
|
// adapt the sizeList if necessary
|
|
const int sizeMax = (int)(ceil((radius[i] + sigma[i]) * scalingFactor * patternScale)) + 1;
|
|
if( patternSizes[scaleIdx] < sizeMax )
|
|
patternSizes[scaleIdx] = sizeMax;
|
|
|
|
++pointIdx;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// build the list of orientation pairs
|
|
orientationPairs[0].w=0; orientationPairs[0].x=3; orientationPairs[1].w=1; orientationPairs[1].x=4; orientationPairs[2].w=2; orientationPairs[2].x=5;
|
|
orientationPairs[3].w=0; orientationPairs[3].x=2; orientationPairs[4].w=1; orientationPairs[4].x=3; orientationPairs[5].w=2; orientationPairs[5].x=4;
|
|
orientationPairs[6].w=3; orientationPairs[6].x=5; orientationPairs[7].w=4; orientationPairs[7].x=0; orientationPairs[8].w=5; orientationPairs[8].x=1;
|
|
|
|
orientationPairs[9].w=6; orientationPairs[9].x=9; orientationPairs[10].w=7; orientationPairs[10].x=10; orientationPairs[11].w=8; orientationPairs[11].x=11;
|
|
orientationPairs[12].w=6; orientationPairs[12].x=8; orientationPairs[13].w=7; orientationPairs[13].x=9; orientationPairs[14].w=8; orientationPairs[14].x=10;
|
|
orientationPairs[15].w=9; orientationPairs[15].x=11; orientationPairs[16].w=10; orientationPairs[16].x=6; orientationPairs[17].w=11; orientationPairs[17].x=7;
|
|
|
|
orientationPairs[18].w=12; orientationPairs[18].x=15; orientationPairs[19].w=13; orientationPairs[19].x=16; orientationPairs[20].w=14; orientationPairs[20].x=17;
|
|
orientationPairs[21].w=12; orientationPairs[21].x=14; orientationPairs[22].w=13; orientationPairs[22].x=15; orientationPairs[23].w=14; orientationPairs[23].x=16;
|
|
orientationPairs[24].w=15; orientationPairs[24].x=17; orientationPairs[25].w=16; orientationPairs[25].x=12; orientationPairs[26].w=17; orientationPairs[26].x=13;
|
|
|
|
orientationPairs[27].w=18; orientationPairs[27].x=21; orientationPairs[28].w=19; orientationPairs[28].x=22; orientationPairs[29].w=20; orientationPairs[29].x=23;
|
|
orientationPairs[30].w=18; orientationPairs[30].x=20; orientationPairs[31].w=19; orientationPairs[31].x=21; orientationPairs[32].w=20; orientationPairs[32].x=22;
|
|
orientationPairs[33].w=21; orientationPairs[33].x=23; orientationPairs[34].w=22; orientationPairs[34].x=18; orientationPairs[35].w=23; orientationPairs[35].x=19;
|
|
|
|
orientationPairs[36].w=24; orientationPairs[36].x=27; orientationPairs[37].w=25; orientationPairs[37].x=28; orientationPairs[38].w=26; orientationPairs[38].x=29;
|
|
orientationPairs[39].w=30; orientationPairs[39].x=33; orientationPairs[40].w=31; orientationPairs[40].x=34; orientationPairs[41].w=32; orientationPairs[41].x=35;
|
|
orientationPairs[42].w=36; orientationPairs[42].x=39; orientationPairs[43].w=37; orientationPairs[43].x=40; orientationPairs[44].w=38; orientationPairs[44].x=41;
|
|
|
|
for( unsigned m = NB_ORIENPAIRS; m--; )
|
|
{
|
|
float dx = patternLookup[orientationPairs[m].w].x - patternLookup[orientationPairs[m].x].x;
|
|
float dy = patternLookup[orientationPairs[m].w].y - patternLookup[orientationPairs[m].x].y;
|
|
float norm_sq = (dx * dx + dy * dy);
|
|
orientationPairs[m].y = round((dx / (norm_sq)) * 4096.0); //weight_dx
|
|
orientationPairs[m].z = round((dy / (norm_sq)) * 4096.0); //weight_dy
|
|
}
|
|
|
|
// build the list of description pairs
|
|
uchar2 allPairs[(int)((FREAK_NB_POINTS * (FREAK_NB_POINTS + 1)) / 2)];
|
|
for( int i = 1, idx = 0; i < FREAK_NB_POINTS; ++i )
|
|
{
|
|
// (generate all the pairs)
|
|
for( int j = 0; j < i; ++j )
|
|
{
|
|
allPairs[idx++] = (uchar2){(uchar)i, (uchar)j};
|
|
}
|
|
}
|
|
for( int i = 0; i < NB_PAIRS; ++i )
|
|
descriptionPairs[i] = allPairs[FREAK_DEF_PAIRS[i]];
|
|
|
|
int kpScaleIdx[keypoints.size()];
|
|
|
|
// kernel running with parameter :
|
|
// __kernel void freak(
|
|
// __read_only image2d_t image, // grayescale image - height X width
|
|
// __read_only image2d_t imgIntegral, // (height+1) X (width+1) with zero values
|
|
// __global float3* keypoints, // ptx, pty, angle
|
|
// __global uchar* descriptors, // kp_size * (64 = NB_PAIRS/8) - CV_8U with zero values
|
|
// __global int* patternSizes, // array size : NB_SCALES = 64
|
|
// __global int4* orientationPairs, // array size : FREAK_NB_ORIENTATION = 256
|
|
// __global float3* patternLookup, // array size : NB_SCALES(64) * FREAK_NB_ORIENTATION(256) * FREAK_NB_POINTS(43)
|
|
// __global uchar2* descriptionPairs, // array size : NB_PAIRS = 512
|
|
// __global int* nOctaves,
|
|
// __global int* kpScaleIdx //array size = kp_size - used to save pattern scale index corresponding to each keypoints
|
|
// )
|
|
// FREAK_LOG2 = 0.693147180559945;
|
|
// FREAK_NB_ORIENTATION = 256;
|
|
// FREAK_NB_POINTS = 43;
|
|
// FREAK_SMALLEST_KP_SIZE = 7;
|
|
// NB_PAIRS = 512;
|
|
// NB_SCALES = 64;
|