예제 #1
0
// Construct descriptor vector for this interest point
void SurfDescriptor::GetDescriptor(IPoint &ip, bool bUpright, bool bExtended)
{
	int sample_x, sample_y, count = 0;
	int i = 0, ix = 0, j = 0, jx = 0, xs = 0, ys = 0;
	float dx, dy, mdx, mdy, co, si;
	float dx_yn, mdx_yn, dy_xn, mdy_xn;
	float gauss_s1 = (float)0, gauss_s2 = (float)0;
	float rx = (float)0, ry = (float)0, rrx = (float)0, rry = (float)0, len = (float)0;
	float cx = (float)-0.5, cy = (float)0; //Subregion centers for the 4x4 gaussian weighting

	// Get rounded InterestPoint data
	int X = (int)floor(ip.x + (float)0.5);
	int Y = (int)floor(ip.y + (float)0.5);
	int S = (int)floor(ip.scale + (float)0.5);

	// Allocate descriptor memory
	ip.SetDescriptorLength(64);

	if (bUpright)
	{
		co = 1;
		si = 0;
	}
	else
	{
		co = (float)cos(ip.orientation);
		si = (float)sin(ip.orientation);
	}

	//Calculate descriptor for this interest point
	i = -8;
	while (i < 12)
	{
		j = -8;
		i = i - 4;

		cx += (float)1;
		cy = (float)-0.5;

		while (j < 12)
		{
			cy += (float)1;

			j = j - 4;

			ix = i + 5;
			jx = j + 5;

			dx = dy = mdx = mdy = (float)0;
			dx_yn = mdx_yn = dy_xn = mdy_xn = (float)0;

			xs = (int)floor(X + (-jx * S * si + ix * S * co) + (float)0.5);
			ys = (int)floor(Y + (jx * S * co + ix * S * si) + (float)0.5);

			// zero the responses
			dx = dy = mdx = mdy = (float)0;
			dx_yn = mdx_yn = dy_xn = mdy_xn = (float)0;

			for (int k = i; k < i + 9; ++k)
			{
				for (int l = j; l < j + 9; ++l)
				{
					//Get coords of sample point on the rotated axis
					sample_x = (int)floor(X + (-l * S * si + k * S * co) + (float)0.5);
					sample_y = (int)floor(Y + (l * S * co + k * S * si) + (float)0.5);

					//Get the gaussian weighted x and y responses
					gauss_s1 = Gaussian(xs - sample_x, ys - sample_y, (float)2.5 * S);
					rx = (float)img->HaarX(sample_y, sample_x, 2 * S);
					ry = (float)img->HaarY(sample_y, sample_x, 2 * S);

					//Get the gaussian weighted x and y responses on rotated axis
					rrx = gauss_s1 * (-rx * si + ry * co);
					rry = gauss_s1 * (rx * co + ry * si);


					if (bExtended)
					{
						// split x responses for different signs of y
						if (rry >= 0)
						{
							dx += rrx;
							mdx += fabs(rrx);
						}
						else
						{
							dx_yn += rrx;
							mdx_yn += fabs(rrx);
						}

						// split y responses for different signs of x
						if (rrx >= 0)
						{
							dy += rry;
							mdy += fabs(rry);
						}
						else
						{
							dy_xn += rry;
							mdy_xn += fabs(rry);
						}
					}
					else
					{
						dx += rrx;
						dy += rry;
						mdx += fabs(rrx);
						mdy += fabs(rry);
					}
				}
			}

			//Add the values to the descriptor vector
			gauss_s2 = Gaussian(cx - (float)2, cy - (float)2, (float)1.5);

			ip.descriptor[count++] = dx * gauss_s2;
			ip.descriptor[count++] = dy * gauss_s2;
			ip.descriptor[count++] = mdx * gauss_s2;
			ip.descriptor[count++] = mdy * gauss_s2;

			// add the extended components
			if (bExtended)
			{
				ip.descriptor[count++] = dx_yn * gauss_s2;
				ip.descriptor[count++] = dy_xn * gauss_s2;
				ip.descriptor[count++] = mdx_yn * gauss_s2;
				ip.descriptor[count++] = mdy_xn * gauss_s2;
			}

			len += (dx * dx + dy * dy + mdx * mdx + mdy * mdy
					+ dx_yn + dy_xn + mdx_yn + mdy_xn) * gauss_s2 * gauss_s2;

			j += 9;
		}
		i += 9;
	}

	//Convert to Unit Vector
	len = (float)sqrt((double)len);
	if (len > 0)
	{
		for (int d = 0; d < ip.descriptorLength; ++d)
		{
			ip.descriptor[d] /= len;
		}
	}
}