129 lines
5.5 KiB
Common Lisp
129 lines
5.5 KiB
Common Lisp
void meanIntensity( image2d_t _image, image2d_t _integral, float kp_x, float kp_y,
|
|
int scale, int rot, int* point, float3* patternLookupPtr, uchar* output)
|
|
{
|
|
// Prepare a suitable OpenCL image sampler.
|
|
sampler_t const sampler = CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;
|
|
// get point position in image
|
|
float3* FreakPoint = patternLookupPtr + (scale * FREAK_NB_ORIENTATION * FREAK_NB_POINTS + rot * FREAK_NB_POINTS + (*point));
|
|
float xf = FreakPoint->x + kp_x;
|
|
float yf = FreakPoint->y + kp_y;
|
|
int x = (int)xf;
|
|
int y = (int)yf;
|
|
|
|
// get the sigma:
|
|
float radius = FreakPoint->z;//sigma
|
|
|
|
// calculate output:
|
|
if( radius < 0.5 )
|
|
{
|
|
// interpolation multipliers:
|
|
const int r_x = (int)((xf - x) * 1024);
|
|
const int r_y = (int)((yf - y) * 1024);
|
|
const int r_x_1 = (1024 - r_x);
|
|
const int r_y_1 = (1024 - r_y);
|
|
uint ret_val;
|
|
// linear interpolation:
|
|
ret_val = (r_x_1 * r_y_1 * (int)(read_imageui(_image, sampler, (int2)(y , x ))).x)
|
|
+ (r_x * r_y_1 * (int)(read_imageui(_image, sampler, (int2)(y , x+1))).x)
|
|
+ (r_x_1 * r_y * (int)(read_imageui(_image, sampler, (int2)(y+1, x ))).x)
|
|
+ (r_x * r_y * (int)(read_imageui(_image, sampler, (int2)(y+1, x+1))).x);
|
|
// return the rounded mean
|
|
ret_val += 2 * 1024 * 1024;
|
|
output[*point] = (uchar)(ret_val / (4 * 1024 * 1024));
|
|
}
|
|
|
|
// calculate borders
|
|
const int x_left = round(xf - radius);
|
|
const int y_top = round(yf - radius);
|
|
const int x_right = round(xf + radius + 1); // integral image is 1px wider
|
|
const int y_bottom = round(yf + radius + 1); // integral image is 1px higher
|
|
int ret_val;
|
|
|
|
ret_val = read_imageui(_integral, sampler, (int2)(y_bottom, x_right)).x; // bottom right corner
|
|
ret_val -= read_imageui(_integral, sampler, (int2)(y_bottom, x_left)).x; // bottom left corner
|
|
ret_val += read_imageui(_integral, sampler, (int2)(y_top, x_left)).x; // top left corner
|
|
ret_val -= read_imageui(_integral, sampler, (int2)(y_top, x_right)).x; // top right corner
|
|
const int area = (x_right - x_left) * (y_bottom - y_top);
|
|
ret_val = (ret_val + area / 2) / area;
|
|
output[*point] = (uchar)(ret_val);
|
|
}
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
__kernel void freak(
|
|
__read_only image2d_t image, // grayescale image
|
|
__read_only image2d_t imgIntegral,
|
|
__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
|
|
)
|
|
{
|
|
const float sizeCst = (float)(NB_SCALES / (FREAK_LOG2 * *nOctaves));
|
|
uchar pointsValue[FREAK_NB_POINTS];
|
|
int thetaIdx = 0;
|
|
int direction0;
|
|
int direction1;
|
|
|
|
int k = get_global_id(0);
|
|
|
|
kpScaleIdx[k] = max( (int)(log(7.0 / FREAK_SMALLEST_KP_SIZE) * sizeCst + 0.5) ,0);
|
|
if( kpScaleIdx[k] >= NB_SCALES )
|
|
kpScaleIdx[k] = NB_SCALES - 1;
|
|
|
|
if( keypoints[k].x <= patternSizes[kpScaleIdx[k]] || // check if the description at this specific position and scale fits inside the image
|
|
keypoints[k].y <= patternSizes[kpScaleIdx[k]] ||
|
|
keypoints[k].x >= get_image_dim(image).y - patternSizes[kpScaleIdx[k]] ||
|
|
keypoints[k].y >= get_image_dim(image).x - patternSizes[kpScaleIdx[k]])
|
|
return;
|
|
|
|
// get the points intensity value in the un-rotated pattern
|
|
for( int i = FREAK_NB_POINTS; i--; )
|
|
{
|
|
meanIntensity(image, imgIntegral, keypoints[k].x, keypoints[k].y,
|
|
*(kpScaleIdx + k), 0, &i, patternLookup, pointsValue);
|
|
}
|
|
direction0 = 0;
|
|
direction1 = 0;
|
|
for( int m = 45; m--; )
|
|
{
|
|
// iterate through the orientation pairs
|
|
const int delta = (pointsValue[ orientationPairs[m].w ] - pointsValue[ orientationPairs[m].x ]);
|
|
direction0 += delta * (orientationPairs[m].y) / 2048; // weight_dx
|
|
direction1 += delta * (orientationPairs[m].z) / 2048; // weight_dy
|
|
}
|
|
|
|
thetaIdx = round(FREAK_NB_ORIENTATION *
|
|
(float)(atan2((float)direction1,(float)direction0) * (180.0 / 3.141592653589793238462643383279502884197169399375)) *
|
|
(1 / 360.0));
|
|
|
|
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--; )
|
|
{
|
|
meanIntensity(image, imgIntegral, keypoints[k].x, keypoints[k].y,
|
|
*(kpScaleIdx + k), thetaIdx, &i, patternLookup, pointsValue);
|
|
}
|
|
|
|
// Extract descriptor
|
|
int cnt = 0;
|
|
for( int n = 0; n<4; n++ )
|
|
{
|
|
for (int m = 8; m >= 1; m--)
|
|
{
|
|
for(int kk = (n*16)+15; kk >= (n*16); --kk, ++cnt)
|
|
{
|
|
descriptors[(k * 64) + kk] *= 2;
|
|
if (pointsValue[(int)descriptionPairs[cnt].x] >= pointsValue[(int)descriptionPairs[cnt].y])
|
|
descriptors[(k * 64) + kk] += 1;
|
|
}
|
|
}
|
|
}
|
|
} |