本講展示了如何在Ground Truth Labeler應(yīng)用程序中開發(fā)自動標(biāo)記車道邊界的算法。
良好的地面真實數(shù)據(jù)對于開發(fā)駕駛算法和評估其性能至關(guān)重要。然而,創(chuàng)建一套豐富多樣的標(biāo)注駕駛數(shù)據(jù)需要大量的時間和資源。Ground Truth Labeler應(yīng)用程序使這一過程變得高效。可以將該應(yīng)用作為一個完全手動的標(biāo)注工具,為視覺系統(tǒng)標(biāo)注車道邊界、車輛邊界框和其他感興趣的對象。然而,手動標(biāo)注需要大量的時間和資源。這款應(yīng)用程序還提供了一個框架來創(chuàng)建算法,以擴(kuò)展和自動化標(biāo)簽過程??梢允褂脛?chuàng)建的算法來快速標(biāo)記整個數(shù)據(jù)集,然后用更高效、更短的手動驗證步驟進(jìn)行跟進(jìn)。還可以編輯自動化步驟的結(jié)果,以說明自動化算法可能遺漏的挑戰(zhàn)性場景。本示例介紹了如何將車道檢測算法插入到應(yīng)用程序的自動化工作流程中。
3.1 創(chuàng)建車道檢測算法
首先,創(chuàng)建一個車道檢測算法。使用單目攝像頭的視覺感知示例描述了檢測車道邊界的過程,helperMonoSensor類將該算法打包成一個單一的、可重用的類。在單個視頻幀上嘗試該算法來檢測左被控車道邊界。
configData= load('birdsEyeConfig');
sensor = configData.birdsEyeConfig.Sensor;
monoSensor= helperMonoSensor(sensor);
I = imread('road.png');
sensorOut =processFrame(monoSensor, I);
lb =sensorOut.leftEgoBoundary;
figure
IwithLane =insertLaneBoundary(I, lb, sensor, [3 30], 'Color', 'blue');
imshow(IwithLane);
title('DetectedLeft Lane BoundaryModel');
3.2 標(biāo)記邊界點(diǎn)
上一步中檢測到的車道是一個模型,必須轉(zhuǎn)換為一組離散的點(diǎn)。這些點(diǎn)類似于用戶可能手動放置在圖像上的點(diǎn)。在攝像機(jī)視圖中,車道邊界中更靠近車輛的部分(攝像機(jī)圖像的下部)將比更遠(yuǎn)的部分跨越更多的像素。因此,用戶會將更多的點(diǎn)以更高的置信度放置在相機(jī)圖像的較低部分。為了復(fù)制這種行為,從邊界模型中確定車道邊界位置,在更靠近車輛的點(diǎn)上更加密集。
ROI = [3 30];
xPoints = [3 3.5 4 5 7 12 30]'; % Moredense closer to the vehicle
yPoints = lb.computeBoundaryModel(xPoints);
% Findcorresponding image locations
boundaryPointsOnImage= vehicleToImage(sensor, [xPoints, yPoints]);
imshow(I)
hold on
plot(boundaryPointsOnImage(:,1),boundaryPointsOnImage(:,2),...
'o',...
'MarkerEdgeColor','b',...
'MarkerFaceColor','b',...
'MarkerSize',10)
title('AutomaticallyMarked Lane Boundary Points');
hold off
3.3 準(zhǔn)備車道檢測自動化類
要將這個車道檢測算法納入到應(yīng)用程序的自動化工作流程中,請構(gòu)造一個繼承自抽象基類 vision.labeleler.AutomationAlgorithm的類。這個基類為應(yīng)用程序用于配置和運(yùn)行自定義算法的方法定義了屬性和簽名。GroundTruth Labeler 應(yīng)用程序提供了一種獲取初始自動化類模板的便捷方法。AutoLaneMarking類基于該模板,提供了一個用于車道檢測的即用型自動化類。該類的注釋概述了實現(xiàn)每個API調(diào)用所需的基本步驟。 步驟1包含定義算法名稱和描述的屬性,以及使用算法的方向。
%----------------------------------------------------------------------
% Step 1: Define required propertiesdescribing the algorithm. This
% includes Name, Description, and UserDirections.
properties(Constant)
% Name: Give a name for your algorithm.
Name = 'LaneDetector';
% Description: Provide a one-linedescription for your algorithm.
Description = 'Automatically detect lane-like features';
% UserDirections: Provide a set of directions that are displayed
% when this algorithm isinvoked. The directions
% are to be provided as a cellarray of character
% vectors, with each element of the cell array
% representing a step in thelist of directions.
UserDirections = {...
'Load a MonoCamera configurationobject from the workspace using the settings panel',...
'Specify additional parameters in thesettings panel',...
'Run the algorithm',...
'Manually inspect and modify resultsif needed'};
end
步驟2包含核心算法所需的自定義屬性。必要的屬性由上面的車道檢測和車道點(diǎn)創(chuàng)建部分確定。
%---------------------------------------------------------------------
% Step 2: Defineproperties to be used during the algorithm. These are
% user-definedproperties that can be defined to manage algorithm
% execution.
properties
%MonoCamera
% The monoCamera object associated with thisvideo
MonoCamera = [];
%MonoCameraVarname
% The workspace variable name of the monoCamera object
MonoCameraVarname = '';
%BirdsEyeConfig
% The birdsEyeView object needed to create thebird's-eye view
BirdsEyeConfig = [];
%MaxNumLanes
% The maximum number of lanes the algorithmtries to annotate
MaxNumLanes = 2;
%ROI
% The region ofinterest around the vehicle used to search for
% lanes
ROI = [3, 30, -3, 3];
%LaneMaskSensitivity
% The sensitivity parameter used in thesegmentLaneMarkerRidge function
LaneMaskSensitivity= 0.25;
%LaneBoundaryWidth
% The laneboundary width, used infindParabolicLaneBoundaries
LaneBoundaryWidth = 0.6;
%XPoints
% The x-axis points along which to mark the lane boundaries
XPoints = [3 3.5 4 4.5 5 6 7 10 30];
end
第3步是函數(shù)定義。第一個函數(shù)checkLabelDefinition,確保只有適當(dāng)類型的標(biāo)簽才會被啟用以實現(xiàn)自動化。對于車道檢測,您需要確保只啟用類型為Line的標(biāo)簽,所以這個版本的函數(shù)檢查標(biāo)簽的類型:
function TF = checkLabelDefinition(~,labelDef)
% Lanedetection only works with Line type labels
TF =labelDef.Type == labelType.Line;
end
The next functionis checkSetup. Note that this algorithm requires a monoCamera sensor configuration to be available.All other properties have defined reasonable defaults.
function TF = checkSetup(algObj, ~)
% This is the only required input
TF = ~isempty(algObj.MonoCamera);
end
接下來,settingsDialog函數(shù)將獲取并修改步驟2中定義的屬性。通過該 API 調(diào)用,您可以創(chuàng)建一個對話框,當(dāng)用戶點(diǎn)擊自動選項卡中的設(shè)置按鈕時,該對話框就會打開。要創(chuàng)建這個對話框,請使用 inputdlg 函數(shù)快速創(chuàng)建一個簡單的模態(tài)窗口,要求用戶指定 monoCamera 對象。以下代碼片段概述了基本語法。完整的AutoLaneMarking代碼擴(kuò)展了這一邏輯,還增加了輸入驗證步驟。
% Describethe inputs
prompt = {...
'Enter the MonoCamera variable name',...
'Maximum number of Lanes',...
};
defaultAnswer = {...
'',...
num2str(2),...
};
% Create an input dialog
name = 'Settings for lane detection';
numLines = 1;
options.Resize = 'on';
options.WindowStyle = 'normal';
options.Interpreter = 'none';
answer =inputdlg(prompt,name,numLines,defaultAnswer,options);
% Obtain the inputs
monoCameraVarname = answer{1};
maxNumberOfLanes = answer{2};
第四步指定執(zhí)行函數(shù)。一些自動化算法需要實現(xiàn)一個初始化例程,根據(jù)應(yīng)用中現(xiàn)有的標(biāo)簽來填充初始算法狀態(tài)。這個車道檢測算法在每一幀上都是獨(dú)立工作的,所以默認(rèn)版本的模板已經(jīng)被修剪成不采取任何行動:
function initialize(~,~, ~)
end
接下來,run函數(shù)定義了這個自動化類的核心車道檢測算法,每個視頻幀都會調(diào)用run,并期望自動化類返回一組標(biāo)簽。AutoLaneMarking中的run函數(shù)包含了之前介紹的車道檢測和轉(zhuǎn)換為點(diǎn)的邏輯。helperMonoSensor中的代碼也被折疊進(jìn)來,以便更緊湊的參考。
functionautoLabels = run(algObj, I)
Ig = rgb2gray(I);
birdsEyeViewImage =transformImage(algObj.BirdsEyeConfig, Ig);
birdsEyeViewBW = segmentLaneMarkerRidge(birdsEyeViewImage,...
algObj.BirdsEyeConfig,algObj.LaneBoundaryWidth, ...
'Sensitivity',algObj.LaneMaskSensitivity);
% Obtain lane candidate points in world coordinates
[imageX, imageY] = find(birdsEyeViewBW);
boundaryPointsxy =imageToVehicle(algObj.BirdsEyeConfig, [imageY, imageX]);
% Fit requested number of boundariesto it
lbs =findParabolicLaneBoundaries(...
boundaryPointsxy,algObj.LaneBoundaryWidth, ...
'MaxNumBoundaries',algObj.MaxNumLanes);
numDetectedLanes = numel(lbs);
% Convert the model to discrete set of points at the specified
% x coordinates
boundaryPoints = cell(1,numDetectedLanes);
xPoints = algObj.XPoints';
for ind = 1:numel(lbs)
yPoints =lbs(ind).computeBoundaryModel(xPoints);
boundaryPoints{ind} =vehicleToImage(algObj.MonoCamera, [xPoints, yPoints]);
end
% Package up the results in a table
autoLabels = table(...
boundaryPoints',...
repmat(labelType.Line,[numDetectedLanes,1]),...
repmat(algObj.SelectedLabelDefinitions.Name, [numDetectedLanes,1]));
autoLabels.Properties.VariableNames= {'Position','Type','Name'};
end
最后,終止函數(shù)處理自動化完成后所需的任何清理或拆除。該算法不需要任何清理,所以該函數(shù)為空。
function terminate(~)
end
3.4 在App中使用AutoLaneMarking自動化類
車道檢測算法的打包版本現(xiàn)在已經(jīng)可以在AutoLaneMarking類中使用。要在應(yīng)用中使用這個類。 --在當(dāng)前文件夾下創(chuàng)建所需的文件夾結(jié)構(gòu),并將自動化類復(fù)制到其中。
mkdir('+vision/+labeler');
copyfile(fullfile(matlabroot,'toolbox','driving','drivingdemos','AutoLaneMarking.m'),'+vision/+labeler');
--將monoCamera信息加載到工作區(qū)。
configData =load('birdsEyeConfig');
sensor = configData.birdsEyeConfig.Sensor;
--打開 "地面真值標(biāo)簽機(jī) "應(yīng)用。
groundTruthLabelercaltech_cordova1.avi
在左側(cè)窗格中,單擊 "定義新的投資回報率標(biāo)簽 "按鈕,并定義所示的投資回報率線樣式。然后單擊 "確定"。
- 點(diǎn)擊算法 > 選擇算法 > 刷新列表。- 點(diǎn)擊 "算法">"自動車道檢測"。如果沒有看到這個選項,請確保當(dāng)前工作文件夾中有一個名為+vision/+labeler的文件夾,其中有一個名為AutoLaneMarking.m的文件。
- 單擊Automate(自動)。將打開一個新的標(biāo)簽,顯示算法的使用方向。- 點(diǎn)擊設(shè)置,在打開的對話框中,在第一個文本框中輸入傳感器。如果需要,請修改其他參數(shù),然后再單擊 "確定"。
- 單擊 "運(yùn)行"。車道檢測算法在視頻上進(jìn)行。注意,在某些幀中,結(jié)果并不令人滿意。- 運(yùn)行完成后,使用滑塊或方向鍵滾動整個視頻,以定位算法失敗的幀。
- 通過移動車道邊界點(diǎn)或刪除整個邊界,手動調(diào)整結(jié)果。
- 一旦對整個視頻的車道邊界感到滿意,請單擊 "接受"。標(biāo)記視頻的自動車道檢測部分已經(jīng)完成??梢岳^續(xù)標(biāo)記其他感興趣的對象,保存會話,或?qū)С霰敬螛?biāo)記運(yùn)行的結(jié)果。
3.5 總結(jié)
這個例子展示了將車道檢測算法納入Ground Truth Labeler應(yīng)用程序的步驟。可以將此概念擴(kuò)展到其他自定義算法,以簡化和擴(kuò)展應(yīng)用程序的功能。