ドキュメンテーション

最新のリリースでは、このページがまだ翻訳されていません。 このページの最新版は英語でご覧になれます。

交通標識の検出と認識

この例では、深層学習を使用する交通標識の検出および認識用途の CUDA® MEX コードを生成する方法を説明します。交通標識の検出および認識は、ドライバーに道路標識についての情報を提供して支援する運転者支援システムのための重要な用途です。

この例では、交通標識の検出および認識は、検出、非最大抑制 (NMS)、および認識の 3 つのステップで実行されます。この例では、最初に You Only Look Once (YOLO) ネットワークのバリアントであるオブジェクト検出ネットワークを使用して、与えられた入力イメージにある交通標識を検出します。次に、NMS アルゴリズムを使用して、重なりのある検出を抑制します。最後に、認識ネットワークを使用して、検出された交通標識を分類します。

必要条件

  • Compute Capability 3.2 以上の CUDA 対応 NVIDIA® GPU。

  • NVIDIA CUDA ツールキットおよびドライバー。

  • NVIDIA cuDNN ライブラリ v7 以上。

  • コンパイラおよびライブラリの環境変数。詳細は、Environment Variables を参照してください。

  • Deep Learning Toolbox™ (SeriesNetwork オブジェクトを使用するため)。

  • Image Processing Toolbox™ (イメージを読み取って表示するため)。

  • Computer Vision Toolbox™ (この例で使用するビデオ リーダー、ビューアー、および非最大抑制 (NMS) 用)。

  • GPU Coder™ (CUDA コードを生成するため)。

  • GPU Coder Interface for Deep Learning Libraries サポート パッケージ。このサポート パッケージをインストールするには、アドオン エクスプローラーを使用します。

GPU 環境の検証

関数 coder.checkGpuInstall を使用し、この例を実行するのに必要なコンパイラおよびライブラリが適切に設定されていることを検証します。

coder.checkGpuInstall('gpu','codegen','cudnn','quiet');

検出ネットワークと認識ネットワークについて

検出ネットワークは、Darknet フレームワークで学習が行われ、推論のために MATLAB® にインポートされています。交通標識のサイズはイメージのサイズと比べて比較的小さく、学習データ内のクラスあたりの学習サンプル数が少ないため、すべての交通標識を検出ネットワークに学習させるための単一のクラスと見なします。

検出ネットワークは、入力イメージを 7x7 のグリッドに分割し、各グリッド セルは、交通標識の中心がそのグリッド セル内にある場合に交通標識を検出します。各セルは、2 つの境界ボックスとそれらの境界ボックスの信頼スコアを予測します。信頼スコアは、そのボックスがオブジェクトを含んでいるかどうかを示します。また、各セルは、グリッド セル内で交通標識が見つかる確率も予測します。最終的なスコアはそれら 2 つの値の積です。この最終スコアに 0.2 のしきい値を適用して検出を選択します。

認識ネットワークも、MATLAB を使用して同じイメージについて学習済みです。

trainRecognitionnet.m スクリプトは、認識ネットワークの学習について示しています。

事前学習済みの SeriesNetwork の取得

検出ネットワークと認識ネットワークをダウンロードします。

getTsdr();

検出ネットワークには、畳み込み層、漏洩 ReLU 層、全結合層など、58 個の層が含まれています。

load('yolo_tsr.mat');
yolo.Layers
ans = 

  58x1 Layer array with layers:

     1   'input'         Image Input             448x448x3 images
     2   'conv1'         Convolution             64 7x7x3 convolutions with stride [2  2] and padding [3  3  3  3]
     3   'relu1'         Leaky ReLU              Leaky ReLU with scale 0.1
     4   'pool1'         Max Pooling             2x2 max pooling with stride [2  2] and padding [0  0  0  0]
     5   'conv2'         Convolution             192 3x3x64 convolutions with stride [1  1] and padding [1  1  1  1]
     6   'relu2'         Leaky ReLU              Leaky ReLU with scale 0.1
     7   'pool2'         Max Pooling             2x2 max pooling with stride [2  2] and padding [0  0  0  0]
     8   'conv3'         Convolution             128 1x1x192 convolutions with stride [1  1] and padding [0  0  0  0]
     9   'relu3'         Leaky ReLU              Leaky ReLU with scale 0.1
    10   'conv4'         Convolution             256 3x3x128 convolutions with stride [1  1] and padding [1  1  1  1]
    11   'relu4'         Leaky ReLU              Leaky ReLU with scale 0.1
    12   'conv5'         Convolution             256 1x1x256 convolutions with stride [1  1] and padding [0  0  0  0]
    13   'relu5'         Leaky ReLU              Leaky ReLU with scale 0.1
    14   'conv6'         Convolution             512 3x3x256 convolutions with stride [1  1] and padding [1  1  1  1]
    15   'relu6'         Leaky ReLU              Leaky ReLU with scale 0.1
    16   'pool6'         Max Pooling             2x2 max pooling with stride [2  2] and padding [0  0  0  0]
    17   'conv7'         Convolution             256 1x1x512 convolutions with stride [1  1] and padding [0  0  0  0]
    18   'relu7'         Leaky ReLU              Leaky ReLU with scale 0.1
    19   'conv8'         Convolution             512 3x3x256 convolutions with stride [1  1] and padding [1  1  1  1]
    20   'relu8'         Leaky ReLU              Leaky ReLU with scale 0.1
    21   'conv9'         Convolution             256 1x1x512 convolutions with stride [1  1] and padding [0  0  0  0]
    22   'relu9'         Leaky ReLU              Leaky ReLU with scale 0.1
    23   'conv10'        Convolution             512 3x3x256 convolutions with stride [1  1] and padding [1  1  1  1]
    24   'relu10'        Leaky ReLU              Leaky ReLU with scale 0.1
    25   'conv11'        Convolution             256 1x1x512 convolutions with stride [1  1] and padding [0  0  0  0]
    26   'relu11'        Leaky ReLU              Leaky ReLU with scale 0.1
    27   'conv12'        Convolution             512 3x3x256 convolutions with stride [1  1] and padding [1  1  1  1]
    28   'relu12'        Leaky ReLU              Leaky ReLU with scale 0.1
    29   'conv13'        Convolution             256 1x1x512 convolutions with stride [1  1] and padding [0  0  0  0]
    30   'relu13'        Leaky ReLU              Leaky ReLU with scale 0.1
    31   'conv14'        Convolution             512 3x3x256 convolutions with stride [1  1] and padding [1  1  1  1]
    32   'relu14'        Leaky ReLU              Leaky ReLU with scale 0.1
    33   'conv15'        Convolution             512 1x1x512 convolutions with stride [1  1] and padding [0  0  0  0]
    34   'relu15'        Leaky ReLU              Leaky ReLU with scale 0.1
    35   'conv16'        Convolution             1024 3x3x512 convolutions with stride [1  1] and padding [1  1  1  1]
    36   'relu16'        Leaky ReLU              Leaky ReLU with scale 0.1
    37   'pool16'        Max Pooling             2x2 max pooling with stride [2  2] and padding [0  0  0  0]
    38   'conv17'        Convolution             512 1x1x1024 convolutions with stride [1  1] and padding [0  0  0  0]
    39   'relu17'        Leaky ReLU              Leaky ReLU with scale 0.1
    40   'conv18'        Convolution             1024 3x3x512 convolutions with stride [1  1] and padding [1  1  1  1]
    41   'relu18'        Leaky ReLU              Leaky ReLU with scale 0.1
    42   'conv19'        Convolution             512 1x1x1024 convolutions with stride [1  1] and padding [0  0  0  0]
    43   'relu19'        Leaky ReLU              Leaky ReLU with scale 0.1
    44   'conv20'        Convolution             1024 3x3x512 convolutions with stride [1  1] and padding [1  1  1  1]
    45   'relu20'        Leaky ReLU              Leaky ReLU with scale 0.1
    46   'conv21'        Convolution             1024 3x3x1024 convolutions with stride [1  1] and padding [1  1  1  1]
    47   'relu21'        Leaky ReLU              Leaky ReLU with scale 0.1
    48   'conv22'        Convolution             1024 3x3x1024 convolutions with stride [2  2] and padding [1  1  1  1]
    49   'relu22'        Leaky ReLU              Leaky ReLU with scale 0.1
    50   'conv23'        Convolution             1024 3x3x1024 convolutions with stride [1  1] and padding [1  1  1  1]
    51   'relu23'        Leaky ReLU              Leaky ReLU with scale 0.1
    52   'conv24'        Convolution             1024 3x3x1024 convolutions with stride [1  1] and padding [1  1  1  1]
    53   'relu24'        Leaky ReLU              Leaky ReLU with scale 0.1
    54   'fc25'          Fully Connected         4096 fully connected layer
    55   'relu25'        Leaky ReLU              Leaky ReLU with scale 0.1
    56   'fc26'          Fully Connected         539 fully connected layer
    57   'softmax'       Softmax                 softmax
    58   'classoutput'   Classification Output   crossentropyex

認識ネットワークには、畳み込み層、全結合層、分類出力層など、14 個の層が含まれています。

load('RecognitionNet.mat');
convnet.Layers
ans = 

  14x1 Layer array with layers:

     1   'imageinput'    Image Input             48x48x3 images with 'zerocenter' normalization and 'randfliplr' augmentations
     2   'conv_1'        Convolution             100 7x7x3 convolutions with stride [1  1] and padding [0  0  0  0]
     3   'relu_1'        ReLU                    ReLU
     4   'maxpool_1'     Max Pooling             2x2 max pooling with stride [2  2] and padding [0  0  0  0]
     5   'conv_2'        Convolution             150 4x4x100 convolutions with stride [1  1] and padding [0  0  0  0]
     6   'relu_2'        ReLU                    ReLU
     7   'maxpool_2'     Max Pooling             2x2 max pooling with stride [2  2] and padding [0  0  0  0]
     8   'conv_3'        Convolution             250 4x4x150 convolutions with stride [1  1] and padding [0  0  0  0]
     9   'maxpool_3'     Max Pooling             2x2 max pooling with stride [2  2] and padding [0  0  0  0]
    10   'fc_1'          Fully Connected         300 fully connected layer
    11   'dropout'       Dropout                 90% dropout
    12   'fc_2'          Fully Connected         35 fully connected layer
    13   'softmax'       Softmax                 softmax
    14   'classoutput'   Classification Output   crossentropyex with '0' and 34 other classes

関数 'tsdr_predict' について

関数 tsdr_predict.m は、イメージ入力を受け取り、検出ネットワークを使用してイメージ内の交通標識を検出します。また、selectStrongestBbox を使用して重なりのある検出を抑制し (NMS)、認識ネットワークを使用して交通標識を認識します。この関数は、ネットワーク オブジェクトを yolo_tsr.mat から永続変数 detectionnet に、RecognitionNet.mat から永続変数 recognitionnet に読み込みます。それ以降、この関数を呼び出すと、交通標識の検出および認識のためにこれらの永続オブジェクトが再利用されます。

type('tsdr_predict.m')
function [selectedBbox,idx] = tsdr_predict(img)
%#codegen

% This function detects the traffic signs in the image using Detection Network
% (modified version of Yolo) and recognizes(classifies) using Recognition Network
%
% Inputs :
%
% im            : Input test image
%
% Outputs :
%
% selectedBbox  : Detected bounding boxes 
% idx           : Corresponding classes

% Copyright 2017 The MathWorks, Inc.

coder.gpu.kernelfun;

% resize the image
img_rz = imresize(img,[448,448]);

% Converting into BGR format
img_rz = img_rz(:,:,3:-1:1);
img_rz = im2single(img_rz);

%% TSD
persistent detectionnet;
if isempty(detectionnet)   
    detectionnet = coder.loadDeepLearningNetwork('yolo_tsr.mat','Detection');
end

predictions = detectionnet.activations(img_rz,56,'OutputAs','channels');


%% Convert predictions to bounding box attributes
classes = 1;
num = 2;
side = 7;
thresh = 0.2;
[h,w,~] = size(img);


boxes = single(zeros(0,4));    
probs = single(zeros(0,1));    
for i = 0:(side*side)-1
    for n = 0:num-1
        p_index = side*side*classes + i*num + n + 1;
        scale = predictions(p_index);       
        prob = zeros(1,classes+1);
        for j = 0:classes
            class_index = i*classes + 1;
            tempProb = scale*predictions(class_index+j);
            if tempProb > thresh
                
                row = floor(i / side);
                col = mod(i,side);
                
                box_index = side*side*(classes + num) + (i*num + n)*4 + 1;
                bxX = (predictions(box_index + 0) + col) / side;
                bxY = (predictions(box_index + 1) + row) / side;
                
                bxW = (predictions(box_index + 2)^2);
                bxH = (predictions(box_index + 3)^2);
                
                prob(j+1) = tempProb;
                probs = [probs;tempProb];
                                
                boxX = (bxX-bxW/2)*w+1;
                boxY = (bxY-bxH/2)*h+1;
                boxW = bxW*w;
                boxH = bxH*h;
                boxes = [boxes; boxX,boxY,boxW,boxH];
            end
        end
    end
end

%% Run Non-Maximal Suppression on the detected bounding boxess
coder.varsize('selectedBbox',[98, 4],[1 0]);
[selectedBbox,~] = selectStrongestBbox(round(boxes),probs);

%% Recognition

persistent recognitionnet;
if isempty(recognitionnet) 
    recognitionnet = coder.loadDeepLearningNetwork('RecognitionNet.mat','Recognition');
end

idx = zeros(size(selectedBbox,1),1);
inpImg = coder.nullcopy(zeros(48,48,3,size(selectedBbox,1)));
for i = 1:size(selectedBbox,1)
    
    ymin = selectedBbox(i,2);
    ymax = ymin+selectedBbox(i,4);
    xmin = selectedBbox(i,1);
    xmax = xmin+selectedBbox(i,3);

    
    % Resize Image
    inpImg(:,:,:,i) = imresize(img(ymin:ymax,xmin:xmax,:),[48,48]);
end

for i = 1:size(selectedBbox,1)
    output = recognitionnet.predict(inpImg(:,:,:,i));
    [~,idx(i)]=max(output);
end

関数 'tsdr_predict' の CUDA MEX の生成

MEX ターゲットの GPU 構成オブジェクトを作成し、ターゲット言語を C++ に設定します。関数 coder.DeepLearningConfig を使用して CuDNN 深層学習構成オブジェクトを作成し、それを GPU コード構成オブジェクトの DeepLearningConfig プロパティに割り当てます。CUDA MEX を生成するには、codegen コマンドを使用し、入力のサイズを [480,704,3] に指定します。この値は関数 tsdr_predict の入力イメージ サイズに対応します。

cfg = coder.gpuConfig('mex');
cfg.TargetLang = 'C++';
cfg.DeepLearningConfig = coder.DeepLearningConfig('cudnn');
codegen -config cfg tsdr_predict -args {ones(480,704,3,'uint8')} -report
Code generation successful: To view the report, open('codegen/mex/tsdr_predict/html/report.mldatx').

メモ: TensorRT を使用してコードを生成するには、'cudnn' の代わりに、coder.DeepLearningConfig('tensorrt') をオプションとしてコーダー構成オブジェクトに渡します。

生成された MEX の実行

入力イメージを読み込みます。

im = imread('stop.jpg');
imshow(im);

入力イメージに対して tsdr の関数 predict を呼び出します。

im = imresize(im, [480,704]);
[bboxes,classes] = tsdr_predict_mex(im);

クラス番号をクラス ディクショナリ内の交通標識名にマッピングします。

classNames = {'addedLane','slow','dip','speedLimit25','speedLimit35','speedLimit40','speedLimit45',...
    'speedLimit50','speedLimit55','speedLimit65','speedLimitUrdbl','doNotPass','intersection',...
    'keepRight','laneEnds','merge','noLeftTurn','noRightTurn','stop','pedestrianCrossing',...
    'stopAhead','rampSpeedAdvisory20','rampSpeedAdvisory45','truckSpeedLimit55',...
    'rampSpeedAdvisory50','turnLeft','rampSpeedAdvisoryUrdbl','turnRight','rightLaneMustTurn',...
    'yield','yieldAhead','school','schoolSpeedLimit25','zoneAhead45','signalAhead'};

classRec = classNames(classes);

検出した交通標識を表示します。

outputImage = insertShape(im,'Rectangle',bboxes,'LineWidth',3);

for i = 1:size(bboxes,1)
    outputImage = insertText(outputImage,[bboxes(i,1)+bboxes(i,3) bboxes(i,2)-20],classRec{i},'FontSize',20,'TextColor','red');
end

imshow(outputImage);

ビデオにある交通標識の検出と認識

用意されている例ファイル tsdr_testVideo.m は、テスト ビデオからフレームを取得して、交通標識の検出および認識を呼び出し、テスト ビデオの各フレームについて結果をプロットします。

  % Input video
  v = VideoReader('stop.avi');
  fps = 0;
   while hasFrame(v)
      % Take a frame
      picture = readFrame(v);
      picture = imresize(picture,[920,1632]);
      % Call MEX function for Traffic Sign Detection and Recognition
      tic;
      [bboxes,clases] = tsdr_predict_mex(picture);
      newt = toc;
      % fps
      fps = .9*fps + .1*(1/newt);
      % display
       displayDetections(picture,bboxes,clases,fps);
    end

clear mex を使用して、メモリに読み込まれた静的ネットワーク オブジェクトを削除します。

clear mex;

関連するトピック