当前位置: 首页 > article >正文

最新深度学习YoloV11训练,转化,推理,C#部署

注意本文主要是介绍YoloV11的相关操作以及主要应用,想要了解yolov11的人可以看网上其他人的介绍

目录

 一、环境配置

如果你是yolo的初学者建议先看看yolov5

 Anaconda3下载

cuda-11.7

cudnn

 torch -1.13.0

 二、标注数据

 三、训练

四、推理

五、转化

六、部署C#模型 onnx


ultralvtics发布了最新的作品YOLOv11,这一次YOLOv11的变化相对于ultralvtics公司的上一代作品YOLOv8变化不是很大的 (YOLOv9YOLOv10均不是uitralyics公司作品),其中改变的位置涉及到C21变为C3K2,在SPPF后面加了一层类似于注意力机制的C2PSA,还有一个变化大家从yaml文件是看不出来的就是它的检测头内部替换了两个DWConv,以及模型的深度和宽度参数进行了大幅度调整,但是在损失函数方面就没有变化还是采用的CIoU作为边界框回归损失,下面带大家深入理解一下ultralytics最新作品YOLOv11的创新点。

源码下载 GitHub - ultralytics/ultralytics: Ultralytics YOLO11 🚀

如果打不开直接下载我的就可以:

         【免费】Yolov11最新的源码文件包含(训练,转化,推理)脚本文件资源-CSDN文库

 一、环境配置

如果你是yolo的初学者建议先看看yolov5

yolov5-7.0实现训练推理以及C#部署onnx-CSDN博客

       关于环境你可以直接用V5的环境,因为这俩是一个人的作品相关环境不会有太大差异。

      配置pytorch  去这里下载相对应的包

cuda和cudnn各个版本的Pytorch下载网页版,onnx,ncnn,pt模型转化工具_cuda国内镜像下载网站-CSDN博客

如果打不开网页直接下载我的

 Anaconda3下载

【免费】Anaconda3-2021.11-Windows-x86-64安装包资源-CSDN文库

下载三个包并配置,cuda和cudnn配置网上都有可以搜搜

cuda-11.7

        链接:https://pan.baidu.com/s/1pjtN6y7qBu8R5oDrg7vf2A 
        提取码:tru8

cudnn

链接:https://pan.baidu.com/s/1jTBaT3_cNpj_JDB3xpMf6Q 
        提取码:618j

 torch -1.13.0

相关torch包都在这里

       链接:https://pan.baidu.com/s/1aR_SwoPtZiMw25LO_KZHsw 
       提 取码:kt93

安装配置之后就可以安装其他的包了。

pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple/

 有一点要注意 因为你配置的是gpu的pytorch和cuda 所以你下载requirements.txt 中的torch和torchvision项要给注释掉或者直接删掉,建议删掉

 二、标注数据

 标注是用labelimg 

  直接pip下载

pip install labelimg -i https://pypi.tuna.tsinghua.edu.cn/simple

如果想把自己的标签导入labelimg中直接再下方路径里创建一个data文件夹添加你的classes.txt文件就行了

F:Anaconda3\envs\ 你安装labelimg的环境 \Lib\site-packages\labelImg

添加后就有了但是需要注意的是txt的命名有要求的   predefined_classes.txt

 三、训练

标注后需要如下放置方式

程序中如下读取

如果你下载的是我的代码那么你可以直接配置train.py进行训练

你也可以在命令行中训练

python train.py --cache

四、推理

配置你训练完的模型和需要推理的样本文件夹即可 再运行

五、转化

需要转化成什么模型 就替换onnx那里就可以

随即就可以部署了

六、部署C#模型 onnx

可以先图片处理 缩放输入的规格

int height = temp_image.Height;
int width = temp_image.Width;
//Mat temp_image = image.Clone();

if (height > input_height || width > input_width)
{
    float scale = Math.Min((float)input_height / height, (float)input_width / width);
    OpenCvSharp.Size new_size = new OpenCvSharp.Size((int)(width * scale), (int)(height * scale));
    Cv2.Resize(temp_image, temp_image, new_size);
}
ratio_height = (float)height / temp_image.Rows;
ratio_width = (float)width / temp_image.Cols;

//Mat input_img = new Mat();
//Mat temp_image2 = Cv2.ImRead(image_path, ImreadModes.Color);
Cv2.CopyMakeBorder(temp_image, temp_image, 0, input_height - temp_image.Rows, 0, input_width - temp_image.Cols, BorderTypes.Constant);

Cv2.ImShow("input_img", input_img);

输入Tensor
Tensor<float> input_tensor = new DenseTensor<float>(new[] { 1, 3, 640, 640 });

for (int y = 0; y < temp_image.Height; y++)
{
    for (int x = 0; x < temp_image.Width; x++)
    {
        input_tensor[0, 0, y, x] = temp_image.At<Vec3b>(y, x)[0] / 255f;
        input_tensor[0, 1, y, x] = temp_image.At<Vec3b>(y, x)[1] / 255f;
        input_tensor[0, 2, y, x] = temp_image.At<Vec3b>(y, x)[2] / 255f;
    }
}

List<NamedOnnxValue> input_container = new List<NamedOnnxValue>
{
NamedOnnxValue.CreateFromTensor("images", input_tensor)
};

 这是绘制结果部分

Cv2.PutText(inputMat, $"{r.Class}:{r.Confidence:P0}", new OpenCvSharp.Point(r.Rect.TopLeft.X, r.Rect.TopLeft.Y - 10), HersheyFonts.HersheySimplex, 1, Scalar.Red, 2);
Cv2.Rectangle(inputMat, r.Rect, Scalar.Red, thickness: 2);

主函数完整流程

using Microsoft.ML.OnnxRuntime;
using OpenCvSharp;
using OpenCvSharp.Dnn;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace YoloV11WinformDome
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            model_path = @"H:\YCDandPCB_Yolov5_net\yoloV11\YoloV11WinformDome\YoloV11WinformDome\model\yolo11n.onnx";

            classer_path = @"H:\YCDandPCB_Yolov5_net\yoloV11\YoloV11WinformDome\YoloV11WinformDome\model\label.txt";
        }
        string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";
        string image_path = "";
        string model_path;
        string classer_path;
        public string[] class_names;
        public int class_num;
        List<DetectionResult> detResults = new List<DetectionResult>();

        DateTime dt1 = DateTime.Now;
        DateTime dt2 = DateTime.Now;

        int input_height;
        int input_width;
        float ratio_height;
        float ratio_width;

        InferenceSession onnx_session;

        int box_num;
        float conf_threshold;
        float nms_threshold;

        private void button1_Click(object sender, EventArgs e)
        {
            
            SessionOptions options = new SessionOptions();
            options.LogSeverityLevel = OrtLoggingLevel.ORT_LOGGING_LEVEL_INFO;
            options.AppendExecutionProvider_CPU(0);// 设置为CPU上运行

            
            onnx_session = new InferenceSession(model_path, options);//model_path 为onnx模型文件的路径

            input_height = 640;
            input_width = 640;

            box_num = 8400;
            conf_threshold = 0.55f;
            nms_threshold = 0.5f;

            //classer_path = @"H:\YCDandPCB_Yolov5_net\yoloV11\WindowsFormsApp120\WindowsFormsApp12\model\label.txt";
            //label2.Text = "labels";
            class_names = File.ReadAllLines(classer_path, Encoding.UTF8);
            class_num = class_names.Length;
            Adds_images();

        }

        private void Adds_images(/*object sender, EventArgs e*/)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = fileFilter;
            if (ofd.ShowDialog() != DialogResult.OK) return;            
            image_path = ofd.FileName;            
            Mat temp_image = new Mat();
            temp_image = Cv2.ImRead(image_path, ImreadModes.Color);

            //图片缩放
            int height = temp_image.Height;
            int width = temp_image.Width;
         

            if (height > input_height || width > input_width)
            {
                float scale = Math.Min((float)input_height / height, (float)input_width / width);
                OpenCvSharp.Size new_size = new OpenCvSharp.Size((int)(width * scale), (int)(height * scale));
                Cv2.Resize(temp_image, temp_image, new_size);
            }
            ratio_height = (float)height / temp_image.Rows;
            ratio_width = (float)width / temp_image.Cols;

            
            Cv2.CopyMakeBorder(temp_image, temp_image, 0, input_height - temp_image.Rows, 0, input_width - temp_image.Cols, BorderTypes.Constant);

            ;

            输入Tensor
            Tensor<float> input_tensor = new DenseTensor<float>(new[] { 1, 3, 640, 640 });

            for (int y = 0; y < temp_image.Height; y++)
            {
                for (int x = 0; x < temp_image.Width; x++)
                {
                    input_tensor[0, 0, y, x] = temp_image.At<Vec3b>(y, x)[0] / 255f;
                    input_tensor[0, 1, y, x] = temp_image.At<Vec3b>(y, x)[1] / 255f;
                    input_tensor[0, 2, y, x] = temp_image.At<Vec3b>(y, x)[2] / 255f;
                }
            }

            List<NamedOnnxValue> input_container = new List<NamedOnnxValue>
            {
            NamedOnnxValue.CreateFromTensor("images", input_tensor)
            };

            //推理
            dt1 = DateTime.Now;
            var ort_outputs = onnx_session.Run(input_container).ToArray();
            dt2 = DateTime.Now;

            Yolov11model yolov11Model = new Yolov11model();
            float[] data = yolov11Model.Transpose(ort_outputs[0].AsTensor<float>().ToArray(), 4 + class_num, box_num);

            float[] confidenceInfo = new float[class_num];
            float[] rectData = new float[4];

            for (int i = 0; i < box_num; i++)
            {
                Array.Copy(data, i * (class_num + 4), rectData, 0, 4);
                Array.Copy(data, i * (class_num + 4) + 4, confidenceInfo, 0, class_num);

                float score = confidenceInfo.Max(); // 获取最大值

                int maxIndex = Array.IndexOf(confidenceInfo, score); // 获取最大值的位置

                int _centerX = (int)(rectData[0] * ratio_width);
                int _centerY = (int)(rectData[1] * ratio_height);
                int _width = (int)(rectData[2] * ratio_width);
                int _height = (int)(rectData[3] * ratio_height);

                detResults.Add(new DetectionResult(
                    maxIndex,
                    class_names[maxIndex],
                    new Rect(_centerX - _width / 2, _centerY - _height / 2, _width, _height),
                    score));
            }

            //NMS
            CvDnn.NMSBoxes(detResults.Select(x => x.Rect), detResults.Select(x => x.Confidence), conf_threshold, nms_threshold, out int[] indices);
            detResults = detResults.Where((x, index) => indices.Contains(index)).ToList();

            if (detResults.Count == 0)
            {
                label2.Text = "无目标";
            }
            //绘制结果
            Mat inputMat = Cv2.ImRead(image_path, ImreadModes.Color);
            foreach (DetectionResult r in detResults)
            {
                if (r.Class.ToString() == r.Class)
                {
                    if (r.Class == "15: cat")
                    {
                        int int0 = detResults.Count(result => result.Class == "15: cat");

                        Cv2.PutText(inputMat, $"{r.Class}:{r.Confidence:P0}", new OpenCvSharp.Point(r.Rect.TopLeft.X, r.Rect.TopLeft.Y - 10), HersheyFonts.HersheySimplex, 1, Scalar.Red, 2);
                        Cv2.Rectangle(inputMat, r.Rect, Scalar.Red, thickness: 2);
                        int count = detResults.Count;
                        label2.Text = "ok   " + "找到目标    " + count + "猫    " + int0;
                    }
                }            }
            pictureBox2.Image = new Bitmap(inputMat.ToMemoryStream());
            textBox1.Text = "推理耗时:" + (dt2 - dt1).TotalMilliseconds + "ms";
            //button2.Enabled = true;
            }
        }
    }

http://www.kler.cn/a/451165.html

相关文章:

  • 亚信安全举办“判大势 悟思想 强实践”主题党日活动
  • springboot项目对数据库密码加解密
  • nmap扫描优化
  • 【RAG实战】Prompting vs. RAG vs. Finetuning: 如何选择LLM应用选择最佳方案
  • 记录一个SVR学习
  • 华为EC6108V9/C 通刷固件包,内含高安版及详细教程
  • uniapp跨平台开发---webview调用app方法
  • Scala图书管理系统
  • 【电路笔记 信号】Metastability 平均故障间隔时间(MTBF)公式推导:进入亚稳态+退出亚稳态+同步器的可靠性计算
  • php时间strtotime函数引发的问题 时间判断出错
  • LabVIEW软件开发的未来趋势
  • 【前端】详解前端三大主流框架:React、Vue与Angular的比较与选择
  • 老旧小区用电安全保护装置#限流式防火保护器参数介绍#
  • Spring Boot 3.4新特性:RestClient和RestTemplate的重大更新详解
  • Python 标准库:random——随机数
  • 【Chrome Extension】一、CSDN计时扩展设计
  • Swift Type Erasure(类型擦除)
  • 【docker】pull 镜像异常
  • Redis--通用命令学习
  • centos权限大集合,覆盖多种权限类型,解惑权限后有“. + t s”问题!
  • 技术与教育的融合:构建现代成绩管理系统
  • 4、数据结构与算法解析(C语言版)--栈
  • PH热榜 | 2024-12-24
  • 提高保养效率:4S店预约系统的设计与开发
  • SpringBoot简单使用Stomp
  • 深入理解批量归一化(BN):原理、缺陷与跨小批量归一化(CmBN)