ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

基于Matlab的行人检测实战:从HOG+SVM到YOLO微调与部署

基于Matlab的行人检测实战:从HOG+SVM到YOLO微调与部署 简介这是基于MATLAB实现的行人检测完整工程包面向计算机视觉初学者、课程设计者及算法爱好者以SOBEL边缘检测为主线覆盖从边缘提取、运动目标识别到多目标跟踪的完整流程。包内共31个文件以22个m脚本为主涵盖检测、跟踪、去噪、均衡、建模等函数模块同时提供GUI界面文件便于按模块拆解学习并附带3个mp4与1个avi演示视频、3个fig界面、zip工具包和C辅助源文件可直接对照算法效果并支持二次开发压缩包整体大小48.85MB。已有1083人学习浏览适合用于课堂实验、毕业设计或作为行人检测算法入门与改进的实用参考。## 1. 监控场景下的行人检测Matlab 为什么仍是工程落地的高效选择 在安防摄像头、智慧交通和园区巡检这类固定机位监控场景里行人检测的核心诉求从来不是“算法越新越好”而是“在可接受的误检率下稳定检出且能快速交给业务系统”。Matlab 在这类任务里之所以没有被 Python 生态完全替代是因为 Computer Vision Toolbox 和 Deep Learning Toolbox 提供了从数据标注、模型训练到 C 代码部署的完整链路尤其适合算法工程师在几天内做出可演示、可测试的原型。本文不讨论“哪个框架更优越”而是围绕“行人检测_matlab_行人检测”这个主题给出一条从经典方法到深度学习的务实技术路径覆盖数据集组织、训练参数设置、检测效果调优和日志防篡改设计等工程落地环节。适合正在做监控系统原型验证、课程设计或小型安防项目的工程师参考。 ## 2. 行人检测的算法选型HOGSVM 与深度学习模型的分界线 ### 2.1 经典方法 HOGSVM 为什么仍在监控场景占有一席之地 HOGHistogram of Oriented Gradients方向梯度直方图特征描述的是局部图像区域的梯度方向分布对光照变化和几何形变有一定鲁棒性配合线性 SVM 分类器可以构成一个轻量级行人检测器。在 Matlab 中extractHOGFeatures 函数可以直接提取特征fitcecoc 或 fitcsvm 可以训练分类器。监控场景中相机位置固定、行人姿态相对直立HOGSVM 的检测速度在 CPU 上可以达到实时且无需 GPU 资源这对很多没有深度学习加速硬件的项目来说有实际意义。 matlab % 读取一张训练样本 img imread(pedestrian_001.png); if size(img, 3) 3 img rgb2gray(img); end % 提取 HOG 特征 [hogFeature, vis] extractHOGFeatures(img, CellSize, [8 8], BlockSize, [2 2]);这里的CellSize决定特征粒度[8 8]是常见默认配置适合 64x128 像素的行人检测窗口。BlockSize用于局部归一化[2 2]表示每个 Block 包含 2x2 个 Cell。提取的特征向量维度较高通常需要在训练前进行归一化处理。HOG 特征的核心思想是把图像分成小区域Cell统计每个区域的梯度方向直方图再通过 Block 归一化消除光照影响。在监控场景中行人通常占图像高度 100 到 300 像素这个尺度下 HOG 特征能很好描述轮廓信息。但它的局限也很明显对遮挡、姿态复杂、视角变化较大的场景检测率会明显下降。所以如果你处理的是密集人群或俯拍角度HOGSVM 可能不是最佳起点。2.2 基于深度学习的检测模型YOLO 与 SSD 在 Matlab 中的接入方式深度学习模型在行人检测任务上基本取代了传统方法主要因为卷积神经网络能自动学习更丰富的语义特征对遮挡、光照变化和复杂背景有更好的鲁棒性。Matlab 从 R2018b 开始支持yolov2ObjectDetector后续版本陆续加入yolov4ObjectDetector、ssdObjectDetector和fasterRCNNObjectDetector这使得在不离开 Matlab 环境的情况下训练和使用先进检测模型成为可能。% 加载预训练的 YOLO v4 检测器 net yolov4ObjectDetector(csp-darknet53-coco); % 对测试图像执行检测 img imread(monitoring_frame_01.jpg); [bboxes, scores, labels] detect(net, img, Threshold, 0.5); % 可视化检测结果 detectionImg insertObjectAnnotation(img, Rectangle, bboxes, scores); imshow(detectionImg);Threshold参数控制检测置信度阈值值越低检出越多但误检也会增加。在监控场景中建议初始设为 0.5后续根据实际误检率调整到 0.6 或 0.7。detect函数返回的bboxes是 Nx4 的矩阵每行对应一个检测框的[x, y, width, height]坐标。预训练模型基于 COCO 数据集虽然包含行人类别但针对监控这种固定视角场景微调是必要的。一个常见问题是直接用预训练模型检测监控视频会发现漏检率较高尤其是在行人较小或穿着与背景颜色相近时。这是因为 COCO 数据集中的行人图片多为自然照片与监控视角存在分布差异。因此使用自己的监控数据对模型进行微调Fine-tuning是推荐做法。2.3 误检率与漏检率的权衡IoU 阈值和置信度阈值的配合无论采用哪种模型行人检测的效果评估都离不开两个指标误检率False Positive Rate和漏检率False Negative Rate。在监控场景中误检会导致系统产生大量无效告警漏检则可能错过真正的安全事件。两者的权衡直接由两个参数控制置信度阈值和 NMS IoU 阈值。detect函数中的Threshold控制置信度阈值而selectStrongestBbox函数Matlab 自带 NMS中的RatioType和OverlapThreshold控制非极大值抑制强度。NMS 的目的是去除同一目标上的多个重叠检测框OverlapThreshold越大保留的重叠框越多也意味着检测越“宽容”。% 执行非极大值抑制减少重叠检测框 [selectedBboxes, selectedScores] selectStrongestBbox(bboxes, scores, ... OverlapThreshold, 0.5, RatioType, Union);OverlapThreshold设为 0.5 是经典 PASCAL VOC 标准RatioType选择Union表示重叠率计算使用并集面积适合不同大小目标的场景。如果你发现同一行人被输出多个检测框可以降低OverlapThreshold到 0.4但同时要留意这可能导致挨得很近的两个行人被合并成一个框。在监控场景中行人通常不会大规模重叠0.5 是一个稳健的起点。调节这两个参数时建议在验证集上画出 PR 曲线Precision-Recall Curve找到最符合业务需求的平衡点。3. Matlab 实现行人检测的完整流程从数据准备到模型训练3.1 用 Image Labeler 制作自己的行人检测数据集监控场景的行人检测最关键的环节不是模型结构而是数据质量。Matlab 提供了imageLabeler应用程序支持在交互式界面上标注矩形框也可以通过脚本批量标注。如果你有现成的标注文件如 PASCAL VOC 格式的 XML可以用bboxLabelDatastore直接读取避免重复劳动。创建数据存储的标准做法如下% 从文件夹创建图像数据存储 imds imageDatastore(monitoring_frames); % 从 XML 标注文件创建标签数据存储 blds bboxLabelDatastore(annotation_folder); % 合并为可用于训练的数据存储 ds combine(imds, blds); % 划分训练集和验证集比例为 8:2 [dsTrain, dsVal] splitEachLabel(ds, 0.8, 0.2);splitEachLabel的第三个参数是训练集比例这里设为 0.8。如果标注数据量较少可以先用augmentedImageDatastore做在线数据增强包括随机平移、翻转、亮度调整等。数据增强能显著提升模型的泛化能力尤其能缓解监控场景中不同光照条件和季节变化带来的影响。需要注意的是标注框必须是严格的矩形包围盒包含完整的行人轮廓但不过度包含背景否则训练时模型会学到错误的目标区域。经验上标注框的上边界贴到行人头顶下边界贴到脚底左右边界贴到肢体最外侧即可。3.2 训练 ACF 检测器Matlab 自带的行人检测传统方案如果你不想引入深度学习模型Matlab 的trainACFObjectDetector是一个值得尝试的中间方案。ACFAggregate Channel Features聚合通道特征是在 HOG 基础上扩展的特征表示同时利用颜色、梯度幅值和梯度直方图等多个通道的信息精度和速度都优于经典 HOGSVM。训练 ACF 检测器只需要三个输入标注数据、训练尺寸和训练参数。% 定义训练选项 options trainingOptions(sgdm, ... InitialLearnRate, 0.01, ... MaxEpochs, 10, ... MiniBatchSize, 64); % 训练 ACF 检测器 detector trainACFObjectDetector(dsTrain, ... ObjectTrainingSize, [64 32], ... NegativeSamplesFactor, 2, ... NumStages, 4, ... TrainingOptions, options);ObjectTrainingSize是行人检测窗口的尺寸[64 32]表示高度 64 像素、宽度 32 像素这是 ACF 检测器的默认推荐值。如果监控摄像头距地面较高行人在画面中较小可以把尺寸缩小到[48 24]但要注意过小的尺寸会丢失细节特征导致误检率上升。NegativeSamplesFactor控制负样本采样数量设为 2 表示负样本数量为正样本的 2 倍值越大误检率越低但训练时间也会增加。NumStages是级联分类器的级数级数越多误检率越低但检测速度越慢监控场景下 4 级是一个均衡配置。训练完成后detect函数可以用于推理使用方法与之前相同。3.3 微调 YOLOv4用少量数据适配监控视角对于有 GPU 并且需要更高精度的项目在预训练 YOLOv4 模型上进行微调是最实际的路线。微调的核心是保留网络前几层已经学到的通用特征提取能力只更新后几层的检测头。Matlab 中实现微调不需要手动修改网络结构trainYOLOv4ObjectDetector函数会自动完成网络构建和权重初始化。% 加载预训练检测器 baseDetector yolov4ObjectDetector(csp-darknet53-coco); % 定义训练参数 options trainingOptions(sgdm, ... InitialLearnRate, 0.001, ... LearnRateSchedule, piecewise, ... LearnRateDropPeriod, 5, ... LearnRateDropFactor, 0.1, ... MaxEpochs, 20, ... MiniBatchSize, 8, ... Shuffle, every-epoch); % 微调模型 detector trainYOLOv4ObjectDetector(dsTrain, baseDetector, options);微调时的学习率设置比从头训练要低一个数量级因为预训练权重已经处于一个较好的局部最优解附近过大的学习率会破坏已有的特征表示。这里InitialLearnRate设为 0.001并以 piecewise 方式逐步衰减。LearnRateDropFactor为 0.1 表示每经过LearnRateDropPeriod个 epoch学习率乘以 0.1。MiniBatchSize设为 8 是考虑 GPU 显存限制如果显存充足可以适当增大但不要超过 32否则梯度估计会变得不稳定。在监控场景中如果每帧图像中有大量行人建议增加MiniBatchSize并配合更大的输入图像尺寸因为小批量样本在小目标检测上表现更好。微调过程中应监控验证集的 loss 和 mAPmean Average Precision如果 loss 在几个 epoch 后不再下降说明学习率过大或数据集过于简单。3.4 检测日志的防篡改设计哈希链与时间戳绑定监控系统不仅要检测行人还要保证检测日志的可信性。如果日志可以被随意修改那么整个监控系统的证据价值就丧失了。常见做法是把检测结果按时间顺序记录并使用哈希链的方式防篡改。具体来说每条日志的哈希值不仅包含自身内容还包含上一条日志的哈希值这样任何中间节点的修改都会导致整条链断裂。% 定义日志结构体 logEntry struct(... timestamp, datestr(now, yyyy-mm-dd HH:MM:SS), ... frameId, frameId, ... bboxes, bboxes, ... hash, ); % 计算当前日志内容的 SHA-256 哈希 dataToHash sprintf(%s|%d|%s, logEntry.timestamp, logEntry.frameId, mat2str(bboxes)); logEntry.hash matlab.lang.makeValidName(dataToHash); % 简化示意实际需要调用数据哈希函数实际工程中建议使用 Java 或 Python 的哈希库Matlab 自身没有直接的 SHA-256 函数但可以通过 JavaMessageDigest或调用 OpenSSL 命令行实现。这里的关键设计是每条日志的哈希值必须包含上一条日志的哈希值形成链式结构。检测系统的日志防篡改设计还应该包括数字签名和审计日志数字签名可以保证日志生成者的身份可信审计日志记录系统访问行为。监控日志的存储建议使用只写介质如 WORM 存储同时定期进行完整性校验。4. 监控场景行人检测的实战调优小目标、遮挡和夜间场景的处理技巧4.1 小目标行人的多尺度检测策略监控场景最常见的困境是行人在画面中只占 30 到 60 像素的高度直接输入到检测器很难被识别。解决小目标检测问题的有效方法是多尺度检测即在不同图像分辨率上分别执行检测再把结果合并。Matlab 中可以使用detect函数的MiniBatchSize参数配合图像金字塔实现多尺度推理。% 生成图像金字塔 scales [1.0, 0.75, 0.5]; allBboxes []; allScores []; for i 1:length(scales) scaledImg imresize(img, scales(i)); [bboxes, scores] detect(detector, scaledImg, Threshold, 0.4); if ~isempty(bboxes) % 将检测框坐标映射回原始图像尺寸 bboxes bboxes / scales(i); allBboxes [allBboxes; bboxes]; allScores [allScores; scores]; end end % 合并多尺度检测结果执行 NMS [finalBboxes, finalScores] selectStrongestBbox(allBboxes, allScores, ... OverlapThreshold, 0.4, RatioType, Union);多尺度检测的核心是在不同缩放级别下原本很小的行人会变得足够大从而被检测器识别。scales数组定义了图像金字塔的缩放比例0.75和0.5分别对应 1.33 倍和 2 倍的检测尺度。注意检测框坐标在缩放后需要除以对应的比例因子才能映射回原始图像坐标。selectStrongestBbox的多尺度融合结果中OverlapThreshold应设置为小于单尺度 NMS 的值如 0.4因为不同尺度下的检测框会有更多重叠。多尺度检测的代价是计算量成倍增加一个备选方案是只在图像的下半部分地面区域做额外尺度的检测因为监控场景中行人几乎不会出现在画面顶部。4.2 遮挡场景通过检测框置信度与轨迹连续性降低漏检行人被遮挡是监控场景的常态尤其在人群密集的地铁站和商场入口。完全依靠单帧检测无法解决遮挡问题工程上主流方案是引入跟踪模块利用时间上下文预测被遮挡行人的位置。有个轻量级的做法是使用trackerGNN全局最近邻跟踪器将连续帧中的检测结果关联成轨迹当某帧检测框缺失时用上一帧的轨迹位置做插值。% 创建 GNN 跟踪器 tracker trackerGNN(FilterInitializationFcn, initConstantVelocityFilter, ... AssignmentThreshold, 30, ... ConfirmationThreshold, [3 5], ... DeletionThreshold, [5 5]); % 每帧调用跟踪器 confirmedTracks tracker(tracks, time);AssignmentThreshold是检测框与轨迹关联的最大距离单位像素设得越大越容易将远处的新检测框关联到已有轨迹但也容易产生错误的身份切换。ConfirmationThreshold [3 5]表示轨迹被确认所需的最少检测次数和最少数帧数值越大轨迹越稳定但确认延迟越高。DeletionThreshold [5 5]控制轨迹在连续丢失多少个检测框后被删除。在遮挡场景中合理使用跟踪器可以有效降低漏检率——当行人短暂被遮挡时跟踪器可以保持轨迹不中断等行人重新出现后立即恢复检测。需要说明的是跟踪并不能提高单帧检测精度它只是利用时间上下文做了预测平滑因此跟踪器参数应当根据场景的遮挡严重程度来设置。4.3 夜间与较差光照条件下的图像预处理夜间监控的红外图像和普通可见光图像在特征分布上有显著差异。直接在原始红外图像上做行人检测深度模型的精度通常会下降 15 到 20 个百分点。围绕这个问题一个实用的做法是在检测前加入图像增强预处理。直方图均衡化是简单有效的手段但对红外图像的增强效果有限更适合在检测前对可见光图像做去雾和亮度校正。% 对图像做 CLAHE 增强限制对比度以避免过曝 imgLab rgb2lab(img); L imgLab(:,:,1); Lenhanced adapthisteq(L, NumTiles, [8 8], ClipLimit, 0.02); imgLab(:,:,1) Lenhanced; imgEnhanced lab2rgb(imgLab);adapthisteq是自适应直方图均衡化ClipLimit是 0.02 表示对比度限制避免图像局部区域出现噪声放大。只在 Lab 色彩空间的 L 通道亮度上做增强保持颜色信息不变这样检测器看到的颜色特征不会被破坏。夜间场景的颜色信息本身有限如果使用红外摄像头建议训练时专门加入红外样本否则检测器很难泛化。一个容易被忽视的点是在增强图像上训练的模型部署时也必须在增强后的图像上运行否则会出现训练与推理不一致的问题。所以预处理模块的参数一旦在训练阶段确定部署时必须严格保持一致。4.4 误检消除的常见技巧多模型投票与候选区域限制监控系统中大量误检来自背景中的类人物体——电线杆、树桩、路牌、车辆尾部等。除了基于内容的检测还可以利用场景先验来排除误检。一个简单有效的技巧是设置“感兴趣区域”ROI把检测范围限制在行人可能出现的区域如道路和广场排除树木和建筑物区域。% 定义 ROI 多边形顶点坐标顺序为顺时针 roiPolygon [100 200; 500 200; 600 600; 50 600]; % 筛选检测框中心点是否在 ROI 内 centers [bboxes(:,1) bboxes(:,3)/2, bboxes(:,2) bboxes(:,4)/2]; inROI inpolygon(centers(:,1), centers(:,2), roiPolygon(:,1), roiPolygon(:,2)); filteredBboxes bboxes(inROI, :);inpolygon是 Matlab 内置函数判断点是否在多边形内。ROI 绘制可以在imageLabeler中人工标注也可以通过脚本生成。设置 ROI 的副作用是如果行人走到了 ROI 之外比如靠近摄像头边缘将不会被检测到。实际监控系统中应该定期检查 ROI 的设置是否仍然合理因为摄像头的角度可能因风或其他因素发生微小偏移导致检测区域漂移。从工程经验来看最稳妥的做法是在 ROI 基础上再额外设置一个“预警区域”当行人出现在 ROI 边缘区域时给系统发出提醒由业务逻辑决定是否需要触发告警。5. 用验证集指标体系判断行人检测模型是否合格5.1 核心指标计算精确率、召回率与单类平均精度 AP在行人检测任务中至少需要计算三类指标精确率Precision、召回率Recall和平均精度AP。精确率等于真正例除以真正例加假正例衡量的是模型检测出的框中有多少是真正的行人召回率等于真正例除以真正例加假负例衡量的是所有真实行人中有多少被检测出来。AP 是不同置信度阈值下 Precision-Recall 曲线下方的面积用于综合评价模型在多个阈值下的表现。% 计算验证集上的精确率和召回率 evaluationResults evaluateDetectionPrecision(detector, dsVal, 0.5); % 输出平均精度和召回率曲线 averagePrecision mean([evaluationResults.AP]); disp([Average Precision: , num2str(averagePrecision)]);evaluateDetectionPrecision的第三个参数 0.5 是 IoU 阈值表示当检测框与标注框的重叠率超过 0.5 时认为该检测是正确命中。在监控安防场景中0.5 的 IoU 阈值可能过于宽松——因为检测框只需要有一半以上与标注框重叠即可算作正确而安防告警对定位精度有更高要求。如果你的项目需要更精准的告警可以把 IoU 阈值提高到 0.6 或 0.7但同时 AP 值也会下降。一个 AP 为 0.8 的模型在实际监控中是否合格取决于业务端如何消费检测结果。如果要驱动云台联动需要更精确的框坐标如果只是统计人流量0.5 的 IoU 阈值就足够了。5.2 可视化分析用置信度曲线定位误检和漏检的分布模式指标只能告诉你“多少”不能告诉你“为什么”。定位误检和漏检的分布模式是调优的关键一个有效的方法是把验证集上的所有检测结果按置信度排序画出检测框置信度分布直方图并找出误检的样本图像。置信度分布通常呈双峰形状一个峰对应真实检测置信度较高另一个峰对应误检置信度较低。如果两个峰有明显重叠说明阈值很难同时兼顾误检和漏检。% 获取验证集所有检测结果及其置信度 results detect(detector, dsVal, Threshold, 0.1); allScores results.Scores; % 画出置信度分布直方图 histogram(allScores, 50); xlabel(Detection Confidence); ylabel(Number of Detections); grid on;把阈值从默认的 0.5 降到 0.1 是为了收集置信度较低但可能确实是真值的检测框。如果直方图中低置信度区域的峰值明显高于高置信度区域说明检测器对真实目标的置信度普遍不高需要考虑重新训练或更换模型如果高置信度区域存在大量误检说明正样本和负样本的特征区分度不够需要补充更多难负样本Hard Negative Mining。一种常用的难负样本挖掘方法是先用初始模型在无行人的背景图像上做检测把所有误检框作为额外负样本加入训练集重新训练模型。迭代两到三轮后误检率通常会有肉眼可见的下降。5.3 部署时的模型压缩与速度优化训练完成不等于可以上线。监控场景往往有较高的帧率要求15 FPS 以上Matlab 生成的检测模型在部署时通常需要做压缩或转换。一个操作风险低且有效的手段是使用 GPU Coder 将训练好的检测器转换为 CUDA 代码再由 C 封装成推理服务。另一种思路是直接利用coder.Constant约束输入尺寸这样可以大幅减少模型在推理时的内存占用和支路计算。你有两种选择让模型在任意分辨率下运行灵活性更高但速度更慢或者将输入分辨率固定为训练时的值Fast 但不够灵活。监控摄像头通常固定分辨率因此第二种选择是可行的。转换后需要对比转换前后的检测结果是否一致确保数值误差不会导致检测框偏移。% 配置代码生成参数目标为 CUDA GPU cfg coder.gpuConfig(exe); cfg.DeepLearningConfig coder.DeepLearningConfig(cudnn); % 生成的代码在 GPU 上完成推理 codegen -config cfg myDetectorPredict -args {coder.typeof(uint8(zeros(1080,1920,3)), [1080 1920 3], [0 0 0])};代码生成不是一次性工作coder.typeof中的输入尺寸必须与训练时一致否则会报尺寸不匹配的错误。如果在代码生成后遇到“数据类型不支持”的错误可以打开 GPU Coder 的日志定位是哪一层算子不兼容再决定是否替换网络中的某些层。常见的坑是自定义层如注意力模块可能不支持标准 CUDA 代码生成需要手动改写为标准层。此外模型压缩不止限于代码生成还包括权重剪枝和量化但这两者的实现复杂度和支持程度在各版本的 Matlab 中差异较大使用前务必查询当前版本的帮助文档。如果你的部署环境没有 GPU还有一个轻量级备选方案把检测器导出为 ONNX 格式再用 ONNX Runtime 在 CPU 上跑推理实测在 1080P 分辨率下 ACF 检测器可以达到 25 FPS 左右的性能。p a hrefhttps://download.csdn.net/download/weixin_42696271/25534562 stylecolor:#ec7500;font-size:14px; 本文还有配套的精品资源点击获取 /a img altmenu-r.4af5f7ec.gif srchttps://csdnimg.cn/release/wenkucmsfe/public/img/menu-r.4af5f7ec.gif stylewidth:16px;margin-left:4px;vertical-align:text-bottom;cursor:text; /p
返回列表