[C#]winform部署yolov5自定义数据集的目标检测模型onnx

 pt权重文件转换为onnx文件

使用python语言将训练好的模型.pt权重文件转换为onnx格式。

将原本yolov5中的export.py 程序简化了,只保留导出onnx文件部分。

import torch
import models
from models.experimental import attempt_load
from utils.general import check_img_size
import onnx

# Set the required arguments
weights_path = './1-5.7.pt'
img_size = [640, 640]
batch_size = 1
device = 'cpu'

# Load PyTorch model
model = attempt_load(weights_path, map_location=device)  # load FP32 model

# Checks
gs = int(max(model.stride))  # grid size (max stride)
img_size = [check_img_size(x, gs) for x in img_size]  # verify img_size are gs-multiples

# Input
img = torch.zeros(batch_size, 3, *img_size)  # image size(1,3,320,192) iDetection

# ONNX export
f = weights_path.replace('.pt', '.onnx')  # filename
torch.onnx.export(model, img, f, verbose=False, opset_version=12, input_names=['images'],
                  output_names=['output'],
                  dynamic_axes={'images': {0: 'batch', 2: 'height', 3: 'width'},  # size(1,3,640,640)
                                'output': {0: 'batch', 2: 'y', 3: 'x'}})

# Checks
onnx_model = onnx.load(f)  # load onnx model
onnx.checker.check_model(onnx_model)  # check onnx model
print('ONNX export success, saved as %s' % f)

使用上面代码导出onnx文件,注意:使用yolov8库导出onnx模型的程序(本人上一篇文章https://blog.csdn.net/2301_80438203/article/details/140459751)与yolov5的不能混用,两者格式不一致会报错。

下载yolov5-net

 在论坛中博主:该醒醒了~的文中直接在yolov5-net中修改,本人参考他的进行修改(感谢大佬),使用引入的方法。

文章:C#调用yolov5模型转化onnx模型实现C#模型部署icon-default.png?t=N7T8https://blog.csdn.net/qq_65356682/article/details/138177436?ops_request_misc=&request_id=&biz_id=102&utm_term=C&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-0-138177436.142^v100^pc_search_result_base4&spm=1018.2226.3001.4187#yoloV5&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-0-138177436.142^v100^pc_search_result_base4

首先去官网上下载  yolov5-net源码文件icon-default.png?t=N7T8https://github.com/techwingslab/yolov5-net创建一个.NET项目,在Nuget中安装以下库:
Microsoft.ML.OnnxRuntime 
OpenCvSharp4.Extensions 
OpenCvSharp4.Windows 
在下载的包中引用\yolov5-net-master\src\Yolov5Net.Scorer\bin\Debug\net6.0\Yolov5Net.Scorer.dll

添加现有项,选择"\yolov5-net-master\src\Yolov5Net.Scorer\Models\YoloCocoP5Model.cs"

打开添加进来的YoloCocoP5Model.cs,把YoloCocoP5Model修改一下,不要和原来的重复。

 YoloCocoP5Model.cs最终修改为下面代码:

using NetOnnx;
using Yolov5Net.Scorer.Models.Abstract;

namespace Yolov5Net.Scorer.Models;

public record YoloCocoP5Model2() : YoloModel(
    number.Width,
    number.Height,
    number.depth,

    number.dimensions,

    new[] { 8, 16, 32 },

    new[]
    {
        new[] { new[] { 010, 13 }, new[] { 016, 030 }, new[] { 033, 023 } },
        new[] { new[] { 030, 61 }, new[] { 062, 045 }, new[] { 059, 119 } },
        new[] { new[] { 116, 90 }, new[] { 156, 198 }, new[] { 373, 326 } }
    },

    new[] { 80, 40, 20 },

    0.80f,
    0.85f,
    0.85f,

    new[] { "output" },

    new()
    {
        new(1, number.jjabels[0]),
        new(2, number.jjabels[1]),
        new(3, number.jjabels[2]),
        new(4, number.jjabels[3]),
        new(5, number.jjabels[4]),
        new(6, number.jjabels[5]),
        new(7, number.jjabels[6]),
        new(8, number.jjabels[7]),
        new(9, number.jjabels[8]),
        new(10,number.jjabels[9]),
        new(11,number.jjabels[10]),
        new(12, number.jjabels[11]),
        new(13, number.jjabels[12]),
        new(14, number.jjabels[13]),
        new(15, number.jjabels[14]),
        new(16, number.jjabels[15]),
        new(17, "dog"),
        new(18, "horse"),
        new(19, "sheep"),
        new(20, "cow"),
        new(21, "elephant"),
        new(22, "bear"),
        new(23, "zebra"),
        new(24, "giraffe"),
        new(25, "backpack"),
        new(26, "umbrella"),
        new(27, "handbag"),
        new(28, "tie"),
        new(29, "suitcase"),
        new(30, "frisbee"),
        new(31, "skis"),
        new(32, "snowboard"),
        new(33, "sports ball"),
        new(34, "kite"),
        new(35, "baseball bat"),
        new(36, "baseball glove"),
        new(37, "skateboard"),
        new(38, "surfboard"),
        new(39, "tennis racket"),
        new(40, "bottle"),
        new(41, "wine glass"),
        new(42, "cup"),
        new(43, "fork"),
        new(44, "knife"),
        new(45, "spoon"),
        new(46, "bowl"),
        new(47, "banana"),
        new(48, "apple"),
        new(49, "sandwich"),
        new(50, "orange"),
        new(51, "broccoli"),
        new(52, "carrot"),
        new(53, "hot dog"),
        new(54, "pizza"),
        new(55, "donut"),
        new(56, "cake"),
        new(57, "chair"),
        new(58, "couch"),
        new(59, "potted plant"),
        new(60, "bed"),
        new(61, "dining table"),
        new(62, "toilet"),
        new(63, "tv"),
        new(64, "laptop"),
        new(65, "mouse"),
        new(66, "remote"),
        new(67, "keyboard"),
        new(68, "cell phone"),
        new(69, "microwave"),
        new(70, "oven"),
        new(71, "toaster"),
        new(72, "sink"),
        new(73, "refrigerator"),
        new(74, "book"),
        new(75, "clock"),
        new(76, "vase"),
        new(77, "scissors"),
        new(78, "teddy bear"),
        new(79, "hair drier"),
        new(80, "toothbrush")
    }, 

    true
);

 定义全局变量,标签种类,标签列表,图片宽高,图片深度。标签种类(number.dimensions)为实际数量加5.

public class number
{
    public static int dimensions;
    public static int Width;
    public static int Height;
    public static int depth;
    public static string[] jjabels;
}

进行初始化,标签列表先定义最高16种,需要的可以加。

private void Form1_Load(object sender, EventArgs e)
{
    number.depth = 3;
    number.Height = 640;
    number.Width = 640;
    textBox3.Text = number.depth.ToString();
    textBox4.Text = minConfidence.ToString();
    number.jjabels = new string[] { "dog", "songsu", "1", "2", "3", "4", "5", "8", "dog", "songsu", "1", "2", "3", "4", "5", "8" };
}

加载标签文件(txt文本),例如

OpenFileDialog opnDlg = new OpenFileDialog();
opnDlg.Filter = "标签文件 | *.txt";
opnDlg.Title = "打开标签文件";
opnDlg.ShowHelp = true;
opnDlg.Multiselect = false;
opnDlg.RestoreDirectory = true;

if (opnDlg.ShowDialog() == DialogResult.OK)
{
    string filePath = opnDlg.FileName;

    if (File.Exists(filePath))
    {
        string[] content = File.ReadAllLines(filePath);
        mylabel = new string[content.Length];
        number.dimensions = content.Length + 5;
        textBox2.Text = content.Length.ToString();
        for (int i = 0; i < content.Length; i++)
        {
            //MessageBox.Show(content[i].ToString());
            mylabel[i] = content[i];
        }
    }
    else
    {
        MessageBox.Show("文件不存在");
    }

    for (int i = 0; i < mylabel.Length; i++)
    {
        number.jjabels[i] = mylabel[i];
    }
}

到此准备工作完成。

读取onnx模型

OpenFileDialog opnDlg = new OpenFileDialog();
opnDlg.Filter = "模型文件 | *.onnx";
opnDlg.Title = "打开模型文件";
opnDlg.ShowHelp = true;
opnDlg.Multiselect = false;
opnDlg.RestoreDirectory = true;

if (opnDlg.ShowDialog() == DialogResult.OK)
{
    string filename = opnDlg.FileName;
    //加载模型
    try
    {
        scorer = new YoloScorer<YoloCocoP5Model2>(filename);
        if (scorer != null)
        {
            MessageBox.Show("模型加载成功\r\n");
        }
    }
    catch (System.Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

 使用添加进来的YoloCocoP5Model2读取模型

读取图片

OpenFileDialog dialog = new OpenFileDialog();
//dialog.Multiselect = true;//该值确定是否可以选择多个文件
dialog.Title = "请选择文件";
dialog.Filter = "图像文件(*.jpg;*.jpeg;*.bmp)|*.jpg;*.jpeg;*.bmp";
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
    string file = dialog.FileName;
    textBox1.Text = file;
 
    HOperatorSet.ReadImage(out ho_ModelImage1, file);
    //显示图片
    showImage();
    //使用模型进行预测
    showyolov5(dialog);
}

使用模型预测

string imgpath = dialog.FileName;
System.Drawing.Image inimage = System.Drawing.Image.FromFile(imgpath);
Image<Rgba32> image = ConvertImageToRgba32(inimage);
//图像预测
List<YoloPrediction> predictions = scorer.Predict(image);

//if (predictions != null)
if (predictions.Any())
{
    
    foreach (YoloPrediction prediction in predictions)
    {
        if (prediction.Score >= minConfidence)
        {
            var X = prediction.Rectangle.X;
            var Y = prediction.Rectangle.Y;
            var width = prediction.Rectangle.X + prediction.Rectangle.Width;
            var height = prediction.Rectangle.Y + prediction.Rectangle.Height;
            // 创建一个矩形
            HRegion rectangle = new HRegion();
            rectangle.GenRectangle1(new HTuple(Y), new HTuple(X), new HTuple(height), new HTuple(width));
            //MessageBox.Show(x.ToString()+y.ToString()+ width.ToString() + height.ToString());
            //MessageBox.Show(width.ToString()+height.ToString());
            // 显示矩形
            hWindowControl1.HalconWindow.SetDraw("margin");
            hWindowControl1.HalconWindow.DispObj(rectangle);
            string text = $"{prediction.Label.Name} [{Math.Round(prediction.Score, 2)}]";
            HOperatorSet.SetTposition(hWindowControl1.HalconWindow, Y, X);
            HOperatorSet.WriteString(hWindowControl1.HalconWindow, text);
        }

    }
}
private Image<SixLabors.ImageSharp.PixelFormats.Rgba32> ConvertImageToRgba32(System.Drawing.Image input)
{
    var memoryStream = new MemoryStream();
    input.Save(memoryStream, ImageFormat.Png);
    memoryStream.Position = 0;
    return SixLabors.ImageSharp.Image.Load<Rgba32>(memoryStream);
}

最终效果 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值