主要内容

注释视频使用检测车辆坐标

配置和使用monoCamera对象显示信息中提供的车辆视频显示坐标。

概述

录像上显示数据记录在载体坐标系是不可或缺的一部分地面实况标签和跟踪分析结果。使用一个二维的鸟瞰图可以帮助您了解整个环境,但有时候很难联系鸟瞰图的视频显示。特别是,这个问题变得更糟的是当使用一个第三方的传感器,你不能访问原始视频传感器捕捉到,你需要使用一个视频捕捉到一个单独的相机。

自动驾驶的工具箱™提供了monoCamera对象,促进车辆坐标系和图像坐标系之间的转换。这个例子中读取数据记录的视频传感器安装在测试车辆。则显示数据在一个视频捕捉到一个单独的摄像机安装在同一车。数据和视频记录在以下:

  • 报道车道信息:每秒20倍

  • 报道视觉对象:每秒10倍

  • 视频帧率:20帧每秒

显示一个帧和视频注释

选中的帧对应5.9秒视频,当有几个对象显示在视频。

%设置视频读者和球员videoFile =“01 _city_c2s_fcw_10s.mp4”;videoReader = videoReader (videoFile);放像机= vision.DeployableVideoPlayer;%跳转到所需的框架时间= 5.9;videoReader。CurrentTime =时间;frameWithoutAnnotations = readFrame (videoReader);imshow (frameWithoutAnnotations);标题(原始视频帧的)

图包含一个坐标轴对象。坐标轴对象与标题原创视频帧包含一个类型的对象的形象。

得到相应的记录数据。

recordingFile =“01 _city_c2s_fcw_10s_sensor.mat”;[visionObjects, laneReports,步伐,numSteps] = readDetectionsFile (recordingFile);currentStep =圆(时间/步伐)+ 1;videoDetections = processDetections (visionObjects (currentStep));laneBoundaries = processLanes (laneReports (currentStep));%设置monoCamera对象视频显示传感器= setupMonoCamera (videoReader);frameWithAnnotations = updateDisplay (frameWithoutAnnotations、传感器、videoDetections laneBoundaries);imshow (frameWithAnnotations);标题(带注释的视频帧的)

图包含一个坐标轴对象。坐标轴对象与标题注释视频帧包含一个类型的对象的形象。

显示一个剪辑视频注释

显示视频剪辑与注释,简单地重复注释一帧。视频显示,汽车球略向上和向下,这改变了螺距角。没有一直尝试弥补这俯仰运动。因此,从车辆坐标转换到图像坐标有点不准确的一些帧。

%重置时间回零currentStep = 0;%重置记录数据步伐videoReader。CurrentTime = 0;%重置视频读者时间currentStep < numSteps & & hasFrame (videoReader)%更新场景计数器currentStep = currentStep + 1;%得到当前时间抽搐%准备跟踪检测videoDetections = processDetections (visionObjects (currentStep), videoDetections);%过程通道laneBoundaries = processLanes (laneReports (currentStep));%更新视频帧的注释报道对象frameWithoutAnnotations = readFrame (videoReader);frameWithAnnotations = updateDisplay (frameWithoutAnnotations、传感器、videoDetections laneBoundaries);%的速度记录数据得到20帧每秒。%暂停为50毫秒更现实的显示率。如果你%处理数据和形式跟踪在这个循环中,你不需要这个%的停顿。暂停(0.05 - toc);%显示注释框放像机(frameWithAnnotations);结束

创建Mono相机视频显示

setupMonoCamera函数返回一个monoCamera传感器对象,用于将在车辆坐标转换为图像坐标。

了解相机的内在动力和外在的校准参数精确的像素和车辆坐标之间的转换的关键。

首先定义摄像机内参数。这个函数的参数是根据摄像机模型估计。为你的相机获得的参数,使用相机校准器应用程序。

在这个例子中,因为数据几乎没有变形,这个函数忽略了镜头畸变系数。参数存储在一个cameraIntrinsics对象。

接下来,定义相机外在。相机外在与相机安装在汽车上的方式。安装包括以下属性:

  • 离地面高度:安装高度,在米。

  • 情节:音高的相机,在度,是积极的角度地平线以下,向地面。在大多数情况下,相机是略低于地平线。

  • 对其轴卷:卷相机。例如,如果视频被掀翻,使用滚= 180。

  • 偏航:角相机侧面,正面积极的方向y设在(左)。例如,前置摄像头的偏航角为0度,和一个将摄像头的偏航角为180度。

函数传感器= setupMonoCamera (vidReader)%定义摄像头intrinsic的视频信息focalLength = (1260 - 1100);%(外汇、财政年度)%像素principalPoint = (360 - 245);% (cx, cy] %像素图象尺寸= [vidReader。高度,vidReader.width];% (numRows numColumns] %像素intrinsic = cameraIntrinsics (focalLength principalPoint图象尺寸);%定义摄像机安装(相机外在)mountingHeight = 1.45;%米从地面高度mountingPitch = 1.25;%相机在距度mountingRoll = 0.15;%相机的卷度mountingYaw = 0;%偏航相机的度传感器= monoCamera (intrinsic mountingHeight,“节”mountingPitch,“滚”mountingRoll,“偏航”,mountingYaw);结束

使用Mono相机对象更新显示

updateDisplay函数注释显示所有对象的视频帧。

显示更新包括以下步骤:

  1. 使用monoCamera传感器将检测报告转换成边界框和注释的框架。

  2. 使用insertLaneBoundary的方法parabolicLaneBoundary对象插入巷注释。

函数帧= updateDisplay(框架、传感器、videoDetections laneBoundaries)%分配内存的边界框bboxes = 0(元素个数(videoDetections), 4);%创建边界框i = 1:元素个数(videoDetections)%使用monoCamera传感器将车辆的位置坐标%的位置在图像坐标。%指出:% 1。报告对象的宽度,用于计算%对象周围的边界框的大小(宽度的一半%)。物体的高度不是报道。相反,% 0.85函数使用一个高度/宽度比汽车和3%的行人。% 2。报告的位置是在世贸中心的对象%的水平,即。,the bottom of the bounding box.xyLocation1 = vehicleToImage(传感器、videoDetections(我)。职位' + [0,videoDetections(我).widths / 2]);xyLocation2 = vehicleToImage(传感器、videoDetections(我)。职位”——[0,videoDetections(我).widths / 2]);dx = xyLocation2 (1) - xyLocation1 (1);%定义高度/宽度比基于对象类如果比较字符串(videoDetections .labels(我),“汽车”)dy = dx * 0.85;elseif比较字符串(videoDetections .labels(我),“行人”)dy = dx * 3;其他的dy = dx;结束%估计车辆周围的边界框。减去的高度%定义的边界框的左上角。bboxes(我:)= ((xyLocation1 - [0, dy]), dx, dy);结束%添加标签标签= {videoDetections (:) .labels} ';%添加边界框的框架如果~ isempty(标签)= insertObjectAnnotation帧(帧,“矩形”bboxes,标签,“颜色”,“黄色”,“字形大小”10“TextBoxOpacity”8,“线宽”2);结束%显示车道边界上的视频帧xRangeVehicle = (100);xRangeVehicle xPtsInVehicle = linspace (xRangeVehicle (1), (2), 100) ';= insertLaneBoundary帧(帧,laneBoundaries(1),传感器,xPtsInVehicle,“颜色”,“红色”);= insertLaneBoundary帧(帧,laneBoundaries(2),传感器,xPtsInVehicle,“颜色”,“绿色”);结束

总结

这个例子展示了如何创建一个monoCamera传感器对象,并使用它来显示对象描述了在车辆坐标系在视频捕捉到一个单独的相机。试着用自己的记录数据和一个视频摄像头。校准你的相机来创建一个尝试monoCamera允许从车辆图像坐标转换,反之亦然。

金宝app支持功能

readDetectionsFile——读取传感器数据记录文件。记录的数据在一个单一的结构,分为四个结构体数组。这个示例只使用以下两个数组:

  1. laneReports,一个结构体数组报告巷的边界。它有这些字段:正确的。数组的每个元素对应一个不同的步伐。这两个正确的与这些领域的结构:isValid,信心,boundaryType,抵消,headingAngle,曲率

  2. visionObjects一个结构体数组,报告发现视觉对象。它的字段numObjects(整数),对象(结构体)。数组的每个元素对应一个不同的步伐。对象是一个结构体数组,其中每个元素是一个单独的对象与这些字段:id,分类,位置(x, y, z),速度(vx; v; vz),大小(dx, dy, dz)。注意:z = v = vz = dx = dz = 0

函数[visionObjects, laneReports,步伐,numSteps] = readDetectionsFile(文件名)=负载(strcat(文件名));visionObjects = A.vision;laneReports = A.lane;%准备一些时间变量步伐= 0.05;%巷提供数据每50毫秒numSteps =元素个数(visionObjects);%的数量记录的步伐结束

processDetections——读取记录视力检测。这个例子只提取以下属性:

  1. 位置:一个二维(x, y)在车辆坐标数组

  2. 宽度:对象的宽度所报道的视频传感器(注:传感器不报告任何其他对象的尺寸大小。)

  3. 标签:报道对象的分类

函数videoDetections = processDetections (visionData videoDetections)%的视频传感器报告分类值为整数%根据下面的枚举(从0开始)ClassificationValues = {“未知”,不知名的小的,未知的大的,“行人”,“自行车”,“汽车”,“卡车”,“障碍”};%的总数传感器报告的对象在这个框架numVideoObjects = visionData.numObjects;%的视频对象是每秒只有10次,但视频% 20帧每秒的帧速率。防止注释%闪烁,这个函数返回之前的值%步伐如果没有视频对象。如果numVideoObjects = = 0如果输入参数个数= = 1%返回一个结果,即使没有前一个值videoDetections =结构(“职位”{},“标签”{},“宽度”,{});结束返回;其他的%准备视频检测的相关属性的容器videoDetections =结构(“职位”[],“标签”[],“宽度”[]);i = 1: numVideoObjects videoDetections(我)。宽度= visionData.object (i) .size (2);videoDetections(我)。位置= visionData.object (i) .position (1:2);videoDetections(我)。标签= ClassificationValues {visionData.object(我)。分类+ 1};结束结束结束

processLanes——读车道信息并将其转换成报告parabolicLaneBoundary对象。

车道边界的基础上更新laneReports从录音。道作为参数的传感器报告一个抛物线模型:% y = 一个 x 2 + b x + c

函数laneBoundaries = processLanes (laneReports)%返回车道边界处理%边界类型信息类型= {“无名”,“固体”,“冲”,“无名”,“BottsDots”,“无名”,“无名”,“DoubleSolid”};%阅读记录的车道报告框架leftLane = laneReports.left;rightLane = laneReports.right;%为左和右车道边界创建parabolicLaneBoundary对象leftParams = ([leftLane。曲率,leftLane。headingAngle,左Lane.offset],“双”);leftBoundaries = parabolicLaneBoundary (leftParams);leftBoundaries。BoundaryType =类型{leftLane.boundaryType};rightParams = ([rightLane。曲率,rightLane。headingAngle,正确的Lane.offset],“双”);rightBoundaries = parabolicLaneBoundary (rightParams);rightBoundaries。BoundaryType =类型{rightLane.boundaryType};laneBoundaries = [leftBoundaries, rightBoundaries];结束

另请参阅

应用程序

功能

对象

相关的话题