亚像素的对位

2022-07-27,

1,原始图进行模板匹配,得到得分Mat;

2,将找出得分Mat最佳匹配点;

3,将最佳匹配点周围9个像素,进行计算亚像素;

经过金字塔逐步扩大100倍的方法测试,这种亚像素精度在0.02像素。

//调用
	Point MatchingPoint;
	float score[9];
	int num = 0;
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			score[num] = resultMat.at<float>(i + MatchingPoint.y - 1, j + MatchingPoint.x - 1);
			num++;
		}
	}
	Point2f MatchingPoint2f = Point2f(MatchingPoint) + CalcSubpixLocation(score);

 

//亚像素计算
Point2f CalcSubpixLocation(float score[9])
{
	Point loc[9] = { { -1, -1 },{ 0, -1 },{ 1, -1 },{ -1, 0 },{ 0, 0 },{ 1, 0 },{ -1, 1 },{ 0, 1 },{ 1, 1 } };
	int x1, x2, x3, x4;
	int y1, y2, y3, y4;
	int x1y1, x2y1, x1y2, x2y2, x1y3, x3y1;
	float c1, c1x1, c1y1, c1x2, c1y2, c1x1y1;

	x1 = x2 = x3 = x4 = 0;
	y1 = y2 = y3 = y4 = 0;
	x1y1 = x2y1 = x1y2 = x2y2 = x1y3 = x3y1 = 0;
	c1 = c1x1 = c1y1 = c1x2 = c1y2 = c1x1y1 = 0;

	for (int i = 0; i<9; i++)
	{
		int lx = loc[i].x;
		int ly = loc[i].y;

		x1 += lx;
		x2 += lx*lx;
		x3 += lx*lx*lx;
		x4 += lx*lx*lx*lx;

		y1 += ly;
		y2 += ly*ly;
		y3 += ly*ly*ly;
		y4 += ly*ly*ly*ly;

		x1y1 += lx*ly;
		x2y1 += lx*lx*ly;
		x1y2 += lx*ly*ly;
		x2y2 += lx*lx*ly*ly;
		x1y3 += lx*ly*ly*ly;
		x3y1 += lx*lx*lx*ly;

		float sc = score[i];
		c1 += sc;
		c1x1 += sc*lx;
		c1y1 += sc*ly;
		c1x2 += sc*lx*lx;
		c1y2 += sc*ly*ly;
		c1x1y1 += sc*lx*ly;
	}

	Mat MA = Mat::zeros(6, 6, CV_32FC1);
	MA.at<float>(0, 0) = 9.f;
	MA.at<float>(0, 1) = x1;
	MA.at<float>(0, 2) = y1;
	MA.at<float>(0, 3) = x2;
	MA.at<float>(0, 4) = x1y1;
	MA.at<float>(0, 5) = y2;

	MA.at<float>(1, 0) = x1;
	MA.at<float>(1, 1) = x2;
	MA.at<float>(1, 2) = x1y1;
	MA.at<float>(1, 3) = x3;
	MA.at<float>(1, 4) = x2y1;
	MA.at<float>(1, 5) = x1y2;

	MA.at<float>(2, 0) = y1;
	MA.at<float>(2, 1) = x1y1;
	MA.at<float>(2, 2) = y2;
	MA.at<float>(2, 3) = x2y1;
	MA.at<float>(2, 4) = x1y2;
	MA.at<float>(2, 5) = y3;

	MA.at<float>(3, 0) = x2;
	MA.at<float>(3, 1) = x3;
	MA.at<float>(3, 2) = x2y1;
	MA.at<float>(3, 3) = x4;
	MA.at<float>(3, 4) = x3y1;
	MA.at<float>(3, 5) = x2y2;

	MA.at<float>(4, 0) = x1y1;
	MA.at<float>(4, 1) = x2y1;
	MA.at<float>(4, 2) = x1y2;
	MA.at<float>(4, 3) = x3y1;
	MA.at<float>(4, 4) = x2y2;
	MA.at<float>(4, 5) = x1y3;

	MA.at<float>(5, 0) = y2;
	MA.at<float>(5, 1) = x1y2;
	MA.at<float>(5, 2) = y3;
	MA.at<float>(5, 3) = x2y2;
	MA.at<float>(5, 4) = x1y3;
	MA.at<float>(5, 5) = y4;

	Mat MB = MA.inv();

	Mat MC = Mat::zeros(6, 1, CV_32FC1);
	MC.at<float>(0, 0) = c1;
	MC.at<float>(1, 0) = c1x1;
	MC.at<float>(2, 0) = c1y1;
	MC.at<float>(3, 0) = c1x2;
	MC.at<float>(4, 0) = c1x1y1;
	MC.at<float>(5, 0) = c1y2;

	Mat MD = MB * MC;
	
	float a0, a1, a2, a3, a4, a5;
	a0 = MD.at<float>(0, 0);
	a1 = MD.at<float>(1, 0);
	a2 = MD.at<float>(2, 0);
	a3 = MD.at<float>(3, 0);
	a4 = MD.at<float>(4, 0);
	a5 = MD.at<float>(5, 0);

	float x = (2 * a1*a5 - a2*a4) / (a4*a4 - 4 * a3*a5);
	float y = (2 * a2*a3 - a1*a4) / (a4*a4 - 4 * a3*a5);

	//printf("x:%4.4f, y:%4.4f\n", x, y);

	Point2f shift = { x, y };
	return shift;
}

本文地址:https://blog.csdn.net/qq_30263737/article/details/110168882

《亚像素的对位.doc》

下载本文的Word格式文档,以方便收藏与打印。