最小二乘法拟合亚像素坐标时不准确问题查找

    前面的文章http://blog.csdn.net/zilanpotou182/article/details/69848610介绍了使用Zernike矩进行亚像素边缘细化的方法,如果我们是检测圆形物体,那么可以使用最小二乘法拟合圆来拟合出圆的半径和坐标,本方法的代码在下面列出。

    有的朋友发现拟合出来的边缘打印出来看着没问题,边缘点是一个圆形的形状,但是拟合出来的圆却偏离这个圆心,并且半径也不对。我也想起当时做双层梁圆孔检测的时候也是遇到这问题,写在这里给大家提醒一下,其实是很简单的错误。

    问题就是检测出来的边缘不仅仅只有圆区域,还有其他一些小的干扰区域,我直接用的他的图,请看左上角有一点干扰区域,但是如果画边缘点的时候所用的半径不够大或者线宽不够宽,则打印出来的边缘图根本看不到这一块,带着这个区域去做最小二乘圆拟合,就会出现一个半径较大且偏移的圆,而如果把这两项调的够大,就可以发现这个问题。

                                             最小二乘法拟合亚像素坐标时不准确问题查找_第1张图片

    滤掉左上角的干扰后在进行拟合就没问题了,结果就不放了。附上最小二乘法圆拟合的代码。

        //最小二乘法拟合圆	
	double x1 = 0.0;
	double x2 = 0.0;
	double x3 = 0.0;
	double y1 = 0.0;
	double y2 = 0.0;
	double y3 = 0.0;
	double x1y1 = 0.0;
	double x1y2 = 0.0; 
	double x2y1 = 0.0;
	for (size_t i = 0; i < SubEdgePoints.size(); i++)
	{
		x1 = x1 + SubEdgePoints[i].x;
		y1 = y1 + SubEdgePoints[i].y;
		x2 = x2 + SubEdgePoints[i].x * SubEdgePoints[i].x;
		y2 = y2 + SubEdgePoints[i].y * SubEdgePoints[i].y;
		x3 = x3 + SubEdgePoints[i].x * SubEdgePoints[i].x * SubEdgePoints[i].x;
		y3 = y3 + SubEdgePoints[i].y * SubEdgePoints[i].y * SubEdgePoints[i].y;
		x1y1 = x1y1 + SubEdgePoints[i].x * SubEdgePoints[i].y;
		x2y1 = x2y1 + SubEdgePoints[i].x * SubEdgePoints[i].x * SubEdgePoints[i].y;
		x1y2 = x1y2 + SubEdgePoints[i].x * SubEdgePoints[i].y * SubEdgePoints[i].y;
	}
	int N = 0;
	double C, D , E ,G , H  ;
	double a , b, c ;
	N = SubEdgePoints.size();
	C = N*x2 - x1*x1;
	D = N*x1y1 - x1*y1;
	E = N*x3 + N*x1y2 - (x2 + y2)*x1;
	G = N*y2 - y1*y1;
	H = N*y3 + N*x2y1 - (x2 + y2)*y1;
	
	a = (H*D - E*G) / (C*G - D*D);
	b = (H*C - E*D) / (D*D - G*C);
	c = -(x2 + y2 + a*x1 + b*y1) / N;
	 
	double A , B , R ;
	A = a / (-2);
	B = b / (-2);
	R = sqrt(a*a+b*b-4*c)/2;



你可能感兴趣的:(物体检测)