主要内容

车道检测3 d激光雷达点云

这个例子展示了如何检测车道在激光雷达点云。您可以使用强度值返回从激光雷达点云检测自我车辆车道。你可以使用曲线拟合,从而进一步改善该车道检测算法和跟踪曲线的参数。激光雷达车道检测使您能够构建复杂工作流车道保持辅助、车道偏离警告,自适应巡航控制自动驾驶。测试车辆收集激光雷达数据使用激光雷达传感器安装在屋顶。

介绍

车道检测在激光雷达需要检测的直接左和右车道,也称为自我车辆车道,对激光雷达传感器。它包括以下步骤:

  • 感兴趣的区域提取

  • 地平面分割

  • 峰值强度检测

  • 车道检测使用窗口搜索

  • 抛物线多项式拟合

  • 平行车道配件

  • 车道跟踪

本流程图概述的工作流中给出这个例子。

使用激光雷达数据用于车道检测的优点是:

  • 激光雷达点云给路面的三维表示比图像数据,从而减少所需的校准参数找到鸟瞰图。

  • 激光雷达比图像更健壮的不利气候条件检测。

  • 激光雷达数据有一厘米的精度水平,导致准确巷本地化。

下载和激光雷达数据集做准备

激光雷达数据收集在这个例子使用下台os1 - 64通道激光雷达传感器,产生高分辨率的点云。这个数据集包含点云存储单元阵列的pointCloud对象。每个三维点云是由某某位置以及强度信息。

注意:数据的下载时间取决于您的网络连接。MATLAB期间将暂时没有响应这个代码块的执行。

%下载激光雷达数据lidarData = helperGetDataset;

选择第一帧的数据集进行进一步处理。

%选择第一帧ptCloud = lidarData {1};%可视化输入点云图pcshow (ptCloud)标题(“输入激光雷达点云”15)轴([0 50 -15 5 5])视图(35 [-42])

预处理

估计弄点,第一个激光雷达点云预处理。预处理包括以下步骤:

  • 感兴趣的区域提取

  • 地平面分割

%定义ROI米55 xlim = [5];ylim = 3 [3];zlim = 1 [4];投资回报率= [xlim ylim zlim];%作物使用ROI点云指数= findPointsInROI (ptCloud roi);croppedPtCloud =选择(ptCloud、指标);%去除地平面maxDistance = 0.1;referenceVector = (0 0 1);(模型、内围层异常值)= pcfitplane (croppedPtCloud、maxDistance referenceVector);groundPts =选择(croppedPtCloud,内围层);图pcshow (groundPts)标题(地平面的)视图(3)

弄点检测

通过使用滑动窗口检测车道点搜索,在滑动窗口的初步估计是使用一个灰度直方图。

弄点检测主要包括两个步骤:

  • 峰值强度检测

  • 窗口搜索

峰值强度检测

弄点激光雷达点云有不同强度的分布。通常,这些强度占领上部区域直方图分布和出现高峰。计算直方图的强度检测到地平面沿着自我车辆轴(正轴)。的helperComputeHistogramhelper函数创建一个点强度的柱状图。控制箱的数量直方图通过指定本决议。

histBinResolution = 0.2;[histVal, yvals] = helperComputeHistogram (groundPts histBinResolution);图绘制(yvals histVal,“——k”甘氨胆酸)组(,“XDir”,“反向”)举行

通过使用获得山峰直方图helperfindpeakshelper函数。进一步过滤可能弄点基于车道宽度使用helperInitialWindowhelper函数。

(峰值、loc) = helperfindpeaks (histVal);startYs = yvals (loc);巷宽= 4;[startLanePoints, detectedPeaks] = helperInitialWindow (startYs、山峰、巷宽);情节(startYs,山峰,“* r”)情节(startLanePoints detectedPeaks,的噩)传说(“直方图”,“高峰”,“检测峰”,“位置”,“北”)标题(峰值检测的)举行

窗口搜索

窗口搜索是用来检测车道点通过滑动窗口沿着车道曲率方向。窗口搜索包含两个步骤:

  • 窗口初始化

  • 滑动窗口

窗口初始化

检测到的山峰帮助的初始化搜索窗口。初始化搜索窗口与多个箱子颜色/红色、蓝色分别对于左、右车道。

vBinRes = 1;hBinRes = 0.8;numVerticalBins =装天花板((groundPts.XLimits (2)——groundPts.XLimits (1)) / vBinRes);groundPts.XLimits laneStartX = linspace (groundPts.XLimits (1), (2), numVerticalBins);%显示本窗口图pcshow (groundPts)视图(2)helperDisplayBins (laneStartX, startLanePoints (1) hBinRes / 2, groundPts,“红色”);helperDisplayBins (laneStartX startLanePoints (2), hBinRes / 2, groundPts,“蓝”);标题(“滑动窗口初始化”)

滑动窗口

滑动箱从本位置、初始化和迭代地沿着自我车辆(正轴)方向。的helperDetectLaneshelper函数检测车道分和可视化滑动箱里。连续箱沿轴滑动基于前一本内部的强度值。

在弄点地区失踪,用二次多项式函数预测滑动箱。这种情况常发生在有移动物体穿越车道。滑动箱是黄色的箱子预计使用多项式是绿色的。

显示= true;车道= helperDetectLanes (groundPts hBinRes,numVerticalBins startLanePoints,显示);

%的阴谋最终弄点lane1 =车道{1};lane2 =车道{2};图pcshow (groundPts)标题(“发现弄点”)举行p1 = plot3 (lane1 (: 1), lane1 (:, 2), lane1 (:, 3),“性感”);p2 = plot3 (lane2 (: 1), lane2 (:, 2), lane2 (:, 3),“* r”);持有视图(2)lgnd =传奇((p1 p2) {“左车道点”,“右车道点”});集(lgnd,“颜色”,“白色”,“位置”,“southoutside”)

莱恩配件

巷配件包括估计多项式曲线检测车道上点。使用这些多项式以及平行车道约束巷配件。

抛物线多项式拟合

多项式拟合在x - y点使用同样表示为多项式 一个 x 2 + bx + c ,在那里一个,b,c是多项式参数。进行曲线拟合,使用helperFitPolynomial辅助函数,它还处理离群值(RANSAC)算法使用随机样本的共识。估计三维莱恩点,从飞机模型中提取参数的预处理步骤中创建的。飞机模型表示为 斧头 + 通过 + cz + d = 0 ,z坐标是未知的。估计z坐标用的X - y坐标平面方程。

[P1, error1] = helperFitPolynomial (lane1 (:, 1:2), 2, 0.1);[P2, error2] = helperFitPolynomial (lane2 (:, 1:2), 2, 0.1);xval = linspace (5, 80);yval1 = polyval (P1, xval);yval2 = polyval (P2, xval);% z坐标估计modelParams = model.Parameters;zWorld1 = (-modelParams (1) * xval - modelParams (2) * yval1 - modelParams (4)) / modelParams (3);zWorld2 = (-modelParams (1) * xval - modelParams (2) * yval2 - modelParams (4)) / modelParams (3);%安装可视化巷图pcshow (croppedPtCloud)标题(“多项式拟合巷”)举行p1 = plot3 (xval yval1 zWorld1,“y”,“线宽”,0.2);p2 = plot3 (xval yval2 zWorld2,“r”,“线宽”,0.2);lgnd =传奇((p1 p2) {“左车道点”,“右车道点”});集(lgnd,“颜色”,“白色”,“位置”,“southoutside”(2)持有)视图

平行车道配件

车道通常沿着路相互平行。巷配件强劲,使用这个平行约束。当拟合多项式,helperFitPolynomialhelper函数计算,拟合误差。更新新的多项式车道有错误点。更新这个多项式通过转移沿着轴。

lane3d1 = [xval yval1 zWorld1”);lane3d2 = [xval yval2 zWorld2”);%将多项式与沿轴向一个高分%的多项式很低的分数如果error1 > error2 lanePolynomial = P2;如果lane3d1 (1、2) > 0 lanePolynomial (3) = lane3d2(1、2) +巷宽;其他的lanePolynomial (3) = lane3d2(1、2) -巷宽;结束lane3d1 (:, 2) = polyval (lanePolynomial, lane3d1 (: 1));lanePolynomials = [lanePolynomial;P2);其他的lanePolynomial = P1;如果lane3d2 (1、2) > 0 lanePolynomial (3) = lane3d1(1、2) +巷宽;其他的lanePolynomial (3) = lane3d1(1、2) -巷宽;结束lane3d2 (:, 2) = polyval (lanePolynomial, lane3d2 (: 1));lanePolynomials = [P1;lanePolynomial]结束%可视化车道后平行安装图pcshow (ptCloud)轴([0 50 -15 15 5 5])p1 = plot3 (lane3d1 (: 1), lane3d1 (:, 2), lane3d1 (:, 3),“y”,“线宽”,0.2);p2 = plot3 (lane3d2 (: 1), lane3d2 (:, 2), lane3d2 (:, 3),“r”,“线宽”,0.2);视图(90[-90])标题(“上道”)lgnd =传奇((p1 p2) {“左车道点”,“右车道点”});集(lgnd,“颜色”,“白色”,“位置”,“southoutside”)举行

车道跟踪

车道跟踪有助于稳定巷曲率突然抽搐和漂移引起的。这些变化可能发生因为失踪巷点,车道车辆移动,和错误的车道检测。车道跟踪是一个两步的过程:

  • 轨道巷多项式参数 ( 一个 , b ) 控制的曲率多项式。

  • 开始跟踪点来自峰值检测。该参数表示 c 在多项式。

这些参数更新使用卡尔曼滤波器和一个常数加速度运动模型。要发起一个卡尔曼滤波器,使用configureKalmanFilter

%初始值curveInitialParameters = lanePolynomials (1:2);driftInitialParameters = lanePolynomials (:, 3)”;initialEstimateError = (1 1 1) * 1 e 1;motionNoise = (1 1 1) * 1 e;measurementNoise = 10;%配置卡尔曼滤波器curveFilter = configureKalmanFilter (“ConstantAcceleration”,curveInitialParameters、initialEstimateError motionNoise measurementNoise);driftFilter = configureKalmanFilter (“ConstantAcceleration”,driftInitialParameters、initialEstimateError motionNoise measurementNoise);

遍历数据

循环和过程使用的激光雷达数据helperLaneDetector助手类。这个助手类实现了前面的所有步骤,执行额外的预处理来消除车辆从点云。这确保了检测地面点是平坦和飞机模型是准确的。这类方法detectLanes检测和提取车道分左边和右边车道双元素单元阵列,其中第一个元素对应于左边的车道,第二个元素向右车道。

%初始化随机数生成器rng (2020) numFrames =元素个数(lidarData);探测器= helperLaneDetector (“投资回报”,40 3 3 4 1 [5]);%打开显示球员= pcplayer (50 [0], [-15 15], [5] 5);漂移= 0 (numFrames, 1);filteredDrift = 0 (numFrames, 1);curveSmoothness = 0 (numFrames, 1);filteredCurveSmoothness = 0 (numFrames, 1);i = 1: numFrames ptCloud = lidarData {};%检测车道detectLanes(探测器,ptCloud);%从卡尔曼滤波器预测多项式预测(curveFilter);预测(driftFilter);%正确使用卡尔曼滤波器多项式lanePolynomials = detector.LanePolynomial;漂移(i) =意味着(lanePolynomials (:, 3));curveSmoothness (i) =意味着(lanePolynomials (: 1));updatedCurveParams =正确(curveFilter lanePolynomials (1:2));updatedDriftParams =正确(driftFilter lanePolynomials (:, 3) ');%更新巷多项式updatedLanePolynomials = [repmat (updatedCurveParams 1 [2]), updatedDriftParams”);%多项式估计新巷点更新车道= updateLanePolynomial(检测器,updatedLanePolynomials);filteredDrift (i) =意味着(updatedLanePolynomials (:, 3));filteredCurveSmoothness (i) =意味着(updatedLanePolynomials (: 1));%可视化车道后平行安装ptCloud。颜色= uint8 (repmat ([0 0 255] ptCloud.Count 1));lane3dPc1 = pointCloud(车道{1});lane3dPc1。颜色= uint8 (repmat ([255 0 0] lane3dPc1.Count 1));lanePc = pccat ([ptCloud lane3dPc1]);lane3dPc2 = pointCloud(车道{2});lane3dPc2。颜色= uint8 (repmat (lane3dPc2.Count (255 255 0), 1));lanePc = pccat ([lanePc lane3dPc2]); view(player,lanePc)结束

结果

分析车道检测结果,比较它们对跟踪车道多项式通过绘制数据。每一个情节比较有和没有的卡尔曼滤波器的参数。第一个情节比较的漂移通道沿轴,第二个情节比较平滑的车道多项式。平滑度被定义为的变化率巷曲线的斜率。

图绘制(漂移)情节(filteredDrift)标题(“莱恩随波逐流轴”)传说(“漂移值”,“过滤漂移值”)

图绘制(curveSmoothness)情节(filteredCurveSmoothness)标题(曲线平滑的)传说(曲线平滑的,“曲线平滑过滤”)

总结

这个例子向您展示了如何检测通道的通道强度点云来自激光雷达传感器。你也学会了如何适应二维多项式发现巷点,并利用地面飞机模型来估计三维莱恩点。你还用卡尔曼滤波跟踪进一步提高车道检测。

金宝app支持功能

helperLoadDatahelper函数将激光雷达数据集加载到MATLAB工作区。

函数reflidarData = helperGetDataset () outputFolder = fullfile (tempdir,批发价格指数的);url =“//www.tatmou.com/金宝appsupportfiles/lidar/data/WPI_LidarData.tar.gz”;lidarDataTarFile = fullfile (outputFolder,“WPI_LidarData.tar.gz”);如果~存在(lidarDataTarFile“文件”mkdir (outputFolder);disp (“下载WPI激光雷达驾驶数据(760 MB)……”);websave (lidarDataTarFile、url);解压(lidarDataTarFile outputFolder);结束%检查焦油。gz文件下载,但不是未压缩的如果~ (fullfile (outputFolder,存在“WPI_LidarData.mat”),“文件”)解压(lidarDataTarFile outputFolder);结束%载激光雷达数据负载(fullfile (outputFolder“WPI_LidarData.mat”),“lidarData”);%选择地区著名的强度值reflidarData =细胞(300 1);数= 1;投资回报率=(-50 -30 30负无穷到正无穷);我= 81:380 pc = lidarData {};印第安纳州= findPointsInROI (pc, roi);reflidarData{数}=选择(pc,印第安纳州);数=计数+ 1;结束结束

helperInitialWindowhelper函数计算起点搜索窗口的使用检测直方图峰值。

函数[yval, detectedPeaks] = helperInitialWindow (yvals,山峰,巷宽)leftLanesIndices = yvals > = 0;rightLanesIndices = yvals < 0;leftLaneYs = yvals (leftLanesIndices);rightLaneYs = yvals (rightLanesIndices);peaksLeft =山峰(leftLanesIndices);peaksRight =山峰(rightLanesIndices);diff = 0(和(leftLanesIndices)和(rightLanesIndices));i = 1: sum (leftLanesIndices)j = 1: sum (rightLanesIndices) diff (i, j) = abs(巷宽- (leftLaneYs (i) - rightLaneYs (j)));结束结束[~,minIndex] = min (diff (:));(行,坳)= ind2sub(大小(diff), minIndex);yval = [leftLaneYs(行)rightLaneYs (col)];detectedPeaks = [peaksLeft(行)peaksRight (col)];estimatedLaneWidth = leftLaneYs(行)——rightLaneYs (col);%如果计算车道宽度范围内,%返回巷的最高峰如果abs (estimatedLaneWidth -巷宽)> 0.5如果马克斯(peaksLeft)马克斯(peaksRight) yval = [leftLaneYs (maxLeftInd)南];detectedPeaks = [peaksLeft (maxLeftInd)南);其他的yval =[南rightLaneYs (maxRightInd)];detectedPeaks =[南rightLaneYs (maxRightInd)];结束结束结束

helperFitPolynomialhelper函数符合RANSAC-based多项式的车道检测到分,计算合适的分数。

函数[P,分数]= helperFitPolynomial(分,学位,分辨率)P = fitPolynomialRANSAC(分,学位,决议);ptsSquare = (polyval (P分(:1))-分(:,2))^ 2;分数=√意味着(ptsSquare));结束

helperComputeHistogramhelper函数计算直方图的强度值点云。

函数[histVal, yvals] = helperComputeHistogram (ptCloud histogramBinResolution) numBins =装天花板((ptCloud.YLimits (2) - ptCloud.YLimits (1)) / histogramBinResolution);numBins-1 histVal = 0 (1);ptCloud.YLimits binStartY = linspace (ptCloud.YLimits (1), (2), numBins);numBins-1 yvals = 0 (1);i = 1: numBins-1 roi =[负15 binStartY (i) binStartY (i + 1)负无穷到正无穷];印第安纳州= findPointsInROI (ptCloud roi);subPc =选择(ptCloud,印第安纳州);如果subPc。计数histVal (i) = (subPc.Intensity)之和;yvals (i) = (binStartY(我)+ binStartY (i + 1) / 2;结束结束结束

helperfindpeakshelper函数从直方图中提取高峰值。

函数[pkHistVal, pkIdx] = helperfindpeaks (histVal) pkIdxTemp =(1:尺寸(histVal 2) ';histValTemp =[南;histVal ';南);tempIdx =(1:长度(histValTemp)。';%只保留任何相邻的第一条相等的值(包括南)yFinite = ~ isnan (histValTemp);iNeq = [1;1 +找到(histValTemp (1: end-1) ~ = histValTemp(2:结束)&(yFinite (1: end-1) | yFinite(2:结束))));tempIdx = tempIdx (iNeq);%首样导数的符号s =符号(diff (histValTemp (tempIdx)));%找到当地的最大值maxIdx = 1 +找到(diff (s) < 0);%索引到原始的索引向量没有南书挡pkIdx = tempIdx (maxIdx) - 1;%获取坐标的高峰pkHistVal = histVal (pkIdx);pkIdx = pkIdxTemp (pkIdx)”;结束

引用

[1]Ghallabi,法鲁克,Fawzi Nashashibi, Ghayath El-Haj-Shhade,和Marie-Anne Mittet。“LIDAR-Based车道标记检测车辆定位在一个高清地图。”In 2018 21st International Conference on Intelligent Transportation Systems (ITSC), 2209-14. Maui: IEEE, 2018. https://doi.org/10.1109/ITSC.2018.8569951.

[2]Thuy迈克尔和费尔南多·莱昂。“基于激光雷达数据的车道检测和跟踪。”Metrology and Measurement Systems 17, no. 3 (2010): 311-322. https://doi.org/10.2478/v10178-010-0027-3.