本页面提供的是上一版软件的文档。当前版本中已删除对应的英文页面。

行人检测

此示例说明如何为使用深度学习的行人检测应用程序生成代码。行人检测是计算机视觉的一个关键问题。行人检测在自动驾驶、监控、机器人等领域有诸多应用。

前提条件

  • 支持 CUDA® 的 NVIDIA® GPU,计算能力为 3.2 或更高。

  • NVIDIA CUDA 工具包和驱动程序。

  • NVIDIA cuDNN。

  • 编译器和库的环境变量。有关支持的编译器和库的版本的信息,请参阅Third-party Products (GPU Coder)。有关设置环境变量的信息,请参阅Setting Up the Prerequisite Products (GPU Coder)。

  • GPU Coder Interface for Deep Learning Libraries 支持包。要安装此支持包,请使用附加功能资源管理器

验证 GPU 环境

使用 coder.checkGpuInstall 函数验证运行此示例所需的编译器和库是否已正确设置。

envCfg = coder.gpuEnvConfig('host');
envCfg.DeepLibTarget = 'cudnn';
envCfg.DeepCodegen = 1;
envCfg.Quiet = 1;
coder.checkGpuInstall(envCfg);

行人检测网络

行人检测网络是使用行人和非行人的图像训练得出的。在 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-2019 The MathWorks, Inc.

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

对输入图像调用 pednet_predict_mex

imshow(im);
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;

相关主题