首页 > 代码库 > 直线拟合算法(续)
直线拟合算法(续)
直线拟合算法(续)
曾经写过一篇博客。介绍直线拟合算法。
http://blog.csdn.net/liyuanbhu/article/details/50866802
给出的代码事实上有一点小问题,就是 den = 0 时会出现除以 0 的错误。
今天正好也有网友问起这个问题。
我就再写一篇短文来说说怎样解决问题。
首先我们知道:
那么
我们还有关于
带入后得到:
也就是要求
有了这些就能够分析分析了。
Dyy>Dxx <script id="MathJax-Element-11" type="math/tex">D_{yy} > D_{xx}</script> 这时数据点落在一条垂直直线上,直线方程为x=xˉ <script id="MathJax-Element-12" type="math/tex">x = \bar x</script>。Dyy=Dxx <script id="MathJax-Element-13" type="math/tex">D_{yy} = D_{xx}</script> 数据均匀分布,找不到特殊的方向,无法拟合直线方程。
依照这个分析。我们能够改进我们的代码:
bool lineFit(const std::vector<cv::Point> &points, double &a, double &b, double &c)
{
int size = points.size();
if(size < 2)
{
a = 0;
b = 0;
c = 0;
return false;
}
double x_mean = 0;
double y_mean = 0;
for(int i = 0; i < size; i++)
{
x_mean += points[i].x;
y_mean += points[i].y;
}
x_mean /= size;
y_mean /= size; //至此。计算出了 x y 的均值
double Dxx = 0, Dxy = 0, Dyy = 0;
for(int i = 0; i < size; i++)
{
Dxx += (points[i].x - x_mean) * (points[i].x - x_mean);
Dxy += (points[i].x - x_mean) * (points[i].y - y_mean);
Dyy += (points[i].y - y_mean) * (points[i].y - y_mean);
}
double lambda = ( (Dxx + Dyy) - sqrt( (Dxx - Dyy) * (Dxx - Dyy) + 4 * Dxy * Dxy) ) / 2.0;
double den = sqrt( Dxy * Dxy + (lambda - Dxx) * (lambda - Dxx) );
if(fabs(den) < 1e-5)
{
if( fabs(Dxx / Dyy - 1) < 1e-5) //这时没有一个特殊的直线方向,无法拟合
{
return false;
}
else
{
a = 1;
b = 0;
c = - x_mean;
}
}
else
{
a = Dxy / den;
b = (lambda - Dxx) / den;
c = - a * x_mean - b * y_mean;
}
return true;
}
直线拟合算法(续)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。