private unsafe int mean(double kx, double ky, int scale, int orientation, int pointIndex)
{
const int CV_FREAK_NB_ORIENTATION = FastRetinaKeypointPattern.Orientations;
const int CV_FREAK_NB_POINTS = FastRetinaKeypointPattern.Points;
// get point position in image
var freak = pattern.lookupTable[
scale * CV_FREAK_NB_ORIENTATION * CV_FREAK_NB_POINTS
+ orientation * CV_FREAK_NB_POINTS + pointIndex];
double xf = freak.x + kx;
double yf = freak.y + ky;
int x = (int)(xf);
int y = (int)(yf);
int imagecols = Image.Width;
int ret_val;
// get the sigma:
float radius = freak.sigma;
// calculate output:
if (radius < 0.5)
{
// interpolation multipliers:
int r_x = (int)((xf - x) * 1024);
int r_y = (int)((yf - y) * 1024);
int r_x_1 = (1024 - r_x);
int r_y_1 = (1024 - r_y);
byte* ptr = (byte*)Image.ImageData.ToPointer() + x + y * imagecols;
// linear interpolation:
ret_val = (r_x_1 * r_y_1 * (int)(*ptr));
ptr++;
ret_val += (r_x * r_y_1 * (int)(*ptr));
ptr += imagecols;
ret_val += (r_x * r_y * (int)(*ptr));
ptr--;
ret_val += (r_x_1 * r_y * (int)(*ptr));
return ((ret_val + 512) / 1024);
}
// calculate borders
int x_left = (int)(xf - radius + 0.5);
int y_top = (int)(yf - radius + 0.5);
int x_right = (int)(xf + radius + 1.5); // integral image is 1px wider
int y_bottom = (int)(yf + radius + 1.5); // integral image is 1px higher
ret_val = (int)Integral.InternalData[y_bottom, x_right]; // bottom right corner
ret_val -= (int)Integral.InternalData[y_bottom, x_left];
ret_val += (int)Integral.InternalData[y_top, x_left];
ret_val -= (int)Integral.InternalData[y_top, x_right];
ret_val = ret_val / ((x_right - x_left) * (y_bottom - y_top));
return ret_val;
}