Main Content

このページの翻訳は最新ではありません。ここをクリックして、英語の最新版を参照してください。

深層学習を使用した Simulink での車線検出と車両検出

この例では、Simulink® モデル内で深層畳み込みニューラル ネットワークを使用して、車線検出と車両検出を実行する方法を示します。この例では、交通量ビデオのフレームを入力として受け取り、自車の左右の車線に対応する 2 つの車線境界線を出力し、フレーム内の車両を検出します。

この例では、GPU Coder Toolbox™ の "GPU Coder により最適化された車線検出" の例の事前学習済み車線検出ネットワークを使用します。詳細は、GPU Coder により最適化された車線検出 (GPU Coder) を参照してください。

この例では、Computer Vision Toolbox™ の "YOLO v2 深層学習を使用したオブジェクト検出" の例の事前学習済み車線検出ネットワークも使用します。詳細については、YOLO v2 深層学習を使用したオブジェクトの検出 (Computer Vision Toolbox)を参照してください。

アルゴリズム ワークフロー

この Simulink モデルのアルゴリズム ワークフローのブロック線図を以下に示します。

事前学習済みの車線検出ネットワークおよび車両検出ネットワークの取得

関数 getVehicleDetectionAndLaneDetectionNetworks は、trainedLaneNet.mat ファイルおよび yolov2ResNet50VehicleExample.mat ファイルが存在しない場合、これらをダウンロードします。

getVehicleDetectionAndLaneDetectionNetworks()
Downloading pretrained lane detection network (143 MB)...
Downloading pretrained vehicle detection network (98 MB)...

サンプル ビデオのダウンロード

if ~exist('./caltech_washington1.avi', 'file')
    url = 'https://www.mathworks.com/supportfiles/gpucoder/media/caltech_washington1.avi';
    websave('caltech_washington1.avi', url);
end

車線検出と車両検出の Simulink モデル

交通量ビデオで車線検出と車両検出を実行するための Simulink モデルを示します。このモデルを実行すると、Video Viewer ブロックが、車線と車両に注釈を付けた状態で交通量ビデオを表示します。

open_system('laneAndVehicleDetectionMDL');

車線検出

車線検出では、交通量ビデオは、ビデオの各フレームのサイズを 227 x 227 x3 に変更し、係数 255 でスケーリングすることによって前処理されます。前処理済みのフレームは、Deep Learning Toolbox™ の Predict ブロックに読み込まれた trainedLaneNet.mat ネットワークに入力されます。このネットワークは入力としてイメージを取り、自車の左右の車線に対応する 2 つの車線境界線を出力します。各車線境界線は、次の放物線方程式によって表されます。

$y = ax^2+bx+c$

ここで、y は横方向オフセット、x は車両からの縦方向の距離です。このネットワークは、車線ごとに 3 つのパラメーター a、b、c を出力します。ネットワーク アーキテクチャは AlexNet に似ていますが、最後の数層は、規模の小さい全結合層と回帰出力層に置き換えられています。Lane Detection Coordinates MATLAB Function ブロックは、関数 lane_detection_coordinates を定義します。この関数は、予測ブロックからの出力を受け取り、laneFoundltPtsrtPts という 3 つのパラメーターを出力します。しきい値処理は、左右の車線境界線が両方とも検出できるかどうかを判断するために使用されます。両方とも検出できれば、laneFound は true に設定され、境界線の軌跡が計算されて、ltPtsrtPts にそれぞれ格納されます。

type lane_detection_coordinates
function [laneFound,ltPts,rtPts] = lane_detection_coordinates(laneNetOut)

% Copyright 2020 The MathWorks, Inc.

persistent laneCoeffMeans;
if isempty(laneCoeffMeans)
    laneCoeffMeans = [-0.0002    0.0002    1.4740   -0.0002    0.0045   -1.3787];
end

persistent laneCoeffStds;
if isempty(laneCoeffStds)
    laneCoeffStds = [0.0030    0.0766    0.6313    0.0026    0.0736    0.9846];
end

params = laneNetOut .* laneCoeffStds + laneCoeffMeans;

isRightLaneFound = abs(params(6)) > 0.5; %c should be more than 0.5 for it to be a right lane
isLeftLaneFound =  abs(params(3)) > 0.5;

persistent vehicleXPoints;
if isempty(vehicleXPoints)
    vehicleXPoints = 3:30; %meters, ahead of the sensor
end

ltPts = coder.nullcopy(zeros(28,2,'single'));
rtPts = coder.nullcopy(zeros(28,2,'single'));

if isRightLaneFound && isLeftLaneFound
    rtBoundary = params(4:6);
    rt_y = computeBoundaryModel(rtBoundary, vehicleXPoints);
    ltBoundary = params(1:3);
    lt_y = computeBoundaryModel(ltBoundary, vehicleXPoints);
    
    % Visualize lane boundaries of the ego vehicle
    tform = get_tformToImage;
    % map vehicle to image coordinates
    ltPts =  tform.transformPointsInverse([vehicleXPoints', lt_y']);
    rtPts =  tform.transformPointsInverse([vehicleXPoints', rt_y']);
    laneFound = true;
else
    laneFound = false;
end

end

車両検出

この例では、車両検出のために YOLO v2 ベースのネットワークを使用します。YOLO v2 オブジェクトの検出ネットワークは、特徴抽出ネットワークと、その後に続く検出ネットワークという、2 つのサブネットワークで構成されます。事前学習済みのネットワークは、特徴抽出に ResNet-50 を使用します。検出サブネットワークは特徴抽出ネットワークと比べて小さい CNN であり、少数の畳み込み層と YOLO v2 に固有の層で構成されます。

Simulink モデルは、MATLAB Function ブロック Vehicle Detection YOLOv2 内で車両検出を実行します。この関数ブロックは、事前学習済みの YOLO v2 検出器を読み込む関数 vehicle_detection_yolo_v2 を定義します。このネットワークは、イメージを入力として受け取り、境界ボックス座標をイメージ内の車両の信頼度スコアと共に出力します。

type vehicle_detection_yolo_v2
function [bboxes,scores] = vehicle_detection_yolo_v2(In)

% Copyright 2020 The MathWorks, Inc.

persistent yolodetector;
if isempty(yolodetector)
    yolodetector = coder.loadDeepLearningNetwork('yolov2ResNet50VehicleExample.mat');
end

[bboxes,scores,~] = yolodetector.detect(In, 'threshold', .2);

end

車両境界ボックスの注釈と交通量ビデオの車線軌跡

Lane and Vehicle Annotation MATLAB Function ブロックは、関数 lane_vehicle_annotation を定義します。この関数は、車両境界ボックスに対して信頼度スコアとともに注釈を付けます。laneFound が true の場合、ltPtsrtPts に格納された左右の車線境界線は交通量ビデオにオーバーレイされます。

type lane_vehicle_annotation
function In = lane_vehicle_annotation(laneFound, ltPts, rtPts, bboxes, scores, In)

% Copyright 2020 The MathWorks, Inc.

if ~isempty(bboxes)
    In = insertObjectAnnotation(In, 'rectangle', bboxes, scores);
end

pts = coder.nullcopy(zeros(28, 4, 'single'));
if laneFound
    prevpt =  [ltPts(1,1) ltPts(1,2)];
    for k = 2:1:28
        pts(k,1:4) = [prevpt ltPts(k,1) ltPts(k,2)];
        prevpt = [ltPts(k,1) ltPts(k,2)];
    end
    In = insertShape(In, 'Line', pts, 'LineWidth', 2);
    prevpt =  [rtPts(1,1) rtPts(1,2)];
    for k = 2:1:28
        pts(k,1:4) = [prevpt rtPts(k,1) rtPts(k,2)];
        prevpt = [rtPts(k,1) rtPts(k,2)];
    end
    In = insertShape(In, 'Line', pts, 'LineWidth', 2);
    In = insertMarker(In, ltPts);
    In = insertMarker(In, rtPts);
end

end

シミュレーションの実行

車線検出アルゴリズムおよび車両検出アルゴリズムを検証し、Simulink モデルに読み込まれた交通量ビデオに関する車線軌跡、車両境界ボックス、スコアを表示するため、シミュレーションを実行します。

set_param('laneAndVehicleDetectionMDL', 'SimulationMode', 'Normal');
sim('laneAndVehicleDetectionMDL');
Warning: Saturate on overflow detected.

In MATLAB Function '<a
href="matlab:Stateflow.Debug.Runtime.open_object('laneAndVehicleDetectionMDL/Lane
and Vehicle Annotation', 0);">laneAndVehicleDetectionMDL/Lane and Vehicle
Annotation</a>':

    function In = LaneVehicleAnnotation(laneFound, ltPts, rtPts, bboxes, scores,
    In)

Suggested Actions:
    • Suppress future instances of this diagnostic from this source. - <a
    href="matlab:Simulink.SuppressedDiagnostic({'laneAndVehicleDetectionMDL/Lane
    and Vehicle
    Annotation'},'Stateflow:Runtime:DataSaturateError');">Suppress</a>
 

コード生成

GPU Coder™ を使用すれば、NVIDIA® GPU でのモデルの実行を高速化し、モデルについての CUDA® コードを生成できます。詳細については、車線検出と車両検出を実行する深層学習 Simulink モデルのコード生成 (GPU Coder)を参照してください。

クリーンアップ

Simulink モデルを閉じます。

close_system('laneAndVehicleDetectionMDL/Lane and Vehicle Detection Output');
close_system('laneAndVehicleDetectionMDL');