使用单目相机的视觉感知
这个例子展示了如何构建一个能够进行车道边界和车辆检测的单眼摄像机传感器仿真。该传感器将在车辆坐标系中报告这些检测结果。在本例中,您将了解自动驾驶工具箱™使用的坐标系统,以及设计单目相机传感器设计所涉及的计算机视觉技术。
概述
包含ADAS功能或被设计为全自动驾驶的车辆依赖于多个传感器。这些传感器可以包括声纳、雷达、激光雷达和照相机。这个例子说明了单眼相机系统设计中所涉及的一些概念。这样的传感器可以完成许多任务,包括:
车道边界检测
检测车辆、人和其他物体
从自我车辆到障碍物的距离估计
随后,由单眼摄像机传感器返回的读数可用于发出车道偏离警告、碰撞警告,或设计一个车道保持辅助控制系统。与其他传感器一起,它还可以用于实现紧急制动系统和其他安全关键功能。
该例子实现了在一个完全开发的单眼相机系统上发现的特征子集。它检测车道边界和车辆背面,并报告它们在车辆坐标系中的位置。
定义相机配置
了解相机的内在和外在校准参数对于像素和车辆坐标之间的精确转换至关重要。
首先要定义照相机的内在参数。以下参数是在之前使用棋盘校准模式的相机校准程序确定的。你可以使用相机校准器应用程序来获取你的相机。
focalLength = [309.4362, 344.2161]; % [fx, fy] in pixel units %[fx,fy],以像素为单位表示
principalPoint = [318.9034, 257.5352]; % [cx, cy] optical center in pixel coordinates %[cx,cy]光学中心的像素坐标
imageSize = [480, 640]; % [nrows, mcols]
请注意,透镜失真系数被忽略了,因为数据中失真很小。这些参数存储在一个摄影机初始化对象中。
camIntrinsics = cameraIntrinsics(focalLength, principalPoint, imageSize);
接下来,定义相对于车辆底盘的摄像头方向。您将使用此信息建立相机外部,定义三维摄像机坐标系相对于车辆坐标系的位置。
height = 2.1798; % mounting height in meters from the ground 安装高度%,以米为单位
pitch = 14; % pitch of the camera in degrees 摄像机的角度
上述量可以由外函函数返回的旋转和平移矩阵得到。节距指定照相机从水平位置开始的倾斜度。对于本例中使用的照相机,传感器的滚转和偏航都为零。定义内部信息和外部信息的整个配置都存储在单相机对象中。
sensor = monoCamera(camIntrinsics, height, 'Pitch', pitch);
请注意,单摄像头对象设置了一个非常特定的车辆坐标系,其中x轴指向车辆向前,y轴指向车辆的左侧,z轴指向地面向上。
默认情况下,坐标系的原点在地面上,直接在由相机的焦点定义的相机中心的下方。可以通过使用单个照相机对象的传感器位置属性来移动原点。此外,单相机提供图像到车辆和车辆到图像方法之间的图像和车辆坐标系统之间的转换。
注:坐标系之间的转换假设平坦道路。它是基于建立一个同源性矩阵,将成像平面上的位置映射到路面上的位置。非平坦的道路会在距离计算中引入误差,特别是在远离车辆的位置。
加载视频的一帧
在处理整个视频之前,处理单个视频帧,以说明单目相机传感器设计所涉及的概念。
首先,请创建一个可打开视频文件的视频阅读器对象。为了提高内存效率,视频阅读器一次加载一个视频帧。
videoName = 'caltech_cordova1.avi';
videoReader = VideoReader(videoName);
阅读一个包含车道标记和车辆的有趣的框架。
timeStamp = 0.06667; % time from the beginning of the video 从视频一开始开始的时间
videoReader.CurrentTime = timeStamp; % point to the chosen frame 指向所选的框架
frame = readFrame(videoReader); % read frame at timeStamp seconds 读取帧
imshow(frame) % display frame 显示帧
注:本例忽略了镜头失真。如果您担心由镜头失真引起的距离测量误差,在这一点上,您将使用非失真图像函数来消除镜头失真。
创建鸟瞰图像
有许多方法来分割和检测车道标记。其中一种方法是使用鸟瞰图的图像变换。尽管它会产生计算成本,但这种转换提供了一个主要的优势。鸟瞰视图中的车道标记厚度均匀,从而简化了分割过程。属于同一车道的车道标记也变得平行,从而使进一步的分析更加容易。
给定相机设置,鸟瞰对象将原始图像转换为鸟瞰图。此对象允许您指定要使用车辆坐标进行变换的区域。请注意,当摄像机安装高度以米为单位指定时,车辆坐标单位是由单体摄像机对象建立的。例如,如果高度以毫米为单位指定,那么模拟的其余部分将使用毫米。
% Using vehicle coordinates, define area to transform %使用车辆坐标,定义要变换的区域
distAheadOfSensor = 30; % in meters, as previously specified in monoCamera height input
spaceToOneSide = 6; % all other distance quantities are also in meters %所有其他距离量也以米为单位
bottomOffset = 3;
outView = [bottomOffset, distAheadOfSensor, -spaceToOneSide, spaceToOneSide]; % [xmin, xmax, ymin, ymax]
imageSize = [NaN, 250]; % output image width in pixels; height is chosen automatically to preserve units per pixel ratio %输出图像宽度为像素;自动选择高度以保持每像素比的单位
birdsEyeConfig = birdsEyeView(sensor, outView, imageSize);.
生成鸟瞰图。
birdsEyeImage = transformImage(birdsEyeConfig, frame);
figure
imshow(birdsEyeImage
远离传感器的区域更模糊,因为有更少的像素,因此需要更多的插值。
请注意,只要您可以在车辆坐标中定位车道边界候选像素,您就可以在不使用鸟瞰视图的情况下完成后一个处理步骤。
在车辆坐标中找到车道标记
拥有鸟视图图像,您现在可以使用分段车道标记岭功能从路面上分离车道标记候选像素。选择这种技术是因为其简单性和相对有效性。现有的替代分割技术包括语义分割(深度学习)和可操纵过滤器。您可以使用下面的这些技术来获得下一阶段所需的二进制掩码。
下面函数的大多数输入参数都是用世界单位指定的,例如,输入分段车道标记岭的车道标记宽度。世界单位的使用允许您轻松地尝试新的传感器,即使当输入图像大小的变化。这对于使设计更加健壮和灵活,在改变的相机硬件和处理不同的标准在许多国家。
% Convert to grayscale %转换为灰度
birdsEyeImage = rgb2gray(birdsEyeImage);
% Lane marker segmentation ROI in world units %车道标记分割ROI在世界单位
vehicleROI = outView - [-1, 2, -3, 3]; % look 3 meters to left and right, and 4 meters ahead of the sensor %看左右3米,领先传感器4米
approxLaneMarkerWidthVehicle = 0.25; % 25 centimeters 25厘米
% Detect lane features 检测车道特征
laneSensitivity = 0.25;
birdsEyeViewBW = segmentLaneMarkerRidge(birdsEyeImage, birdsEyeConfig, approxLaneMarkerWidthVehicle,...
'ROI', vehicleROI, 'Sensitivity', laneSensitivity);
figure
imshow(birdsEyeViewBW)
定位各个车道标记发生在固定在摄像头传感器上的车辆坐标中。本示例使用一个抛物线车道边界模型,ax^2+bx+c,来表示车道标记。其他的表示形式,如三次多项式或样条曲线,也是可能的。转换到车辆坐标是必要的,否则车道标记曲率不能正确地用抛物线表示,而它受到透视扭曲的影响。
车道模型适用于车辆路径上的车道标记。道路上的车道标志或涂在沥青上的路标将被拒绝。
% Obtain lane candidate points in vehicle coordinates %获取车辆坐标中的车道候选点
[imageX, imageY] = find(birdsEyeViewBW);
xyBoundaryPoints = imageToVehicle(birdsEyeConfig, [imageY, imageX]);
由于分割后的点包含许多不属于实际车道标记的异常值,因此使用基于随机样本共识(RANSAC)的鲁棒曲线拟合算法。
返回抛物线线边界对象、边界数组中的边界及其抛物线参数(a、b、c)。