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 モデルのアルゴリズム ワークフローのブロック線図を以下に示します。

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

この例では、trainedLaneNet と、事前学習済みのネットワークを含む yolov2ResNet50VehicleExample の MAT ファイルを使用します。ファイルのサイズはそれぞれ、約 143 MB と約 98 MB です。MathWorks の Web サイトからファイルをダウンロードします。

lanenetFile = matlab.internal.examples.downloadSupportFile('gpucoder/cnn_models/lane_detection','trainedLaneNet.mat');
vehiclenetFile = matlab.internal.examples.downloadSupportFile('vision/data','yolov2ResNet50VehicleExample.mat');

テスト用の交通量ビデオのダウンロード

モデルをテストするために、この例では Caltech Lanes Dataset を使用しています。ファイルのサイズは約 16 MB です。MathWorks の Web サイトからファイルをダウンロードします。

mediaFile = matlab.internal.examples.downloadSupportFile('gpucoder/media','caltech_washington1.avi');

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

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

open_system('laneAndVehicleDetectionMDL');

Simulink モデルの予測と検出器のブロックで、ダウンロードしたネットワーク モデルのファイル パスを設定します。Simulink モデルによって読み込まれるテスト ビデオの場所を設定します。

set_param('laneAndVehicleDetectionMDL/Lane Detection','NetworkFilePath',lanenetFile)
set_param('laneAndVehicleDetectionMDL/Vehicle Detector','DetectorFilePath',vehiclenetFile)
set_param('laneAndVehicleDetectionMDL/Traffic Video','inputFileName',mediaFile)

車線検出

車線検出では、交通量ビデオは、ビデオの各フレームのサイズを 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-2021 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;

% 'c' should be more than 0.5 for it to be a right lane
isRightLaneFound = abs(params(6)) > 0.5;
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 モデルは、Computer Vision Toolbox の Object Detector ブロックを使用して車両検出を実行します。このブロックは、イメージを入力として受け取り、境界ボックス座標をイメージ内の車両の信頼度スコアと共に出力します。

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

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-2021 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');

Windows® では、パスの最大長が 260 文字であるため、シミュレーションを実行する時に "File not found" エラーが発生する可能性があります。そのような場合は、例のフォルダーを別の場所に移動するか、Windows で長いパスを有効にしてください。詳細については、Maximum Path Length Limitation (Microsoft) を参照してください。

深層学習アクセラレータ ライブラリの使用

AVX2 命令をサポートする Intel® CPU がある場合は、"MATLAB Coder Interface for Deep Learning Libraries" を使用することで、Intel MKL-DNN のライブラリを使用して、シミュレーションを高速化できます。[モデル コンフィギュレーション パラメーター] ウィンドウの [シミュレーション ターゲット] ペインで、[言語] を C++ に、[ターゲット ライブラリ] を MKL-DNN に設定します。

コード生成

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