YOLOv3作为目标检测领域的经典算法,以其速度和精度的平衡著称。MATLAB从R2020b版本开始内置了YOLOv3支持,让我们无需配置复杂的深度学习环境就能快速实现人体检测。这个方案特别适合以下场景:
首先确保你的MATLAB版本满足要求:
matlab复制>> ver
检查是否包含"Computer Vision Toolbox"和"Deep Learning Toolbox"。推荐使用R2020b或更新版本。
安装预训练模型非常简单:
matlab复制net = yolov3ObjectDetector('tiny-yolov3-coco');
这里我们选择了'tiny-yolov3-coco'这个轻量级模型,它在COCO数据集上预训练,包含80类常见物体检测能力,其中就包含我们需要的人体检测。
注意:首次运行时会自动下载约60MB的模型文件,请确保网络连接正常。模型默认保存在
pretrained文件夹中。
让我们从一个最简单的检测示例开始:
matlab复制% 加载测试图像
img = imread('office.jpg');
% 执行检测
[bboxes, scores, labels] = detect(net, img);
% 可视化结果
detectedImg = insertObjectAnnotation(img, 'rectangle', bboxes, labels);
imshow(detectedImg)
这段代码完成了从检测到可视化的完整流程。其中:
bboxes是N×4矩阵,每行表示一个检测框的[x,y,width,height]scores是N×1置信度向量labels是N×1分类标签元胞数组默认检测阈值0.5比较保守,在实际场景中可能需要调整:
matlab复制[bboxes, scores, labels] = detect(net, img, 'Threshold', 0.3);
降低阈值可以提高召回率,但会增加误检。我的实测数据显示:
对于人群密集场景,建议采用"低阈值+NMS"的组合策略:
matlab复制[bboxes, scores] = detect(net, img, 'Threshold', 0.3);
[bboxes, scores] = selectStrongestBbox(bboxes, scores, 'OverlapThreshold', 0.4);
由于COCO数据集包含80类物体,我们需要专门提取人体检测结果:
matlab复制human_idx = find(labels == 'person');
valid_bboxes = bboxes(human_idx, :);
valid_scores = scores(human_idx);
这个过滤步骤可以避免将椅子、植物等误检为人。在复杂场景中,还可以添加面积过滤:
matlab复制areas = valid_bboxes(:,3) .* valid_bboxes(:,4);
valid_idx = areas > 500; % 过滤掉面积小于500像素的检测
YOLOv3的标准输入尺寸是416×416。直接resize会破坏原始宽高比,影响检测精度。正确的做法是:
matlab复制input_size = [416 416];
scale = min(input_size./size(img,[1 2]));
img_resized = imresize(img, scale);
% 边缘填充
pad = input_size - size(img_resized,[1 2]);
img_padded = padarray(img_resized, floor(pad/2), 128, 'pre');
img_padded = padarray(img_padded, ceil(pad/2), 128, 'post');
这种处理方式相比直接拉伸:
监控场景常遇到光照不均问题,可以添加预处理:
matlab复制img = imadjust(img, [0.1 0.9], []); % 对比度拉伸
img = imlocalbrighten(img); % 局部亮度增强
MATLAB的webcam接口使用非常简单:
matlab复制cam = webcam;
while true
img = snapshot(cam);
[bboxes, scores, labels] = detect(net, img);
% 只显示置信度>0.5的人体检测
human_idx = find(labels == 'person' & scores > 0.5);
if ~isempty(human_idx)
detectedImg = insertObjectAnnotation(img, 'rectangle',...
bboxes(human_idx,:), scores(human_idx));
else
detectedImg = img;
end
imshow(detectedImg)
drawnow
end
提升帧率的有效方法:
matlab复制net = yolov3ObjectDetector('tiny-yolov3-coco', 'ExecutionEnvironment', 'gpu');
在我的RTX 3060笔记本上实测帧率:
可能原因及解决方案:
优化策略:
改进方法:
虽然预训练模型已经表现不错,但在特定场景下微调可以显著提升性能。
matlab复制augmenter = imageDataAugmenter(...
'RandXReflection', true,...
'RandScale', [0.8 1.2],...
'RandRotation', [-15 15]);
典型训练选项:
matlab复制options = trainingOptions('sgdm',...
'InitialLearnRate', 0.001,...
'MiniBatchSize', 8,...
'MaxEpochs', 30,...
'ExecutionEnvironment', 'gpu');
matlab复制% 加载预训练模型
net = yolov3ObjectDetector('tiny-yolov3-coco');
% 准备训练数据
data = load('humanDataset.mat');
trainingData = objectDetectorTrainingData(data.gTruth);
% 微调模型
[detector, info] = trainYOLOv3ObjectDetector(trainingData, net, options);
微调后模型在特定场景下的改进效果:
结合MATLAB的计数功能:
matlab复制% 在视频循环中添加
prev_centroids = centroids; % 保存上一帧中心点
curr_centroids = bbox2centroid(bboxes); % 当前帧中心点
% 使用匈牙利算法匹配轨迹
[assignments, ~] = assignDetectionsToTracks(...
costMatrix(prev_centroids, curr_centroids), 0.2);
% 统计穿越虚拟线的次数
crossings = countCrossings(assignments, line_position);
通过检测框时序分析:
matlab复制speed = norm(centroid - prev_centroid) / dt;
if speed > speed_threshold
alert('快速移动检测');
end
使用MATLAB的Parallel Computing Toolbox实现:
matlab复制parfor i = 1:num_cams
img = getFrame(cams(i));
results{i} = detect(detector, img);
end
这种架构在400平米的监控区域实测可达到:
MATLAB的YOLOv3实现虽然可能在极限性能上不如一些专用框架,但其快速原型开发能力和与其他工具箱的无缝集成,使其成为工业级应用开发的高效选择。特别是在需要与控制系统、仿真模块联动的场景中,这种一体化解决方案能大幅缩短开发周期。