ドキュメンテーション

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

歩行者の検出

この例では、深層学習を使用する歩行者検出用途のコード生成を説明します。歩行者検出は、自動運転、監視、ロボット工学などの分野でさまざまに応用できるコンピューター ビジョンの重要な問題です。

必要条件

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

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

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

  • Computer Vision Toolbox™。

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

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

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

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

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

GPU 環境の検証

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

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

ネットワークについて

歩行者検出ネットワークには、歩行者のイメージと歩行者以外のイメージを使用して学習させました。このネットワークの学習は、MATLAB® で trainPedNet.m スクリプトを使用して行われています。スライディング ウィンドウ手法を使用して、図のようにサイズ [64 32] のイメージからパッチを切り取ります。パッチの寸法は、データセットにあるイメージ内の歩行者の分布を表すヒートマップから取得されます。これは、イメージ内のさまざまな場所にさまざまなスケールで歩行者が存在することを示します。この例では、カメラに近い歩行者のパッチが切り取られて処理されます。最後に、取得されたパッチに非最大抑制 (NMS) が適用され、パッチがマージされて歩行者全体が検出されます。

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

load('PedNet.mat');
PedNet.Layers
ans = 

  12x1 Layer array with layers:

     1   'imageinput'    Image Input                   64x32x3 images with 'zerocenter' normalization
     2   'conv_1'        Convolution                   20 5x5x3 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   'crossnorm'     Cross Channel Normalization   cross channel normalization with 5 channels per element
     6   'conv_2'        Convolution                   20 5x5x20 convolutions with stride [1  1] and padding [0  0  0  0]
     7   'relu_2'        ReLU                          ReLU
     8   'maxpool_2'     Max Pooling                   2x2 max pooling with stride [2  2] and padding [0  0  0  0]
     9   'fc_1'          Fully Connected               512 fully connected layer
    10   'fc_2'          Fully Connected               2 fully connected layer
    11   'softmax'       Softmax                       softmax
    12   'classoutput'   Classification Output         crossentropyex with classes 'NonPed' and 'Ped'

関数 'pedDetect_predict' について

関数 pedDetect_predict.m は、イメージ入力を受け取り、PedNet.mat ファイルに保存されている深層学習ネットワークを使用して、イメージについて予測を実行します。この関数は、PedNet.mat からネットワーク オブジェクトを永続変数 pednet に読み込みます。それ以降、この関数を呼び出すと、予測のためにこの永続オブジェクトが再利用されます。

type('pedDetect_predict.m')
function selectedBbox = pedDetect_predict(img)
%#codegen

% Copyright 2017 The MathWorks, Inc.

% function for predicting the pedestrians
% A persistent object pednet is used to load the series network object.
% At the first call to this function, the persistent object is constructed and
% setup. When the function is called subsequent times, the same object is reused 
% to call predict on inputs, thus avoiding reconstructing and reloading the
% network object.

coder.gpu.kernelfun;

persistent pednet;
if isempty(pednet) 
    pednet = coder.loadDeepLearningNetwork(coder.const('PedNet.mat'),'Pedestrian_Detection');
end

[imgHt , imgWd , ~] = size(img);
VrHt = [imgHt - 30 , imgHt]; % Two bands of vertical heights are considered

% patchHt and patchWd are obtained from heat maps (heat map here refers to
% pedestrians data represented in the form of a map with different
% colors. Different colors indicate presence of pedestrians at various
% scales).
patchHt = 300; 
patchWd = patchHt/3;

% PatchCount is used to estimate number of patches per image
PatchCount = ((imgWd - patchWd)/20) + 2;
maxPatchCount = PatchCount * 2; 
Itmp = zeros(64 , 32 , 3 , maxPatchCount);
ltMin = zeros(maxPatchCount);
lttop = zeros(maxPatchCount);

idx = 1; % To count number of image patches obtained from sliding window
cnt = 1; % To count number of patches predicted as pedestrians

bbox = zeros(maxPatchCount , 4);
value = zeros(maxPatchCount , 1);

%% Region proposal for two bands
for VrStride = 1 : 2
    for HrStride = 1 : 20 : (imgWd - 60)  % Obtain horizontal patches with stride 20.
        ltMin(idx) = HrStride + 1;
        rtMax = min(ltMin(idx) + patchWd , imgWd);
        lttop(idx) = (VrHt(VrStride) - patchHt);
        It = img(lttop(idx): VrHt(VrStride) , ltMin(idx) : rtMax , :);
        Itmp(:,:,:,idx) = imresize(It,[64,32]);
        idx = idx + 1;
    end
end

for j = 1 : size (Itmp,4)
    score = pednet.predict(Itmp(:,:,:,j)); % Classify ROI
    % accuracy of detected box should be greater than 0.90
    if (score(1,2) > 0.80)
        bbox(cnt,:) = [ltMin(j),lttop(j), patchWd , patchHt];
        value(cnt,:) = score(1,2);
        cnt = cnt + 1;
    end
    
end

%% NMS to merge similar boxes
if ~isempty(bbox)
    [selectedBbox,~] = selectStrongestBbox(bbox(1:cnt-1,:),...
        value(1:cnt-1,:),'OverlapThreshold',0.002);
end
    

関数 pedDetect_predict の CUDA MEX の生成

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

% Load an input image.
im = imread('test.jpg');
im = imresize(im,[480,640]);

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

生成された MEX の実行

imshow(im);

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

ped_bboxes = pedDetect_predict_mex(im);

最終予測を表示します。

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

ビデオに対する分類

用意されている例ファイル pedDetect_predict.m は、ビデオからフレームを取得して予測を呼び出し、取得した各ビデオ フレームについて分類結果を表示します。

  v = VideoReader('LiveData.avi');
  fps = 0;
  while hasFrame(v)
     % Read frames from video
     im = readFrame(v);
     im = imresize(im,[480,640]);
     % Call MEX function for pednet prediction
     tic;
     ped_bboxes = pedDetect_predict_mex(im);
     newt = toc;
     % fps
     fps = .9*fps + .1*(1/newt);
     % display
     outputImage = insertShape(im,'Rectangle',ped_bboxes,'LineWidth',3);
     imshow(outputImage)
     pause(0.2)
  end

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

clear mex;