COnnxRuntimeYoloV5Demo

程序员有二十年 2024-08-18 12:02:38
效果

模型信息 Model Properties----------------------------------------------------------------------------------------Inputs-------------------------name:imagestensor:Float[1, 3, 640, 640]---------------------------------------------------------------Outputs-------------------------name:outputtensor:Float[1, 25200, 85]name:350tensor:Float[1, 3, 80, 80, 85]name:416tensor:Float[1, 3, 40, 40, 85]name:482tensor:Float[1, 3, 20, 20, 85]---------------------------------------------------------------项目

代码

Form1.cs

using OpenCvSharp;using System;using System.Drawing;using System.Drawing.Imaging;using System.Text;using System.Windows.Forms;namespace Onnx_Demo{ public partial Form1 : Form { public Form1() { InitializeComponent(); } string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png"; string image_path = ""; string startupPath; DateTime dt1 = DateTime.Now; DateTime dt2 = DateTime.Now; Mat image; Mat result_image; YoloV5 yoloV5; private void button1_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog(); ofd.Filter = fileFilter;if (ofd.ShowDialog() != DialogResult.OK) return; pictureBox1.Image = ; image_path = ofd.FileName; pictureBox1.Image = new Bitmap(image_path); textBox1.Text = ""; pictureBox2.Image = ; } private void button2_Click(object sender, EventArgs e) {if (image_path == "") {return; } button2.Enabled = false; pictureBox2.Image = ; textBox1.Text = ""; Application.DoEvents(); //读图片 image = Cv2.ImRead(image_path);float confidence = 0.4f;if (!float.TryParse(txtConfidence.Text,out confidence)) { confidence = 0.4f; } dt1 = DateTime.Now; var detResults = yoloV5.Detect(image, confidence); dt2 = DateTime.Now; result_image = image.Clone(); image.Dispose(); StringBuilder sb=new StringBuilder(); foreach (DetectionResult r in detResults) { string info = $"{r.Class}:{r.Confidence:P0}"; //绘制 Cv2.PutText(result_image, info, new OpenCvSharp.Point(r.Rect.TopLeft.X, r.Rect.TopLeft.Y - 10), HersheyFonts.HersheySimplex, 1, Scalar.Red, 2); Cv2.Rectangle(result_image, r.Rect, Scalar.Red, thickness: 2); sb.AppendLine(info); } pictureBox2.Image = new Bitmap(result_image.ToMemoryStream()); result_image.Dispose(); textBox1.Text = "推理耗时:" + (dt2 - dt1).TotalMilliseconds + "ms\r\n"; textBox1.Text += "---------------------------\r\n"; textBox1.Text += sb.ToString(); button2.Enabled = true; } private void Form1_Load(object sender, EventArgs e) { startupPath = System.Windows.Forms.Application.StartupPath; yoloV5 = new YoloV5("model/yolov5n.onnx", "model/lable.txt"); image_path = "test_img/dog.jpg"; pictureBox1.Image = new Bitmap(image_path); image = new Mat(image_path); } private void pictureBox1_DoubleClick(object sender, EventArgs e) { Common.ShowNormalImg(pictureBox1.Image); } private void pictureBox2_DoubleClick(object sender, EventArgs e) { Common.ShowNormalImg(pictureBox2.Image); } SaveFileDialog sdf = new SaveFileDialog(); private void button3_Click(object sender, EventArgs e) {if (pictureBox2.Image == ) {return; } Bitmap output = new Bitmap(pictureBox2.Image); sdf.Title = "保存"; sdf.Filter = "Images (*.jpg)|*.jpg|Images (*.png)|*.png|Images (*.bmp)|*.bmp";if (sdf.ShowDialog() == DialogResult.OK) { switch (sdf.FilterIndex) {case 1: { output.Save(sdf.FileName, ImageFormat.Jpeg);break; }case 2: { output.Save(sdf.FileName, ImageFormat.Png);break; }case 3: { output.Save(sdf.FileName, ImageFormat.Bmp);break; } } MessageBox.Show("保存成功,位置:" + sdf.FileName); } } }}

YoloV5.cs

using Microsoft.ML.OnnxRuntime;using Microsoft.ML.OnnxRuntime.Tensors;using OpenCvSharp;using OpenCvSharp.Dnn;using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Text;namespace Onnx_Demo{ internal YoloV5 {float[] input_image; int inpWidth = 640; int inpHeight = 640;float confThreshold;float nmsThreshold; List<string>es; SessionOptions options; InferenceSession onnx_session; public YoloV5(string modelPath, stringesPath) { confThreshold = 0.5f; nmsThreshold = 0.5f;es = File.ReadAllLines(classesPath, Encoding.UTF8).ToList(); options = new SessionOptions(); options.LogSeverityLevel = OrtLoggingLevel.ORT_LOGGING_LEVEL_INFO; options.AppendExecutionProvider_CPU(0);// 设置为CPU上运行 // 创建推理模型类,读取本地模型文件 onnx_session = new InferenceSession(modelPath, options); } public List<DetectionResult> Detect(Mat frame, float confidence) {float ratio = 0.0f; confThreshold = confidence; List<DetectionResult> detResults = new List<DetectionResult>(); int max_image_length = frame.Cols > frame.Rows ? frame.Cols : frame.Rows; Mat max_image = Mat.Zeros(new OpenCvSharp.Size(max_image_length, max_image_length), MatType.CV_8UC3); Rect roi = new Rect(0, 0, frame.Cols, frame.Rows); frame.CopyTo(new Mat(max_image, roi)); Cv2.CvtColor(max_image, max_image, ColorConversionCodes.BGR2RGB); Cv2.Resize(max_image, max_image, new Size(inpWidth, inpHeight)); ratio = (float)(max_image_length / 640.0); max_image.ConvertTo(max_image, MatType.CV_32FC3, (float)(1 / 255.0)); var input = new DenseTensor<float>(Common.ExtractMat(max_image), new[] { 1, 3, inpHeight, inpWidth }); max_image.Dispose(); // Setup inputs and outputs var inputs = new List<NamedOnnxValue> { NamedOnnxValue.CreateFromTensor("images", input) }; var results = onnx_session.Run(inputs); //Postprocessing var resultsArray = results.ToArray(); var pred_value = resultsArray[0].AsEnumerable<float>().ToArray(); var pred_dim = resultsArray[0].AsTensor<float>().Dimensions.ToArray(); var nc = pred_dim[pred_dim.Length - 1] - 5; var candidate = Common.GetCandidate(pred_value, pred_dim, confThreshold); //Compute conffor (int i = 0; i < candidate.Count; i++) { var obj_cnf = candidate[i][4];for (int j = 5; j < candidate[i].Count; j++) { candidate[i][j] *= obj_cnf; } }float[] confidenceInfo = new float[nc];float[] rectData = new float[4];for (int i = 0; i < candidate.Count; i++) { Array.Copy(candidate[i].ToArray(), 0, rectData, 0, 4); Array.Copy(candidate[i].ToArray(), 5, confidenceInfo, 0, nc);float score = confidenceInfo.Max(); // 获取最大值 int maxIndex = Array.IndexOf(confidenceInfo, score); // 获取最大值的位置 int _centerX = (int)(rectData[0] * ratio); int _centerY = (int)(rectData[1] * ratio); int _width = (int)(rectData[2] * ratio); int _height = (int)(rectData[3] * ratio); detResults.Add(new DetectionResult( maxIndex,es[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), confThreshold, nmsThreshold, out int[] indices); detResults = detResults.Where((x, index) => indices.Contains(index)).ToList();return detResults; } }}

0 阅读:2

程序员有二十年

简介:感谢大家的关注