OpenCV 最小二乘拟合方法求取直线倾角

工业相机拍摄的图像中,由于摄像质量的限制,图像中的直线经过处理后,会表现出比较严重的锯齿。在这种情况下求取直线的倾角(其实就是直线的斜率),如果是直接选取直线的开始点和结束点来计算,或是用opencv自带的哈夫曼直线方法,都会引起较大的角度偏差,一般会达到好几度。误差这么大,显然达不到工控要求。后来尝试采取直线点集做最小二乘拟合,误差缩小到0.5以下。以下是算法的代码:

	//最小二乘拟合计算直线的倾角
	int pointCount = pointVect.size();
	if (pointCount > 0)
	{
		int xCount = 0;
		int yCount = 0;
		int xyCount = 0;
		int xxCount = 0;
		for (int i = 0; i< pointCount; i++)
		{
			xCount += pointVect.at(i).x;
			yCount += pointVect.at(i).y;
			xyCount += (pointVect.at(i).x * pointVect.at(i).y);
			xxCount += (pointVect.at(i).x * pointVect.at(i).x);
		}
		double k = (double)(pointCount * xyCount - xCount * yCount) / (double)(pointCount * xxCount - xCount * xCount);
		double sinValue = - k / (sqrt(1 + k * k));
		double radian = asin(sinValue);
	        double pi = 3.1415926535;
	        double angle = radian * 180.0 / pi;
	}


下面是最小二乘的理论基础:

摘自http://blog.sina.com.cn/s/blog_648868460100hevs.html

曲线拟合中最基本和最常用的是直线拟合。设xy之间的函数关系为:

                   ya+bx

式中有两个待定参数,a代表截距,b代表斜率。对于等精度测量所得到的N组数据xiyi),i12……,Nxi值被认为是准确的,所有的误差只联系着yi下面利用最小二乘法把观测数据拟合为直线。     

用最小二乘法估计参数时,要求观测值yi的偏差的加权平方和为最小。对于等精度观测值的直线拟合来说,可使下式的值最小:

上式分别对a、b求偏导得:
    OpenCV 最小二乘拟合方法求取直线倾角_第1张图片

整理后得到方程组

最小二乘法拟合直线


    解上述方程组便可求得直线参数ab的最佳估计值。

OpenCV 最小二乘拟合方法求取直线倾角_第2张图片

相关系数r:

最小二乘法处理数据除给出ab外,常常还给出相关系数r,  r定义为

最小二乘法拟合直线

OpenCV 最小二乘拟合方法求取直线倾角_第3张图片 

算例:我用一篇论文中的已知数据作为算例。OpenCV 最小二乘拟合方法求取直线倾角_第4张图片

计算:

代入上面推导出来的计算公式可得:

a=13.6284394650024    b=-0.0799231779033084



你可能感兴趣的:(OpenCV 最小二乘拟合方法求取直线倾角)