无脑使用matlab运行YOLOv5模型,实现目标检测

在这里插入图片描述



前言

YOLO 是一种经典的一阶段目标检测算法,它将检测问题转化为回归问题。与 Faster R-CNN 不同,YOLO 不是提取 RoI,而是直接通过回归的方法生成每个类的边界框坐标和概率。与 Faster R-CNN相比,大大提高了检测速度。Glenn Jocher 于 2020年提出了 YOLO 的第五个版本,命名为 YOLOv5,其网络结构主要分为骨干模块、颈部模块和头部模块。主干模块基于Focus、BottleneckCSP(跨阶段部分网络)和空间金字塔池,并将其传输到颈部模块。颈部模块基于PANet(路径聚合网络)生成特征金字塔。它通过双向融合低级空间特征和高级语义特征来增强检测不同尺度物体的能力。头部模块通过将锚框应用于来自颈部模块的多尺度特征图来生成检测框、类别信息、坐标和置信度。也有使用matlab完成YOLOv5目标检测,本文将参考 cuixing158 作者的源码,giehub地址为: yoloV5-yoloX-matlab

在这里插入图片描述
重点重点重点:为了代码运行不报错,安装 matlab 版本为 2021 及以上版本。
matlab安装教程大家可以参考这个教程: 手把手教你安装matlab软件

代码

运行效果如下:
在这里插入图片描述

我修改好的代码如下,直接复制即可运行,并解决运行会报错的问题解决一下,我也会把源码包放到公众号,末尾领取资料即可。代码整体流程是:

  1. 模型加载与初始化:

    加载预训练的YOLOv5模型(yolov5s.onnx)。
    设置相关参数,如输入尺寸(640x640)、阈值(0.3,0.5)。

  2. 图像读取与显示:

    读取待检测的图像(‘images/2.jpg’)并显示原图。

  3. 图像预处理:

    对图像进行大小调整(imresize), 将图像像素值缩放至[0,1]范围等

  4. 模型推理:

    使用feval函数进行模型的前向推理,得到检测结果(outs),包括多个检测头的输出。

  5. 解码YOLOv5输出:

    对YOLOv5的输出进行解码,得到每个检测框的坐标、置信度以及类别信息。

  6. 阈值过滤和非极大值抑制(NMS):

    过滤掉低置信度的检测框,对过滤后的检测框进行NMS处理,去除重叠较大的检测框,只保留最强的框。

修改好的代码如下:

model = "./yolov5s.onnx";
customYoloV5FcnName = 'yolov5fcn';
inputSize = [640,640];
throushHold = 0.3;
nmsThroushHold = 0.5;
outs = cell(3,1); % 3个检测head输出
classesNames = categorical(readlines("coco.names"));
colors = randi(255,length(classesNames),3);
params = importONNXFunction(model,customYoloV5FcnName);


image = imread('images/2.jpg');  % 修改为你需要识别的图片路径
imshow(image);
title('原始图像');

[H,W,~] = size(image);

% 图像预处理
img = imresize(image, inputSize);
img = rescale(img, 0, 1);  % 转换到[0,1]
img = permute(img, [3,1,2]);  % 改变维度顺序为 [C,H,W]
img = dlarray(reshape(img, [1, size(img)])); % n*c*h*w,[0,1],RGB顺序
if canUseGPU()
    img = gpuArray(img);
end

t1 = tic;
[outs{:}] = feval(customYoloV5FcnName, img, params, ...
    'Training', false, ...
    'InputDataPermutation', 'none', ...
    'OutputDataPermutation', 'none');  % 预测图像
fprintf('yolov5预测耗时:%.2f 秒\n', toc(t1));

outFeatures = yolov5Decode(outs, H, W);

%% 阈值过滤+NMS处理


scores = outFeatures(:, 5);
% 阈值过滤:只保留大于阈值的框
validIdxs = scores > throushHold;
outFeatures = outFeatures(validIdxs, :); 

% 提取边界框和对应的类别信息
allBBoxes = outFeatures(:, 1:4);
[maxScores, indxs] = max(outFeatures(:, 6:end), [], 2);
allScores = maxScores;
allLabels = classesNames(indxs);

% 如果存在有效边界框,则进行NMS非极大值抑制
if ~isempty(allBBoxes)
    [bboxes, nmsScores, labels] = selectStrongestBboxMulticlass(allBBoxes, allScores, allLabels, ...
        'RatioType', 'Min', 'OverlapThreshold', nmsThroushHold);
    annotations = string(labels) + ": " + string(nmsScores);
    % 获取类别ID并为每个类别分配颜色
    [~, ids] = ismember(labels, classesNames);
    color = colors(ids, :);
    image = insertObjectAnnotation(image, 'rectangle', bboxes, cellstr(annotations), ...
        'Color', color, 'LineWidth', 3);
end



% 显示结果图像
imshow(image);
title('检测结果图像');


function outPutFeatures = yolov5Decode(featuremaps, oriHight, oriWidth, anchors)
    arguments
        featuremaps (:,1) cell
        oriHight (1,1) double
        oriWidth (1,1) double
        anchors (:,2) double = [10,13; 16,30; 33,23;...
            30,61; 62,46; 59,119;...
            116,90; 156,198; 373,326]
    end
    %% yolov5*.onnx known params
    inputSize = 640;  % 输入网络图像大小,正方形图像输入
    na = 3;           % 每个检测head对应anchor的数量
    nc = 80;          % coco类别数量

    %% decode
    scaledX = inputSize./oriWidth;
    scaledY = inputSize./oriHight;
    outPutFeatures = [];
    numberFeaturemaps = length(featuremaps);

    for i = 1:numberFeaturemaps
        currentFeatureMap = featuremaps{i};  % bs*[(4+1+nc)*na]*h*w大小
        currentAnchors = anchors(na*(i-1)+1:na*i, :);  % na*2
        numY = size(currentFeatureMap, 3);
        numX = size(currentFeatureMap, 4);
        stride = inputSize ./ numX;

        % reshape currentFeatureMap到有意义的维度,bs*[(4+1+nc)*na]*h*w --> h*w*(5+nc)*na*bs
        % --> bs*na*h*w*(5+nc),最终的维度方式与yolov5官网兼容
        bs = size(currentFeatureMap, 1);
        h = numY;
        w = numX;
        disp(size(currentFeatureMap));
        currentFeatureMap = reshape(currentFeatureMap, bs, 5 + nc, na, h, w);  % bs*(5+nc)*na*h*w
        currentFeatureMap = permute(currentFeatureMap, [1, 3, 4, 5, 2]);  % bs*na*h*w*(5+nc)

        [~,~,yv,xv] = ndgrid(1:bs, 1:na, 0:h-1, 0:w-1);  % yv, xv大小都为bs*na*h*w,注意顺序,后面做加法维度标签要对应
        gridXY = cat(5, xv, yv);  % 第5维上扩展,大小为bs*na*h*w*2, x,y从1开始的索引
        currentFeatureMap = sigmoid(currentFeatureMap);  % yolov5是对所有值进行归一化,与yolov3/v4不同
        currentFeatureMap(:,:,:,:,1:2) = (2 * currentFeatureMap(:,:,:,:,1:2) - 0.5 + gridXY) .* stride;  % 大小为bs*na*h*w*2,预测对应xy
        anchor_grid = reshape(currentAnchors, 1, na, 1, 1, 2);  % 此处anchor_grid大小为1*na*1*1*2,方便下面相乘
        currentFeatureMap(:,:,:,:,3:4) = (currentFeatureMap(:,:,:,:,3:4) * 2).^2 .* anchor_grid;  % 大小为bs*na*h*w*2

        if nc == 1
            currentFeatureMap(:,:,:,:,6) = 1;
        end
        currentFeatureMap = reshape(currentFeatureMap, bs, [], 5 + nc);  % bs*N*(5+nc)

        if isempty(outPutFeatures)
            outPutFeatures = currentFeatureMap;
        else
            outPutFeatures = cat(2, outPutFeatures, currentFeatureMap);  % bs*M*(5+nc)
        end
    end

    %% 坐标转换到原始图像上
    % [cx, cy, w, h],yolov5.onnx基准图像大小(1*3*640*640)----> [x, y, w, h], 坐标基于原始图像大小(1*3*oriHight*oriWidth)

    outPutFeatures = extractdata(outPutFeatures);  % bs*M*(5+nc), 为[x_center, y_center, w, h, Pobj, p1, p2,..., pn]
    outPutFeatures(:,:,[1,3]) = outPutFeatures(:,:,[1,3]) ./ scaledX;  % x_center, width
    outPutFeatures(:,:,[2,4]) = outPutFeatures(:,:,[2,4]) ./ scaledY;  % y_center, height
    outPutFeatures(:,:,1) = outPutFeatures(:,:,1) - outPutFeatures(:,:,3) / 2;  % x
    outPutFeatures(:,:,2) = outPutFeatures(:,:,2) - outPutFeatures(:,:,4) / 2;  % y

    outPutFeatures = squeeze(outPutFeatures);  % 如果是单张图像检测,则输出大小为M*(5+nc),否则是bs*M*(5+nc)
    if (canUseGPU())
        outPutFeatures = gather(outPutFeatures);  % 推送到CPU上
    end
end

报错解决方法

第一次运行可能会报错
在这里插入图片描述
只需双击 onnxconverter.mlpkginstall 文件安装就行,安装页面需要登录邮箱,没有邮箱注册一个就行,我用的是qq邮箱。
在这里插入图片描述

缺点

目前还不能更换自己训练的模型,也可能作者是在旧版本yolov5中实现的,自己尝试更换,但是会出现很多目标框,还得向大佬学习matlab。


总结

我也会把源码包放到公众号,回复“matlab-yolov5”即可获取源码,关注我,带你不挂科!!!

在这里插入图片描述

### 使用YOLOv8进行目标检测 目前官方支持的YOLO版本在MATLAB中主要集中在YOLOv3以及更早版本[^1]。然而,社区和第三方开发者可能已经提供了针对YOLOv8的支持工具包或接口。对于希望利用最新YOLO架构(如YOLOv8)执行对象检测任务的研究者而言,通常有两种方法可以考虑: #### 方法一:通过ONNX模型转换实现YOLOv8集成 由于MathWorks尚未直接提供对YOLOv8原生支持,一种可行方案是从其他框架导出训练好的YOLOv8模型至中间表示形式(Intermediate Representation, IR),比如ONNX格式,再将其导入到MATLAB环境中用于推理。 具体操作如下所示: 1. 导入必要的库并加载预训练YOLOv8 ONNX模型。 2. 准备输入图像数据集。 3. 执行前向传播计算得到预测边界框与类别置信度分数。 4. 应用非极大抑制(NMS)算法筛选最终输出结果。 ```matlab % 加载ONNX模型 net = onnximport('yolov8.onnx'); % 假设img为待处理的一张图片变量 inputSize = net.Layers(1).InputSizes; processedImg = imresize(img,inputSize); % 进行推断 scores = predict(net, processedImg); ``` 此部分代码仅作为概念验证展示,并未完全覆盖整个流程细节,实际应用时需参照官方文档调整参数配置以匹配特定需求。 #### 方法二:调用Python API间接完成YOLOv8部署 另一种方式是借助MATLAB内置的`py.`命令来桥接Python环境中的YOLOv8实现。这种方法允许研究者充分利用已有的成熟解决方案而无需自行移植网络结构。 下面给出一段简单的例子说明如何设置跨语言交互过程: ```matlab % 初始化Python解释器及其依赖项 if ~isdeployed pyenv('Version', 'C:\path\to\your\python.exe'); end % 添加ultralytics仓库路径以便访问YOLOv8类定义 addPyPath = fullfile('D:', '\UltraLytics', 'ultralytics'); py.sys.path.insert(int32(0), addPyPath); % 创建YOLO实例并与之互动 detector = py.ultralytics.YOLO('yolov8n.pt'); results = detector.predict(py.array({imread('test.jpg')})); % 解析返回的结果... for i=1:length(results) disp(char(results{i}.boxes.cls)); end ``` 上述脚本片段展示了怎样建立连接、加载权重文件以及获取测试样本上的识别成果。需要注意的是,这里假设读者具备一定的Python编程基础并且熟悉安装额外软件包的过程。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

挂科边缘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值