注:本文章仅作为个人附件链接使用,请勿转载。
MATLAB在2017年的2017a版本中推出了自动驾驶工具箱,后面推出的版本又持续更新工具箱。本篇以在MATLAB 2018a下面进行车道线检测。这里只有用到测试集数据,并没有什么训练集,使用的是自动驾驶鸟瞰图转换检测模型。由于测试集较大,所以就不网盘链接分享了,需要跑的朋友请自己准备好测试集,然后把路径改一下即可。下面直接上MATLAB代码:
注释部分可以先不看。
close all;
clear
clc;
addpath D:\FC2017\T1;
addpath D:\xml_io_tools_2010_11_05;
start = tic ;
test_point=290;
task1_dir = 'D:\FC2017\T1\TSD-Lane1';
path = {};%建立一个单元数组,数组的每个单元中包含一个目录
path{1}='D:\FC2017\T1\TSD-Lane\TSD-Lane-00051\';
path{2}='D:\FC2017\T1\TSD-Lane\TSD-Lane-00052\';
path{3}='D:\FC2017\T1\TSD-Lane\TSD-Lane-00056\';
path{4}='D:\FC2017\T1\TSD-Lane\TSD-Lane-00057\';
path{5}='D:\FC2017\T1\TSD-Lane\TSD-Lane-00058\';
path{6}='D:\FC2017\T1\TSD-Lane\TSD-Lane-00065\';
path{7}='D:\FC2017\T1\TSD-Lane\TSD-Lane-00068\';
path{8}='D:\FC2017\T1\TSD-Lane\TSD-Lane-00074\';
path{9}='D:\FC2017\T1\TSD-Lane\TSD-Lane-00076\';
path{10}='D:\FC2017\T1\TSD-Lane\TSD-Lane-00096\';
%至此获得data文件夹及其所有子文件夹(及子文件夹的子文件夹)的路径,存于数组path中。
%下面是逐一文件夹中读取图像
file_num = size(path,2);% 子文件夹的个数
img_counter=0; %图片计数
rotationMatrix=zeros(3,3,'double');
translationVector=zeros(1,3,'double');
%load birdsEyeConfig ,下载鸟瞰图
for i = 4:file_num
file_path = path{i}; % 图像文件夹路径
img_path_list = dir(strcat(file_path,'*.png')); %包含以下字段的空的 0×1 struct 数组:name folder date bytes isdir datenum
img_num = length(img_path_list); %该文件夹中图像数量
if img_num > 0
pos=strfind(file_path,'TSD-Lane'); %返回'TSD-Lane'在file_path出现的位置
GTFile=strcat(file_path(1:pos(1)+7),'-GT\');%GTFile的地址
InfoFile=strcat(file_path(1:pos(1)+7),'-Info\');
GTFile=strcat(GTFile,file_path(pos(2):end-1));
InfoFile=strcat(InfoFile,file_path(pos(2):end-1));
GTFile=strcat(GTFile,'-GT.xml');
InfoFile=strcat(InfoFile,'-Info.xml');
%至此,我们得到了在当前for循环下GTFile和InfoFile的路径,并且每次循环都能保证得到与之相对应的正确路径
XMLFile=xml_read(GTFile); %通过xml_read函数读取XML文件,返回的是1*1的struct
XMLLength=length(XMLFile); %长度为1
XMLField=fieldnames(XMLFile); %401*1的cell
XMLData = struct2cell(XMLFile); %401*1的cell
FrameNumber=XMLData{1,1}; %100
if FrameNumber~=img_num %
msgbox('The image number is wrong!');
break;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
XMLFileInfo=xml_read(InfoFile);%读取XML文件,返回1*1的struct
frame_rate=XMLFileInfo.frame_rate; %
camera_matrix=XMLFileInfo.camera_matrix.data; %1*110char
dataend=strfind(camera_matrix,' '); %
fx=str2double(camera_matrix(1:dataend(1)-1)); %
fy=str2double(camera_matrix(dataend(7)+1:dataend(8)-1));%
cx=str2double(camera_matrix(dataend(2)+1:dataend(3)-1)); %
cy=str2double(camera_matrix(dataend(8)+1:dataend(9)-1)); %
focalLength = [fx, fy]; % [fx, fy]%[1.5841e+03,1.5872e+03]
principalPoint = [cx, cy]; % [cx, cy][667.4675,507.3183]
distortion_coefficients=XMLFileInfo.distortion_coefficients.data;%[0,0,0,0,0]
rotation_matrix=XMLFileInfo.rotation_matrix.data;%1x228 char
dataend=strfind(rotation_matrix,' ');% height in meters from the ground
rotationMatrix(1,1)=str2double(rotation_matrix(1:dataend(1)-1));
rotationMatrix(1,2)=str2double(rotation_matrix(dataend(1)+1:dataend(2)-1));
rotationMatrix(1,3)=str2double(rotation_matrix(dataend(5)+1:dataend(6)-1));
rotationMatrix(2,1)=str2double(rotation_matrix(dataend(6)+1:dataend(7)-1));
rotationMatrix(2,2)=str2double(rotation_matrix(dataend(10)+1:dataend(11)-1));
rotationMatrix(2,3)=str2double(rotation_matrix(dataend(11)+1:dataend(12)-1));
rotationMatrix(3,1)=str2double(rotation_matrix(dataend(15)+1:dataend(16)-1));
rotationMatrix(3,2)=str2double(rotation_matrix(dataend(16)+1:dataend(17)-1));
rotationMatrix(3,3)=str2double(rotation_matrix(dataend(20)+1:end));
translation_vector=XMLFileInfo.translation_vector.data;
dataend=strfind(translation_vector,' ');% height in meters from the ground
translationVector(1,1)=str2double(translation_vector(1:dataend(1)-1));
translationVector(1,2)=str2double(translation_vector(dataend(1)+1:dataend(2)-1));
translationVector(1,3)=str2double(translation_vector(dataend(5)+1:end));
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%将extrinsics转换为相机姿势,如数参数为rotationMatrix和translationVector
%返回[orientation, location],方向和位置
%其中orientation为一个3*3矩阵,location为1*3向量
[orientation, location] = extrinsicsToCameraPose(rotationMatrix, ...
translationVector);
%imageSize = [480, 640]; % [mrows, ncols]
height = location(1)/100; % height in meters from the ground
%height=2.1798;
%pitch=atan2(-rotationMatrix(3,1),sqrt(rotationMatrix(1,1)*rotationMatrix(1,1)+rotationMatrix(2,1)*rotationMatrix(2,1)));
% pitch = atan2(-rotationMatrix(3,1),sqrt(rotationMatrix(3,2)*rotationMatrix(3,2)+rotationMatrix(3,3)*rotationMatrix(3,3))); % pitch of the camera, towards the ground, in degrees
%eulZYZ = rotm2eul(rotationMatrix,'ZYZ');
%pitch = -(eulZYZ(2)/pi*180+90);
if i~=7
pitch=5;
else
pitch=1;
end
%pitch=pitch*90;
% if pitch<0
% pitch=pitch+90;
% else
% pitch=90-pitch;
% end
% Define birds-eye-view transformation parameters
distAheadOfSensor = 65; % in meters 传感器远距
spaceToOneSide = 6.5; % look 6 meters to the right and 6 meters to the left
bottomOffset = 3; % look 3 meters ahead of the sensor
outView = [bottomOffset, distAheadOfSensor, -spaceToOneSide, spaceToOneSide];
outImageSize = [NaN, 250]; % output image width in pixels
%camIntrinsics = cameraIntrinsics(focalLength, principalPoint, imageSize);
%sensor = monoCamera(camIntrinsics, height, 'Pitch', pitch);
PosPoint=2;
GTNum=0;
for j = 1:img_num
img_counter=img_counter+1;
GTNum=XMLData{PosPoint,1};
GTPosition=XMLData(PosPoint+1:i+GTNum);
PosPoint=PosPoint+GTNum+1;
if img_counter==test_point
img_counter=test_point;
end
image_name = img_path_list(j).name;% 图像名
image = imread(strcat(file_path,image_name));
imageSize=size(image);
imageSize=imageSize(1:2);
camIntrinsics = cameraIntrinsics(focalLength, principalPoint, imageSize);
sensor = monoCamera(camIntrinsics, height, 'Pitch', pitch);
birdsEyeConfig = birdsEyeView(sensor, outView, outImageSize);
birdsEyeImage = transformImage(birdsEyeConfig,image);
figure(1);
imshow(image);
I=image;
% hold on;
% plot(XMLData{3, 1}.LeftPoints.data(1,1),XMLData{3, 1}.LeftPoints.data(1,2),'s');
% plot(XMLData{3, 1}.RightPoints.data(1,1),XMLData{3, 1}.RightPoints.data(1,2),'s');
% plot(XMLData{3, 1}.LeftPoints.data(1, 3),XMLData{3, 1}.LeftPoints.data(1,4),'s');
% plot(XMLData{3, 1}.RightPoints.data(1,3),XMLData{3, 1}.RightPoints.data(1,4),'s');
figure(2);
%birdsEyeImage = transformImage(bevSensor.birdsEyeConfig,I);
imshow(birdsEyeImage);
% Convert birds-eye-view image to grayscale.
birdsEyeImage = rgb2gray(birdsEyeImage);
% Set the approximate lane marker width to 25 cm, which is in world units.
approxMarkerWidth = 0.25;
approxBoundaryWidth = 0.25;
%%
birdsEyeBW = segmentLaneMarkerRidge(birdsEyeImage,birdsEyeConfig,approxMarkerWidth);
figure(3);
imshow(birdsEyeBW);
[imageX,imageY,imageZ] = find(birdsEyeBW);
xyBoundaryPoints = imageToVehicle(birdsEyeConfig,[imageY,imageX]);
[boundaries,boundaryPoints] = findParabolicLaneBoundaries(xyBoundaryPoints,approxBoundaryWidth,'MaxSamplingAttempts',3);
% XPoints = 3:65;
%figure(4);
% sensor = birdsEyeConfig.Sensor;
% lanesI = insertLaneBoundary(I,boundaries(1),sensor,XPoints);
% lanesI = insertLaneBoundary(lanesI,boundaries(2),sensor,XPoints,'Color','green');
%lanesI = insertLaneBoundary(lanesI,boundaries(3),sensor,XPoints,'Color','red');
%imshow(lanesI)
%figure(5)
% BEconfig = birdsEyeConfig;
%lanesBEI = insertLaneBoundary(birdsEyeImage,boundaries(1),BEconfig,XPoints);
%lanesBEI = insertLaneBoundary(lanesBEI,boundaries(2),BEconfig,XPoints,'Color','green');
% lanesBEI = insertLaneBoundary(lanesBEI,boundaries(3),BEconfig,XPoints,'Color','red');
%imshow(lanesBEI)
end
end
end
time = toc(start) ;
speed = img_counter/time ;
fprintf('%.1f Hz%s\n', speed) ;
运行结果:
鸟瞰图:
鸟瞰图二值化: