public double[] GetDescriptor(int x, int y, int scale, double orientation)
{
// Determine descriptor size
double[] descriptor = (this.extended) ? new double[128] : new double[64];
int count = 0;
double cos, sin;
double length = 0;
double cx = -0.5; // Subregion centers for the
double cy = +0.0; // 4x4 Gaussian weighting.
if (!this.invariant)
{
cos = 1;
sin = 0;
}
else
{
cos = System.Math.Cos(orientation);
sin = System.Math.Sin(orientation);
}
// Calculate descriptor for this interest point
int i = -8;
while (i < 12)
{
int j = -8;
i = i - 4;
cx += 1f;
cy = -0.5f;
while (j < 12)
{
cy += 1f;
j = j - 4;
int ix = i + 5;
int jx = j + 5;
int xs = (int)System.Math.Round(x + (-jx * scale * sin + ix * scale * cos), 0);
int ys = (int)System.Math.Round(y + (+jx * scale * cos + ix * scale * sin), 0);
// zero the responses
double dx = 0, dy = 0;
double mdx = 0, mdy = 0;
double dx_yn = 0, dy_xn = 0;
double mdx_yn = 0, mdy_xn = 0;
for (int k = i; k < i + 9; k++)
{
for (int l = j; l < j + 9; l++)
{
// Get coordinates of sample point on the rotated axis
int sample_x = (int)System.Math.Round(x + (-l * scale * sin + k * scale * cos), 0);
int sample_y = (int)System.Math.Round(y + (+l * scale * cos + k * scale * sin), 0);
// Get the Gaussian weighted x and y responses
double gauss_s1 = gaussian(xs - sample_x, ys - sample_y, 2.5f * scale);
double rx = haarX(sample_y, sample_x, 2 * scale);
double ry = haarY(sample_y, sample_x, 2 * scale);
// Get the Gaussian weighted x and y responses on rotated axis
double rrx = gauss_s1 * (-rx * sin + ry * cos);
double rry = gauss_s1 * (rx * cos + ry * sin);
if (this.extended)
{
// split x responses for different signs of y
if (rry >= 0)
{
dx += rrx;
mdx += System.Math.Abs(rrx);
}
else
{
dx_yn += rrx;
mdx_yn += System.Math.Abs(rrx);
}
// split y responses for different signs of x
if (rrx >= 0)
{
dy += rry;
mdy += System.Math.Abs(rry);
}
else
{
dy_xn += rry;
mdy_xn += System.Math.Abs(rry);
}
}
else
{
dx += rrx;
dy += rry;
mdx += System.Math.Abs(rrx);
mdy += System.Math.Abs(rry);
}
}
}
// Add the values to the descriptor vector
double gauss_s2 = gaussian(cx - 2.0, cy - 2.0, 1.5);
descriptor[count++] = dx * gauss_s2;
descriptor[count++] = dy * gauss_s2;
descriptor[count++] = mdx * gauss_s2;
descriptor[count++] = mdy * gauss_s2;
// Add the extended components
if (this.extended)
{
descriptor[count++] = dx_yn * gauss_s2;
descriptor[count++] = dy_xn * gauss_s2;
descriptor[count++] = mdx_yn * gauss_s2;
descriptor[count++] = mdy_xn * gauss_s2;
}
length += (dx * dx + dy * dy + mdx * mdx + mdy * mdy
+ dx_yn + dy_xn + mdx_yn + mdy_xn) * gauss_s2 * gauss_s2;
j += 9;
}
i += 9;
}
// Normalize to obtain an unitary vector
length = System.Math.Sqrt(length);
if (length > 0)
{
for (int d = 0; d < descriptor.Length; ++d)
descriptor[d] /= length;
}
return descriptor;
}