Main Content

为使用 YOLO v2 的目标检测生成代码

此示例说明如何为 you only look once (YOLO) v2 目标检测器生成 CUDA® MEX。YOLO v2 目标检测网络由两个子网络组成。一个特征提取网络,后跟一个检测网络。此示例为 Computer Vision Toolbox™ 的使用 YOLO v2 深度学习进行目标检测示例中训练的网络生成代码。有关详细信息,请参阅Object Detection Using YOLO v2 Deep Learning (Computer Vision Toolbox)。您可以修改此示例,以便为从 Computer Vision Toolbox™ 中的导入预训练 ONNX YOLO v2 目标检测器示例导入的网络生成 CUDA® MEX。有关详细信息,请参阅Import Pretrained ONNX YOLO v2 Object Detector (Computer Vision Toolbox)

第三方前提条件

必需

此示例生成 CUDA MEX,并具有以下第三方要求。

  • CUDA® 支持 NVIDIA® GPU 和兼容驱动程序。

可选

对于非 MEX 编译,如静态、动态库或可执行文件,此示例有以下附加要求。

验证 GPU 环境

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

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

获取预训练的 DAGNetwork

此示例使用包含预训练网络的 yolov2ResNet50VehicleExample MAT 文件。文件大小约为 98MB。从 MathWorks® 网站下载该文件。

matFile = matlab.internal.examples.downloadSupportFile('vision/data','yolov2ResNet50VehicleExample.mat');
vehicleDetector = load(matFile);
net = vehicleDetector.detector.Network
net = 
  DAGNetwork with properties:

         Layers: [150×1 nnet.cnn.layer.Layer]
    Connections: [162×2 table]
     InputNames: {'input_1'}
    OutputNames: {'yolov2OutputLayer'}

DAG 网络包含 150 层,包括卷积层、ReLU 层和批量归一化层,以及 YOLO v2 变换层和 YOLO v2 输出层。要以交互可视方式呈现深度学习网络架构,请使用 analyzeNetwork 函数。

analyzeNetwork(net);

yolov2_detect 入口函数

yolov2_detect.m 入口函数以图像作为输入,并使用保存在 yolov2ResNet50VehicleExample.mat 文件中的深度学习网络对图像运行检测器。该函数将 yolov2ResNet50VehicleExample.mat 文件中的网络对象加载到持久变量 yolov2Obj 中,并在后续的检测调用中重用该持久性对象。

type('yolov2_detect.m')
function outImg = yolov2_detect(in,matFile)

%   Copyright 2018-2021 The MathWorks, Inc.

persistent yolov2Obj;

if isempty(yolov2Obj)
    yolov2Obj = coder.loadDeepLearningNetwork(matFile);
end

% Call to detect method
[bboxes,~,labels] = yolov2Obj.detect(in,'Threshold',0.5);

% Convert categorical labels to cell array of charactor vectors
labels = cellstr(labels);

% Annotate detections in the image.
outImg = insertObjectAnnotation(in,'rectangle',bboxes,labels);

运行 MEX 代码生成

要为入口函数生成 CUDA 代码,请为 MEX 目标创建一个 GPU 代码配置对象,并将目标语言设置为 C++。使用 coder.DeepLearningConfig (GPU Coder) 函数创建一个 CuDNN 深度学习配置对象,并将其赋给 GPU 代码配置对象的 DeepLearningConfig 属性。运行 codegen 命令,指定 224×224×3 输入大小。该值对应于 YOLOv2 的输入层大小。

cfg = coder.gpuConfig('mex');
cfg.TargetLang = 'C++';
cfg.DeepLearningConfig = coder.DeepLearningConfig('cudnn');
cfg.GenerateReport = true;
inputArgs = {ones(224,224,3,'uint8'),coder.Constant(matFile)};

codegen -config cfg yolov2_detect -args inputArgs
Code generation successful: View report

运行生成的 MEX

设置视频文件读取器并读取输入视频。创建视频播放器来显示视频和输出检测。

videoFile = 'highway_lanechange.mp4';
videoFreader = VideoReader(videoFile);
depVideoPlayer = vision.DeployableVideoPlayer('Size','Custom','CustomSize',[640 480]);

逐帧读取视频输入,并使用检测器检测视频中的车辆。

while hasFrame(videoFreader)
    I = readFrame(videoFreader);
    in = imresize(I,[224,224]);
    out = yolov2_detect_mex(in,matFile);
    depVideoPlayer(out);
    % Exit the loop if the video player figure window is closed
    cont = hasFrame(videoFreader) && isOpen(depVideoPlayer); 
end

参考资料

[1] Redmon, Joseph, and Ali Farhadi."YOLO9000:Better, Faster, Stronger."2017 IEEE Conference on Computer Vision and Pattern Recognition (CVPR).IEEE, 2017.