【自动驾驶】车道线拟合算法---最小二乘法拟合直线

概览

关于自动驾驶车道线拟合算法,常用的方法有B样条、三次样条插值、Ransac、最小二乘法等等。
但是针对于高精度地图的车道线拟合,由于车道线坐标点已知,所以不需要有控制点进行约束,那么B样条、贝塞尔曲线等都不太适合;三次样条插值曲线每两个坐标点都拟合一组参数,如果高精度地图为20cm一个点的画,那么100m的道路一条车道线就将有500组参数,对于性能是不乐观的;而Ransac更适用于散点拟合,对于已知的有序点再进行多次迭代也是耗费性能的,所以目前还是以最小二乘法为主流方案。

最小二乘法,又称最小平方法,其实就是深度学习中的均方误差。它通过最小化 误差的平方和 寻找数据的最佳函数匹配。主要作用是从一堆相关数据中求解数据的一般性规律。在图像处理方面多用于各种形状的拟合。

最小二乘拟合直线,主要体现为找到一条直线,使得所有已知的点到这条直线的欧式距离的和最小(或者理解为点到直线的误差平方和最小)。开始之前先引入一个误差的概念。已知直线y=2x。现有点(x1,y1),求误差是多少,答案就是y1 - 2 * x1。

具体使用哪种模型,还是要根据系统的实际需求:

  • 有时要求高速的车道线输出,曲率变化小,那用简单的线性模型就好
  • 有些需要精确地道路模型,那就要求三次曲线或二次曲线
  • 有些是视觉车到模型,那就要考虑引用Ransac或者Catmull_Rom样条曲线

总之,在做算法工作时,没有最好的算法,只有最适合的算法。

车道线的数学模型相关知识点 可阅读 blog

拟合线性方程

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

               y=a+bx
               此处a 对应车道线里的 lateral deviation横向偏移;
               斜率b 对应车道线里的 heading angle车辆航向角 ;

车辆航向角定义

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

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

上式分别对a、b求偏导得:
在这里插入图片描述

整理后得到方程组:
在这里插入图片描述

解上述方程组便可求得直线参数a和b的最佳估计值:
在这里插入图片描述

相关系数r:

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

在这里插入图片描述
在这里插入图片描述

或者 有的公式 除以了 n:
在这里插入图片描述

  • 当r>0时,斜率 = X的标准差 / Y的标准差;
  • 当r<0时,斜率 = -X的标准差 / Y的标准差;

通常用SD线来直观的表示数据的走向:

1)当r<0时,SD线的斜率小于0时,则说明数据负相关,即当x增大时y减少。

2)当r>0时,SD线的斜率大于0时,则说明数据正相关,此时当x增大时y增大。

3)相关系数r的范围在[-1,1]之间,当r=0时表示数据相关系数为0(不相关)。当r=正负1时,表示数据负相关,此(x,y)点数据都在SD线上。

4)r的值越接近正负1说明(x,y)越靠拢SD线,说明数据相关性越强,r的值越接近0说明(x,y)点到SD线的散度越大(越分散),数据相关性越小。

代码实现

void LineFitLeastSquares(float *data_x, float *data_y, int data_n)  
{  
    float A = 0.0;  
    float B = 0.0;  
    float C = 0.0;  
    float D = 0.0;  
    float E = 0.0;  
    float F = 0.0;  
  
    for (int i=0; i<data_n; i++)  
    {  
        A += data_x[i] * data_x[i];  
        B += data_x[i];  
        C += data_x[i] * data_y[i];  
        D += data_y[i];  
    }  
  
    // 计算斜率a和截距b  
    float a, b, temp = 0;  
    if( temp = (data_n*A - B*B) )// 判断分母不为0  
    {  
        a = (data_n*C - B*D) / temp;  
        b = (A*D - B*C) / temp;  
    }  
    else  
    {  
        a = 1;  
        b = 0;  
    }  
  
    // 计算相关系数r  
    float Xmean, Ymean;  
    Xmean = B / data_n;  
    Ymean = D / data_n;  
  
    float tempSumXX = 0.0, tempSumYY = 0.0;  
    for (int i=0; i<data_n; i++)  
    {  
        tempSumXX += (data_x[i] - Xmean) * (data_x[i] - Xmean);  
        tempSumYY += (data_y[i] - Ymean) * (data_y[i] - Ymean);  
        E += (data_x[i] - Xmean) * (data_y[i] - Ymean);  
    }  
    F = sqrt(tempSumXX) * sqrt(tempSumYY);  
  
    float r;  
    r = E / F;  
}  

拟合一元三次方程(高阶方程)

目前的主流方法直接用最小二乘法做三次曲线拟合,但本文以引入为主,上面先以线性最小二乘法引入。 y = ax + b

使残差和最小:
在这里插入图片描述
在自动驾驶中,需要的就是将曲线参数传入控制规划端用以描述道路形状,现阶段主流的拟合方程为一元三次方程,例如MobileEye以C0,C1,C2,C3传出,所以在我们目前的工作中,要做的就是针对点集数据,求出最优参数使得残差最小。由于残差和的表达式是二元函数,因此分别对参数 a, b 求偏导,使其等于0时,得到残差和的最小值:
在这里插入图片描述
在这里插入图片描述

整理后得
在这里插入图片描述

在一次函数的情况下,函数拟合需要计算两个未知量。推广到高阶函数,就需要一个统一公式去做相关运算

在高阶函数下:
在这里插入图片描述
同理我们还是有 n 个自变量
在这里插入图片描述
和观测值
在这里插入图片描述

不妨将上式写成矩阵形式。
在这里插入图片描述
上述矩阵方程记为:
在这里插入图片描述
观测值 Y 写为向量的形式,记为:在这里插入图片描述

同样,使得残差的平方和最小:在这里插入图片描述

将上式右半部展开,得:
在这里插入图片描述
根据矩阵转置相乘的转换关系,可得:在这里插入图片描述
化简为: 在这里插入图片描述
根据矩阵的求导法则:
在这里插入图片描述
即:
在这里插入图片描述
因此 残差平方和 对 各阶系数 的偏导为:
在这里插入图片描述
化简后,我们得到高阶函数各项系数的最优取值:在这里插入图片描述

面对线性数学模型参数矩阵较大时,求逆矩阵的耗时较大,上式的直接求逆可能就略显鸡肋,一般需要通过QR分解、Cholesky分解、SVD分解进行求解

在这里插入图片描述

面对非线性数学模型,无法直接写出导数或者导数过于复杂,也无法用上述矩阵分解的方式求解,所以一般会请来我们认识的雅克比、海塞来求解,目前主流的方法为:最速下降法、牛顿法、高斯牛顿法、LM等等进行迭代求解,也可以依赖ceres库、G2O库进行求解,后面也会依次介绍。

代码实现

#include <iostream>
#include <Eigen/src/Cholesky/LDLT.h>

Eigen::VectorXd Ls(std::vector<double>& x,std::vector<double>&y)
{
Eigen::Map<Eigen::VectorXd> sampleX(x.data(), static_cast<long>(x.size()));
Eigen::Map<Eigen::VectorXd> sampleY(y.data(), static_cast<long>(y.size()));
Eigen::MatrixXd mtxVandermonde(x.size(), 4);
Eigen::VectorXd colVandermonde = sampleX;
for (int ii = 0; ii < 4; ++ii)
{
if (0 == ii) {
mtxVandermonde.col(0) = Eigen::VectorXd::Constant(static_cast<long>(x.size()), 1, 1);
continue;
}
if (1 == ii) {
mtxVandermonde.col(1) = colVandermonde;
continue;
}
colVandermonde = colVandermonde.array() * sampleX.array();
mtxVandermonde.col(ii) = colVandermonde;
}
Eigen::VectorXd result =(mtxVandermonde.transpose() * mtxVandermonde).inverse() * (mtxVandermonde.transpose()) * sampleY;


return result;
}//代码原文参见
https://zhuanlan.zhihu.com/p/268884807

输出结果后,就得到了数据点拟合曲线的相关参数,即可表达当前道路形状,用于后端控制

参考链接:
https://guyuehome.com/35243
https://blog.csdn.net/qq_36251561/article/details/88020558
https://blog.csdn.net/Naruto_ahu/article/details/8694366

  • 11
    点赞
  • 66
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 最小二乘法是一种优化方法,可以用于拟合直线c。拟合直线c的目标是找到一条直线,使得数据点到该直线的距离之和最小。具体步骤如下: 1. 假设直线c的方程为y = mx + b,其中m为斜率,b为截距。 2. 根据最小二乘法的原理,要使数据点到直线c的距离之和最小,就需要使平方误差的和最小。平方误差的和可以表示为Σ(yi - mx - b)^2,其中yi为第i个数据点的y坐标。 3. 通过对平方误差的和进行求导,并令导数等于零,可以得到斜率和截距的估计值。 4. 解方程组可以得到最终的斜率和截距估计值。 5. 将估计得到的斜率和截距带入直线c的方程中,即可得到拟合直线c。 最小二乘法拟合直线c的优点是可以考虑所有数据点的信息,并且得到的直线能够最大程度地拟合数据点。但是需要注意的是,最小二乘法只适用于平面上的二维数据点。而在实际问题中,数据点可能是多维的,此时需要相应地进行扩展和调整。此外,最小二乘法也对异常值比较敏感,可能会导致拟合结果不准确。因此,在应用最小二乘法进行直线拟合时,需要谨慎地处理异常值,并根据实际情况进行适当调整。 ### 回答2: 最小二乘法是一种常用的数据拟合方法,在拟合直线c时,我们希望找到一条直线,使该直线与给定的一组数据点的残差平方和最小。 假设给定的数据点为(xi,yi),其中i表示第i个数据点。直线c的方程可以表示为:y = mx + b,其中m和b分别是直线的斜率和截距。 要使用最小二乘法拟合直线c,首先需要计算每个数据点到直线的距离(即残差)。然后,我们需要找到使残差平方和最小的斜率和截距。 计算残差的方法是,将每个数据点的x坐标代入直线方程,得到该点在直线上的y坐标,然后将该点的观测y坐标减去预测y坐标即为残差。用残差的平方和来衡量拟合程度。 首先,我们计算斜率m和截距b的估计值。斜率的估计值可以通过以下公式得到:m = Σ((x - x') * (y - y')) / Σ((x - x')^2),其中(x', y')是数据点的均值。截距的估计值可以通过以下公式得到:b = y' - m * x'。 然后,我们可以计算每个数据点的残差平方和:S = Σ(y - (mx + b))^2,其中Σ表示求和。 通过最小化残差平方和,我们可以求得最佳的斜率和截距:m*和b*。 因此,最小二乘法可以帮助我们通过拟合直线c,找到最佳的斜率和截距。这样我们可以使用直线c来预测新的数据点,或者对现有数据进行建模和分析。 ### 回答3: 最小二乘法是一种常用的拟合直线的方法。给定一组离散的数据点{(x1, y1), (x2, y2), ..., (xn, yn)},我们希望找到一条直线y = ax + b能够最好地拟合这些数据点。 假设直线y = ax + b与数据点的偏差为d1, d2, ..., dn。最小二乘法的目标是使这些偏差的平方和最小。因此,我们需要求解以下方程组: ∑d² = ∑(ax + b - yi)² = min 其中,∑表示求和运算,xi和yi是数据点的坐标。 通过对方程组求导,令导数为0,可以求得a和b的最优解: a = (n∑xiyi - ∑xi∑yi) / (n∑xi² - (∑xi)²) b = (1/n)∑yi - a(1/n)∑xi 其中,n表示数据点的个数。 最终,通过计算得到的a和b,我们就可以得到拟合直线y = ax + b的参数。这条直线可以在最小化了数据点与拟合直线之间的偏差平方和的同时,尽量符合原始数据点的分布。 综上所述,最小二乘法通过最小化数据点到拟合直线的偏差平方和来拟合直线c。它在实际应用中被广泛使用,因为它能够有效地进行数据拟合并找到最佳拟合直线

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值