手把手教用matlab做无人驾驶(九)--项目1:使用单目相机检测车道线

现在介绍一个项目,这个项目跟优达学城的课程有点像,可以学习一下.。

  不管是含有ADAS功能的车还是依赖于多种传感器设计的自动驾驶汽车,它们需要的传感器都包括超声波、雷达、激光雷达和摄像头。接下来的项目阐述的是用单目相机实现自动驾驶过程中一部分内容,实现的内容如下:

1.车道线检测

2.检测机动车,行人以及另一些物体。

3.判断自己车与物体的距离。

1.定义相机配置

对于像素坐标与车辆坐标的精确转换,知道摄像机固有和外部校准参数是重要的 ,首先定义相机的内部参数。以下参数可以使用摄像机通过棋盘格方式标定进行确定。你也可以使用 MATLAB中的 Camera Calibrator app(具体步骤见地址:https://ww2.mathworks.cn/help/vision/camera-calibration-and-3-d-vision.html) 来获取你相机的内部参数。下面给出相机内参:

focalLength    = [309.4362, 344.2161]; % [fx, fy] in pixel units
principalPoint = [318.9034, 257.5352]; % [cx, cy] optical center in pixel coordinates
imageSize      = [480, 640];           % [nrows, mcols]

这些参数被存储在cameraIntrinsics中。

camIntrinsics = cameraIntrinsics(focalLength, principalPoint, imageSize);

接下来,定义相对于车辆底盘的摄像机位置,

手把手教用matlab做无人驾驶(九)--项目1:使用单目相机检测车道线_第1张图片

注意,单目像机设置一个非常具体的车体坐标。其中X轴指向车辆前方,Y轴指向车辆左侧,Z轴从地面上指向天空。

坐标系的远点在地面上,直接在的摄像机中心的正下方。

这里给出相机相对坐标参数:

height = 2.1798;    % mounting height in meters from the ground
pitch  = 14;        % pitch of the camera in degrees
sensor = monoCamera(camIntrinsics, height, 'Pitch', pitch);

2.导入视频

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

手把手教用matlab做无人驾驶(九)--项目1:使用单目相机检测车道线_第2张图片

3.创建鸟瞰图(程序后面都有注释)

% 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)

手把手教用matlab做无人驾驶(九)--项目1:使用单目相机检测车道线_第3张图片

车辆坐标中的车道标志

% Convert to grayscale
birdsEyeImage = rgb2gray(birdsEyeImage);

% Lane marker segmentation ROI in world units
vehicleROI = outView - [-1, 2, -3, 3]; % look 3 meters to left and right, and 4 meters ahead of the sensor
approxLaneMarkerWidthVehicle = 0.25; % 25 centimeters

% Detect lane features
laneSensitivity = 0.25;
birdsEyeViewBW = segmentLaneMarkerRidge(birdsEyeImage, birdsEyeConfig, approxLaneMarkerWidthVehicle,...
    'ROI', vehicleROI, 'Sensitivity', laneSensitivity);

figure
imshow(birdsEyeViewBW)

手把手教用matlab做无人驾驶(九)--项目1:使用单目相机检测车道线_第4张图片

% Obtain lane candidate points in vehicle coordinates
[imageX, imageY] = find(birdsEyeViewBW);
xyBoundaryPoints = imageToVehicle(birdsEyeConfig, [imageY, imageX]);
maxLanes      = 2; % look for maximum of two lane markers
boundaryWidth = 3*approxLaneMarkerWidthVehicle; % expand boundary width

[boundaries, boundaryPoints] = findParabolicLaneBoundaries(xyBoundaryPoints,boundaryWidth, ...
    'MaxNumBoundaries', maxLanes, 'validateBoundaryFcn', @validateBoundaryFcn);

决定车道边界

在上面程序中,我们找到的曲线有可能是无效的,例如,当曲线拟合到人行横道标志时,用另一些方法去删除这样的曲线:

% Establish criteria for rejecting boundaries based on their length
maxPossibleXLength = diff(vehicleROI(1:2));
minXLength         = maxPossibleXLength * 0.60; % establish a threshold

% Reject short boundaries
isOfMinLength = arrayfun(@(b)diff(b.XExtent) > minXLength, boundaries);
boundaries    = boundaries(isOfMinLength);
% To compute the maximum strength, assume all image pixels within the ROI
% are lane candidate points
birdsImageROI = vehicleToImageROI(birdsEyeConfig, vehicleROI);
[laneImageX,laneImageY] = meshgrid(birdsImageROI(1):birdsImageROI(2),birdsImageROI(3):birdsImageROI(4));

% Convert the image points to vehicle points
vehiclePoints = imageToVehicle(birdsEyeConfig,[laneImageX(:),laneImageY(:)]);

% Find the maximum number of unique x-axis locations possible for any lane
% boundary
maxPointsInOneLane = numel(unique(vehiclePoints(:,1)));

% Set the maximum length of a lane boundary to the ROI length
maxLaneLength = diff(vehicleROI(1:2));

% Compute the maximum possible lane strength for this image size/ROI size
% specification
maxStrength   = maxPointsInOneLane/maxLaneLength;

% Reject weak boundaries
isStrong      = [boundaries.Strength] > 0.4*maxStrength;
boundaries    = boundaries(isStrong);
boundaries = classifyLaneTypes(boundaries, boundaryPoints);

% Locate two ego lanes if they are present
xOffset    = 0;   %  0 meters from the sensor
distanceToBoundaries  = boundaries.computeBoundaryModel(xOffset);

% Find candidate ego boundaries
leftEgoBoundaryIndex  = [];
rightEgoBoundaryIndex = [];
minLDistance = min(distanceToBoundaries(distanceToBoundaries>0));
minRDistance = max(distanceToBoundaries(distanceToBoundaries<=0));
if ~isempty(minLDistance)
    leftEgoBoundaryIndex  = distanceToBoundaries == minLDistance;
end
if ~isempty(minRDistance)
    rightEgoBoundaryIndex = distanceToBoundaries == minRDistance;
end
leftEgoBoundary       = boundaries(leftEgoBoundaryIndex);
rightEgoBoundary      = boundaries(rightEgoBoundaryIndex);

在鸟瞰视图图像中显示检测到的车道标志,并在常规视角中显示:

xVehiclePoints = bottomOffset:distAheadOfSensor;
birdsEyeWithEgoLane = insertLaneBoundary(birdsEyeImage, leftEgoBoundary , birdsEyeConfig, xVehiclePoints, 'Color','Red');
birdsEyeWithEgoLane = insertLaneBoundary(birdsEyeWithEgoLane, rightEgoBoundary, birdsEyeConfig, xVehiclePoints, 'Color','Green');

frameWithEgoLane = insertLaneBoundary(frame, leftEgoBoundary, sensor, xVehiclePoints, 'Color','Red');
frameWithEgoLane = insertLaneBoundary(frameWithEgoLane, rightEgoBoundary, sensor, xVehiclePoints, 'Color','Green');

figure
subplot('Position', [0, 0, 0.5, 1.0]) % [left, bottom, width, height] in normalized units
imshow(birdsEyeWithEgoLane)
subplot('Position', [0.5, 0, 0.5, 1.0])
imshow(frameWithEgoLane)

手把手教用matlab做无人驾驶(九)--项目1:使用单目相机检测车道线_第5张图片手把手教用matlab做无人驾驶(九)--项目1:使用单目相机检测车道线_第6张图片

定位车辆坐标

检测与跟踪汽车对前碰撞报警系统(FCW)和自动紧急刹车系统(ABE)是至关重要的。

detector = vehicleDetectorACF();

% Width of a common vehicle is between 1.5 to 2.5 meters
vehicleWidth = [1.5, 2.5];
monoDetector = configureDetectorMonoCamera(detector, sensor, vehicleWidth);

[bboxes, scores] = detect(monoDetector, frame);
locations = computeVehicleLocations(bboxes, sensor);

% Overlay the detections on the video frame
imgOut = insertVehicleDetections(frame, locations, bboxes);
figure;
imshow(imgOut);

手把手教用matlab做无人驾驶(九)--项目1:使用单目相机检测车道线_第7张图片

 

问题:

1.你知道怎么把图片转化为鸟瞰图吗?

2.你知道怎么拟合车道边界吗?

3.怎么决定车道标记,如人行道干扰,还有车道有的是实线,有的是虚线?

4.怎么定位车辆坐标?

 

 

 

 

你可能感兴趣的:(matlab,automation)