主要内容

使用摄像头跟踪多辆车

这个例子展示了如何用安装在车辆上的单目摄像机检测和跟踪多辆车辆。

概述

自动驾驶工具箱™ 提供预训练车辆检测器和多目标跟踪器,以便于跟踪ego车辆周围的车辆。车辆检测器基于ACF功能和更快的R-CNN,这是一种基于深度学习的对象检测技术。检测器可以轻松互换,以查看其对车辆跟踪的影响。

跟踪工作流包括以下步骤:

  1. 定义摄像机内部结构和摄像机安装位置。

  2. 加载并配置预训练车辆检测器。

  3. 建立一个多目标跟踪器。

  4. 为每个视频帧运行检测器。

  5. 用检测结果更新跟踪器。

  6. 以视频方式显示跟踪结果。

配置车辆检测器和多目标跟踪器

在此示例中,您使用预训练的ACF车辆检测器,并将此检测器配置为包含摄像头信息。默认情况下,检测器以多个比例扫描整个图像。通过了解摄像头参数,您可以将检测器配置为仅以合理比例在地平面上检测车辆。

%加载包含摄影机信息的单摄影机对象。d=荷载(“FCWDemoMonoCameraSensor.mat”,“传感器”);装上预先训练好的ACF车辆检测器。ACF检测器使用“聚合”%“通道特性”,这在实践中计算速度很快。“全视图”%模型训练的图像的前,后,左,右%的车辆。检测器=车辆检测器ACF(“众目睽睽”);

要尝试更快的R-CNN车辆探测器,请使用vehicleDetectorFasterRCNN代替。该检测器需要深度学习工具箱™许可证。

通过传感器信息配置检测器。探测器只尝试在地平面以上的图像区域寻找车辆。这可以减少计算并防止虚假检测。

%普通车辆的宽度在1.5 - 2.5米之间。只有一个在此范围内宽度为%的边界框被认为是一个检测%形象上的候选人。车辆宽度= [1.5,2.5];%使用单摄像机传感器和所需宽度配置探测器。检测器=配置检测器摄像机(检测器、d传感器、车辆宽度);%初始化多对象跟踪器,包括设置过滤器,%检测-跟踪分配阈值,衰减和%确认参数。的|setupTracker|函数%本例结束。[tracker, positionSelector] = setupTracker();

在视频中跟踪车辆

在每个时间步,运行检测器,用检测结果更新跟踪器,并在视频中显示跟踪结果。

%安装视频阅读器和播放器videoFile =“05 _highway_lanechange_25s.mp4”;videoReader=videoReader(videoFile);videoPlayer=vision.DeployableVideoPlayer();currentStep=0;snapshot=[];snapTimeStamp=120;cont=hasFrame(videoReader);%更新帧计数器。currentStep=currentStep+1;读取下一帧。帧= readFrame (videoReader);%运行检测器并将返回的结果打包到一个对象中%multiObjectTracker需要。您可以找到| detector对象|%函数。detections = detectObjects(检测器,帧,currentStep);%使用objectDetections的列表,返回更新的轨道%“当前步”时间。确认跟踪=更新跟踪(跟踪、检测、当前步骤);移除远处车辆的履带。confirmedTracks=移除虚拟支架(confirmedTracks、位置选择器、d.sensor.Intrinsics.ImageSize);%插入跟踪注释。frameWithAnnotations = insertTrackBoxes(frame, confirmedTracks, positionSelector, d.sensor);%显示带注释的框架。视频播放器(带注释的框架);%在snapTimeStamp秒进行快照发布如果currentStep == snapTimeStamp snapshot = frameWithAnnotations;结束%如果用户关闭视频播放器图形,则退出循环。cont=hasFrame(视频阅读器)和isOpen(视频播放器);结束

显示跟踪的车辆并显示到车辆的距离。

如果~ isempty(快照)图imshow(快照)结束

图中包含一个坐标轴。轴包含一个image类型的对象。

这里提出的跟踪工作流可以很容易地集成到单目摄像机的视觉感知例如,车辆检测步骤可以增强与跟踪器。要了解自动驾驶工具箱™中的其他跟踪功能,请参见单眼multiObjectTracker

金宝app支持功能

设置跟踪器函数创建一个multiObjectTracker使用卡尔曼滤波器跟踪多个目标。在创建multiObjectTracker考虑以下事项:

  • 过滤器初始化FCN:可能的运动和测量模型。在这种情况下,物体会有匀速运动。参见“定义卡尔曼滤波器”部分。

  • AssignmentThreshold:探测距离轨道有多远。该参数的默认值为30。如果有未分配到轨迹的检测(但应该分配到),则增加该值。如果有检测被分配到太远的轨道,减少这个值。本例使用50。

  • DeletionThreshold:在删除之前的最后Q步骤中,有多少次轨迹没有被分配检测(错过)。滑行是一个术语,用于在没有指定检测(预测)的情况下更新轨道。该参数的默认值是5次更新中有5次未命中。

  • ConfirmationThreshold:轨道确认参数。每个未分配的检测都初始化一个新轨道。其中一些检测可能是假的,所以所有的轨迹都被初始化为试探性的.要确认一个轨迹,至少要检测到它M时代N跟踪器更新。选择MN取决于物体的可见度。本例使用默认的5次更新中的3次检测。

的输出设置跟踪器是:

  • 跟踪器- - -multiObjectTracker为本例配置的。

  • positionSelector-一种矩阵,指定状态向量的哪些元素是位置:position = positionSelector * State

函数[跟踪器,位置选择器]=设置跟踪器()创建跟踪器对象。跟踪器=多对象跟踪器(“FilterInitializationFcn”@initBboxFilter,...“AssignmentThreshold”, 50,...“DeletionThreshold”5,...“确认阈值”[3 - 5]);%状态向量为:[x;vx;y;v;w;大众;h;vh)% [x;y;w;h] =位置选择器*状态positionSelector = [1 0 0 0 0 0 0;...0 0 1 0 0 0 0 0;...0 0 0 1 1 0 0 0;...0 0 0 0 0 0 1 0];结束

initBboxFilter函数定义一个卡尔曼滤波器来过滤边界框测量。

函数过滤器= initBboxFilter(检测)%步骤1:定义运动模型和状态。%对图像上的边界框使用恒定速度模型。%状态为[x;vx;y;v;w;西弗吉尼亚州;h;高压)状态转移矩阵为:% [1 dt 0 0 0 0 0 0;% 0 1 0 0 0 0 0 0;% 0 0 1 dt 0 0 0 0;% 0 0 0 1 0 0 0 0;%0 0 0 1 dt 0;% 0 0 0 0 1 0 0 0;%0.01 dt;% 0 0 0 0 0 0 0 1]%假设dt = 1。本例不考虑时变转换线性卡尔曼滤波器的%模型。dt = 1;cvel = [1 dt;0 1];A = blkdiag(cvel, cvel, cvel, cvel);步骤2:定义过程噪声。过程噪声表示过程中模型的各个部分%不被考虑在内。例如,在匀速模型中,%加速度忽略不计。G1d = [dt ^ 2/2;dt];Q1d = G1d * G1d ';Q = blkdiag(Q1d, Q1d, Q1d, Q1d);步骤3:定义度量模型。%只测量位置([x;y;w;h])。%测量模型为H = [1 0 0 0 0 0 0 0;...0 0 1 0 0 0 0 0;...0 0 0 1 1 0 0 0;...0 0 0 0 0 0 1 0];步骤4:将传感器测量值映射到初始状态向量。%因为没有速度的测量,所以v分量是%初始化为0:状态=[检测.测量(1);...0;...检测、测量(2);...0;...检测、测量(3);...0;...Detection.Measurement (4);...0);步骤5:将传感器测量噪声映射到一个状态协方差。%对于传感器直接测量的状态部分,使用%相应测量噪声分量。对于那些%传感器不测量,假设初始状态协方差较大。通过这种方式,%未来的检测可以分配到轨道。L=100;%较大的值stateCov =诊断接头([Detection.MeasurementNoise (1, 1),...l...Detection.MeasurementNoise (2, 2),...l...Detection.MeasurementNoise (3),...l...Detection.MeasurementNoise (4, 4),...L]);%步骤6:创建正确的过滤器。在这个例子中,所有的模型都是线性的,所以使用trackingKF作为%跟踪滤波器。过滤器= trackingKF (...“StateTransitionModel”A....“MeasurementModel”H...“状态”、州、...“StateCovariance”,stateCov,...“MeasurementNoise”、检测。MeasurementNoise,...“加工噪音”,Q);结束

detectObjects功能检测图像中的车辆。

函数detections = detectObjects(detector, frame, frameCount)%运行检测器并返回边界框列表:[x、y、w、h]Bboxes = detect(检测器,帧);定义测量噪声。L=100;测量噪声=[L 0;...0 l 0 0;...0 0 l /2 0;...0 L/2];%表示检测为objectDetection报告列表。numDetections=size(b框,1);detections=cell(numDetections,1);对于i=1:numDetections detections{i}=objectDetection(frameCount,bboxes(i,:),...“MeasurementNoise”, measurementNoise);结束结束

removeNoisyTracks函数去除噪声轨道。如果预测的边界框太小,则认为轨道是有噪声的。通常情况下,这意味着车辆在很远的地方。

函数tracks = removeNoisyTracks(tracks, positionSelector, imageSize)如果isempty(跟踪)返回结束%从所有轨迹中提取位置。position = getTrackPositions(tracks, positionSelector);如果预测位置将要移出,轨迹是“无效的”%或者如果边界框太小。无效=(位置(:,1)<1|...> imageSize(2) | . position (:, 1) + position (:, 3...位置(:,3)<=20|...if (position (: 4) <= 20);跟踪(无效)= [];结束

插入跟踪框在图像中插入包围框,并以世界单位显示赛道在赛车前方的位置。

函数I = insertTrackBoxes(I, tracks, positionSelector, sensor)如果isempty(跟踪)返回结束%分配内存。标签= cell(numel(tracks), 1);%检索包围框的位置。bboxes = getTrackPositions(tracks, positionSelector);对于I = 1:numel(tracks) box = bboxes(I,:);使用moncamera对象转换为车辆坐标。xyVehicle=imageToVehicle(传感器,[box(1)+box(3)/2,box(2)+box(4)];标签{i}=sprintf(“x = % .1f, y = % .1f ',xyVehicle(1),xyVehicle(2));结束I=插入对象注释(I,“矩形”、B盒、标签、,“颜色”,“黄色”,...“字形大小”10“TextBoxOpacity”8,“线宽”, 2);结束

另见

功能

物体

相关的话题