主要内容

交通标志检测与识别

这个例子展示了如何为一个使用深度学习的交通标志检测和识别应用程序生成CUDA®MEX代码。交通标志检测与识别是驾驶员辅助系统的重要应用,为驾驶员提供有关道路标志的信息。

在这个交通标志检测和识别示例中,您执行三个步骤-检测、非最大抑制(NMS)和识别。首先,该示例使用目标检测网络检测输入图像上的交通标志,该网络是YOLO网络的一种变体。然后,利用NMS算法抑制重叠检测。最后,识别网络对检测到的交通标志进行分类。

第三方先决条件

要求

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

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

可选择的

对于非mex构建,如静态、动态库或可执行文件,本例有以下附加要求。

验证GPU环境

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

envCfg=coder.gpuEnvConfig(“主机”);envCfg.DeepLibTarget=“cudnn”;envCfg。DeepCodegen = 1;envCfg。安静= 1;coder.checkGpuInstall (envCfg);

检测与识别网络

检测网络在Darknet框架中进行训练,并导入MATLAB®进行推理。由于交通标志的大小相对于图像的大小相对较小,并且训练数据中每类的训练样本数较少,因此所有交通标志都被视为用于训练检测网络的单个类。

检测网络将输入图像划分为7×7的网格。如果交通标志的中心位于网格单元内,则每个网格单元检测交通标志。每个网格单元预测两个边界框和这些边界框的置信度。置信度表示框中是否包含对象。每个网格单元预测概率在网格单元中查找交通标志的能力。最终分数是前面分数的乘积。您在此最终分数上应用0.2的阈值来选择检测。

利用MATLAB对同一图像进行网络训练。

trainRecognitionnet.m辅助脚本显示了识别网络的训练。

获得预先训练过的系列网络

下载检测和识别网络。

getSDR();

检测网络包含58层,包括卷积层、泄漏ReLU层和全连接层。

负载(“yolo_tsr.mat”); 蛋黄层
ans=58×1带层的层阵列:1“输入”图像输入448×448×3图像2“conv1”卷积64 7×7×3卷积带跨步[2]和填充[3 3 3]3“relu1”泄漏ReLU泄漏ReLU比例为0.1 4“pool1”最大池2×2最大池带跨步[2]和填充[0 0]5'conv2'卷积192 3×3×64卷积带跨步[1]和填充[1]6'relu2'泄漏ReLU泄漏ReLU泄漏ReLU带刻度0.1 7'池2'最大池2×2最大池带跨步[2]和填充[0 0 0 0 0]8'conv3'卷积128 1×1×192卷积带跨步[1]和填充[0 0 0 0 0 0]9'relu3'泄漏ReLU泄漏ReLU泄漏ReLU刻度为0.1 10'conv4'卷积256 3×3×128卷积带跨步[1]和填充[1 1]11'relu4'泄漏ReLU泄漏ReLU泄漏ReLU刻度为0.1 12'conv5'卷积256 1×1×256卷积带跨步[1]和填充[0 0]13“relu5”Leaky ReLU Leaky ReLU比例为0.1 14“conv6”卷积512 3×3×256卷积带跨步[1]和填充[1 1]15“relu6”Leaky ReLU Leaky ReLU比例为0.1 16“pool6”最大池2×2最大池带跨步[2]和填充[0 0 0 0]17“conv7”卷积256 1×1×512卷积带跨步[1]和填充[0 0 0 0 0]18'relu7'泄漏ReLU泄漏ReLU泄漏ReLU刻度为0.1 19'conv8'卷积512 3×3×256卷积带跨步[1 1]和填充[1 1 1]20'relu8'泄漏ReLU泄漏ReLU泄漏ReLU刻度为0.1 21'conv9'卷积256 1×1×512卷积带跨步[1]和填充[0 0 0 0]22“relu9”泄漏ReLU泄漏ReLU泄漏ReLU比例为0.1 23“conv10”卷积512 3×3×256卷积步长为[11]和填充[11]24“relu10”泄漏ReLU泄漏ReLU泄漏ReLU比例为0.1 25“conv11”卷积256 1×1×512卷积步长为[11]和填充[0 0 0]26“relu11”泄漏ReLU泄漏ReLU泄漏ReLU刻度为0.1 27“conv12”卷积512 3×3×256卷积带跨步[1]和填充[1 1]28“relu12”泄漏ReLU泄漏ReLU泄漏ReLU刻度为0.1 29“conv13”卷积256 1×1×512卷积带跨步[1]和填充[0 0]30'relu13'泄漏ReLU泄漏ReLU泄漏ReLU比例为0.1 31'conv14'卷积512 3×3×256卷积步长为[11]和填充[11]32'relu14'泄漏ReLU泄漏ReLU泄漏ReLU比例为0.1 33'conv15'卷积512 1×1×512卷积步长为[11]和填充[0 0]34“relu15”Leaky ReLU Leaky ReLU比例为0.1 35“conv16”卷积1024 3×3×512卷积步幅为[11]和填充为[11]36“relu16”Leaky ReLU Leaky ReLU比例为0.1 37“pool16”最大池2×2最大池步幅为[22]和填充为[0 0 0 0]38“conv17”卷积512 1×1×1024卷积步幅为[11]以及填充[0 0 0 0 0]39'relu17'泄漏ReLU泄漏ReLU泄漏ReLU具有0.1 40'conv18'卷积1024 3×3×512卷积具有跨步[1 1],填充[1 1 1 1 1]41'relu18'泄漏ReLU泄漏ReLU具有0.1 42'conv19'卷积512 1×1×1024卷积具有跨步[1]和填充[0 0 0 0 0 0 0]43'relu19'泄漏ReLU泄漏ReLU泄漏ReLU刻度为0.1 44'conv20'卷积1024 3×3×512卷积带跨步[1]和填充[1 1 1]45'relu20'泄漏ReLU泄漏ReLU泄漏ReLU刻度为0.1 46'conv21'卷积1024 3×3×1024卷积带跨步[1]和填充[1 1 1]47'relu21'泄漏ReLU泄漏ReLU泄漏ReLU比例为0.1 48'conv22'卷积1024 3×3×1024卷积带跨步[2]和填充[1 1 1]49'relu22'泄漏ReLU泄漏ReLU泄漏ReLU泄漏ReLU比例为0.1 50'conv23'卷积1024 3×3×1024卷积带跨步[1]和填充[1 1 1 1]51“relu23”泄漏ReLU泄漏ReLU刻度为0.1的ReLU 52“conv24”卷积1024 3×3×1024卷积带跨步[1]和填充[1]53“relu24”漏ReLU漏ReLU漏ReLU漏ReLU漏ReLU漏ReLU漏ReLU漏ReLU漏ReLU漏ReLU漏ReLU漏ReLU漏ReLU漏ReLU漏ReLU漏ReLU漏ReLU漏ReLU漏ReLU漏ReLU漏ReLU漏ReLU漏ReLU漏ReLU漏ReLU漏ReLU漏ReLU漏ReLU漏ReLU漏ReLU漏ReLU漏ReLU漏ReLU漏ReLU漏ReLU漏ReLU漏ReLU漏ReLU漏ReLU漏ReLU漏ReLU漏ReLU漏ReLU漏ReLU漏ReLU漏ReLU

该识别网络包含14层,包括卷积层、全连接层和分类输出层。

负载(“RecognitionNet.mat”);事先。层
ans=14×1层阵列,带层:1“imageinput”图像输入48×48×3图像,带“zerocenter”归一化和“randfliplr”增强2“conv_1”卷积100 7×7×3卷积,带跨步[1]和填充[0 0 0 0 0 0 0 0]3“relu__1”relu 4“maxpool_1”最大池2×2最大池,带跨步[2]和填充[0 0 0 0 0 0 0 0 0 0 0 0]5'conv_2'卷积150 4×4×100卷积带跨步[1]和填充[0 0 0 0]6'relu_2'relu relu 7'maxpool_2'最大池2×2最大池带跨步[2]和填充[0 0 0 0 0 0]8'conv_3'卷积250 4×4×150卷积带跨步[1]和填充[0 0 0 0 0 0 0 0 0 0 0]9'maxpool_3'最大池带跨步2×2最大池带跨步[2]和padding[0 0 0 0 0]10'fc_1'完全连接300完全连接层11'dropout'dropout 90%dropout 12'fc_2'完全连接35完全连接层13'softmax'softmax softmax 14'classoutput'分类输出与'0'和34其他类交叉输入

tsdr_predict入口点函数

tsdr_.m入口点函数取图像输入,利用检测网络检测图像中的交通标志。该功能通过使用函数抑制重叠检测(NMS)selectStrongestBbox并利用识别网络对交通标志进行识别。该函数用于从中加载网络对象yolo_tsr.mat变成一个持久变量探测网认可网变成一个持久变量recognitionnet.该函数在后续调用中重用持久对象。

类型(“tsdr_predict.m”
函数[selectedBbox idx] = tsdr_predict (img) % # codegen %这个函数图像中检测交通标志使用检测网络%(修改版Yolo)意思和识别(分类)使用识别网络输入% %:% % im:输入测试图像% %输出:% % selectedBbox:检测边界框% idx:版权所有2017-2019 The MathWorks, Inc. coder.gpu.kernelfun;% resize图像img_rz = imresize(img,[448,448]);%转换为BGR格式img_rz = img_rz(:,:,3:-1:1);img_rz = im2single (img_rz);%% TSD持续检测网;if isempty(detectionnet) detectionnet = coder.loadDeepLearningNetwork('yolo_tsr.mat','Detection'); / /检测网络end predictions = detectionnet.activations(img_rz,56,'OutputAs','channels');%%将预测转换为边界框属性类= 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

为以下对象生成CUDA MEX:tsdr_predict函数

为MEX目标创建GPU配置对象,并设置目标语言为c++。使用编码器。深度学习配置函数创建一个CuDNN的深度学习配置对象,并将其分配给深度学习配置属性。要生成CUDA MEX,请使用codegen命令并指定输入的大小为[480704,3]。此值对应于tsdr_predict作用

cfg = coder.gpuConfig (“墨西哥”);cfg。TargetLang =“c++”; cfg.DeepLearningConfig=coder.DeepLearningConfig(“cudnn”);codegen配置cfgtsdr_predictarg游戏{(480704 3 uint8)}-报告
代码生成成功:要查看报告,请打开('codegen/mex/tsdr_predict/html/report.mldatx')。

要使用TensorRT生成代码,请通过coder.DeepLearningConfig(“tensorrt”)作为编码器配置对象的选项,而不是“cudnn”

运行生成的MEX

加载输入图像。

我= imread ('停止,jpg')(imshow);;

调用tsdr\u\u mex在输入图像上。

Im = imresize(Im, [480,704]);[bboxes、类]= tsdr_predict_mex (im);

将类别编号映射到类别字典中的交通标志名称。

一会= {“补充道”“慢”“下降”“speedLimit25”“speedLimit35”“speedLimit40”“speedLimit45”...“speedLimit50”“speedLimit55”“speedLimit65”“speedLimitUrdbl”“doNotPass”“交叉口”...“keepRight”“拉尼兹”“合并”“noLeftTurn”“noRightTurn”“停下来”“pedestrianCrossing”...“停在前面”“rampSpeedAdvisory20”“rampSpeedAdvisory45”“卡车速度限制55”...“rampSpeedAdvisory50”“turnLeft”“rampSpeedAdvisoryUrdbl”“turnRight”“rightLaneMustTurn”...“收益率”“提前产量”“学校”“schoolSpeedLimit25”“zoneAhead45”“前方信号灯”}; classRec=类名称(类);

显示检测到的交通标志。

outputImage = insertShape (im,“矩形”,b盒子,“线宽”,3);对于i=1:size(bboxes,1)outputImage=insertText(outputImage,[bboxes(i,1)+bboxes(i,3)bboxes(i,2)-20],classRec{i},“字体大小”, 20岁,“输入TextColor”“红色”);终止imshow (outputImage);

基于视频的交通标志检测与识别

包含的辅助文件tsdr_testVideo.m从测试视频中获取帧,执行交通标志检测和识别,并在测试视频的每一帧上绘制结果。

%输入视频v=VideoReader('stop.avi');fps=0;
while hasFrame(v) %拍摄帧图片= readFrame(v);照片= imresize(图片,(920、1632));% Call MEX功能用于交通标志检测与识别[bboxes,一堂课]= tsdr_predict_mex(图);纽特= toc;
% FPS = .9* FPS + .1*(1/newt);
%显示
显示检测(图片、BBox、类别、fps);终止

清除加载到内存中的静态网络对象。

清晰的墨西哥人

另见

功能

物体

相关的话题