目录效果模型信息项目代码下载效果模型信息Model Properties-------------------------descriptionUltralytics best model trained on data/head.yamlauthorUltralyticsversion8.1.29taskdetectlicenseAGPL-3.0 License (https://ultralytics.com/license)docshttps://docs.ultralytics.comstride32batch1imgsz[800, 800]names{0: head}---------------------------------------------------------------Inputs-------------------------nameimagestensorFloat16[1, 3, 800, 800]---------------------------------------------------------------Outputs-------------------------nameoutput0tensorFloat16[1, 5, 13125]---------------------------------------------------------------项目代码using Microsoft.ML.OnnxRuntime;using Microsoft.ML.OnnxRuntime.Tensors;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 Onnx_Yolov8_Demo{public partial class Form1 : Form{public Form1(){InitializeComponent();}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;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;/// summary/// 选择图片/// /summary/// param namesender/param/// param namee/paramprivate void button1_Click(object sender, EventArgs e){OpenFileDialog ofd new OpenFileDialog();ofd.Filter fileFilter;if (ofd.ShowDialog() ! DialogResult.OK) return;pictureBox1.Image null;image_path ofd.FileName;pictureBox1.Image new Bitmap(image_path);textBox1.Text ;pictureBox2.Image null;}/// summary/// 推理/// /summary/// param namesender/param/// param namee/paramprivate void button2_Click(object sender, EventArgs e){if (image_path ){return;}button2.Enabled false;pictureBox2.Image null;textBox1.Text ;Application.DoEvents();Mat image new Mat(image_path);//图片缩放int height image.Rows;int width image.Cols;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(image, temp_image, new_size);}ratio_height (float)height / temp_image.Rows;ratio_width (float)width / temp_image.Cols;Mat input_img new Mat();Cv2.CopyMakeBorder(temp_image, input_img, 0, input_height - temp_image.Rows, 0, input_width - temp_image.Cols, BorderTypes.Constant, 0);//Cv2.ImShow(input_img, input_img);//输入TensorTensorFloat16 input_tensor new DenseTensorFloat16(new[] { 1, 3, input_width, input_height });for (int y 0; y input_img.Height; y){for (int x 0; x input_img.Width; x){input_tensor[0, 0, y, x] (Float16)(input_img.AtVec3b(y, x)[0] / 255f);input_tensor[0, 1, y, x] (Float16)(input_img.AtVec3b(y, x)[1] / 255f);input_tensor[0, 2, y, x] (Float16)(input_img.AtVec3b(y, x)[2] / 255f);}}ListNamedOnnxValue input_container new ListNamedOnnxValue{NamedOnnxValue.CreateFromTensor(images, input_tensor)};//推理dt1 DateTime.Now;var ort_outputs onnx_session.Run(input_container).ToArray();dt2 DateTime.Now;Float16[] data Transpose(ort_outputs[0].AsTensorFloat16().ToArray(), 4 class_num, box_num);Float16[] confidenceInfo new Float16[class_num];Float16[] rectData new Float16[4];ListDetectionResult detResults new ListDetectionResult();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);Float16 score confidenceInfo.Max(); // 获取最大值int maxIndex Array.IndexOf(confidenceInfo, score); // 获取最大值的位置if (maxIndex -1) maxIndex 0;int _centerX (int)((float)rectData[0] * ratio_width);int _centerY (int)((float)rectData[1] * ratio_height);int _width (int)((float)rectData[2] * ratio_width);int _height (int)((float)rectData[3] * ratio_height);detResults.Add(new DetectionResult(maxIndex,class_names[maxIndex],new Rect(_centerX - _width / 2, _centerY - _height / 2, _width, _height),(float)score));}//NMSCvDnn.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();//绘制结果Mat result_image image.Clone();foreach (DetectionResult r in detResults){Cv2.PutText(result_image, ${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(result_image, r.Rect, Scalar.Red, thickness: 2);}pictureBox2.Image new Bitmap(result_image.ToMemoryStream());textBox1.Text 推理耗时: (dt2 - dt1).TotalMilliseconds ms;button2.Enabled true;}/// summary///窗体加载/// /summary/// param namesender/param/// param namee/paramprivate void Form1_Load(object sender, EventArgs e){model_path model/v8-head-fp16.onnx;//创建输出会话用于输出模型读取信息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 800;input_width 800;box_num 13125;conf_threshold 0.25f;nms_threshold 0.5f;classer_path model/lable.txt;class_names File.ReadAllLines(classer_path, Encoding.UTF8);class_num class_names.Length;image_path test_img/1.jpg;pictureBox1.Image new Bitmap(image_path);}/// summary/// 保存/// /summary/// param namesender/param/// param namee/paramprivate void button3_Click(object sender, EventArgs e){if (pictureBox2.Image null){return;}Bitmap output new Bitmap(pictureBox2.Image);SaveFileDialog sdf new SaveFileDialog();sdf.Title 保存;sdf.Filter Images (*.jpg)|*.jpg|Images (*.png)|*.png|Images (*.bmp)|*.bmp|Images (*.emf)|*.emf|Images (*.exif)|*.exif|Images (*.gif)|*.gif|Images (*.ico)|*.ico|Images (*.tiff)|*.tiff|Images (*.wmf)|*.wmf;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;}case 4:{output.Save(sdf.FileName, ImageFormat.Emf);break;}case 5:{output.Save(sdf.FileName, ImageFormat.Exif);break;}case 6:{output.Save(sdf.FileName, ImageFormat.Gif);break;}case 7:{output.Save(sdf.FileName, ImageFormat.Icon);break;}case 8:{output.Save(sdf.FileName, ImageFormat.Tiff);break;}case 9:{output.Save(sdf.FileName, ImageFormat.Wmf);break;}}MessageBox.Show(保存成功位置 sdf.FileName);}}private void pictureBox1_DoubleClick(object sender, EventArgs e){ShowNormalImg(pictureBox1.Image);}private void pictureBox2_DoubleClick(object sender, EventArgs e){ShowNormalImg(pictureBox2.Image);}public void ShowNormalImg(Image img){if (img null) return;frmShow frm new frmShow();frm.Width Screen.PrimaryScreen.Bounds.Width;frm.Height Screen.PrimaryScreen.Bounds.Height;if (frm.Width img.Width){frm.Width img.Width;}if (frm.Height img.Height){frm.Height img.Height;}bool b frm.richTextBox1.ReadOnly;Clipboard.SetDataObject(img, true);frm.richTextBox1.ReadOnly false;frm.richTextBox1.Paste(DataFormats.GetFormat(DataFormats.Bitmap));frm.richTextBox1.ReadOnly b;frm.ShowDialog();}public unsafe Float16[] Transpose(Float16[] tensorData, int rows, int cols){Float16[] transposedTensorData new Float16[tensorData.Length];fixed (Float16* pTensorData tensorData){fixed (Float16* pTransposedData transposedTensorData){for (int i 0; i rows; i){for (int j 0; j cols; j){int index i * cols j;int transposedIndex j * rows i;pTransposedData[transposedIndex] pTensorData[index];}}}}return transposedTensorData;}}public class DetectionResult{public DetectionResult(int ClassId, string Class, Rect Rect, float Confidence){this.ClassId ClassId;this.Confidence Confidence;this.Rect Rect;this.Class Class;}public string Class { get; set; }public int ClassId { get; set; }public float Confidence { get; set; }public Rect Rect { get; set; }}}using Microsoft.ML.OnnxRuntime; using Microsoft.ML.OnnxRuntime.Tensors; 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 Onnx_Yolov8_Demo { public partial class Form1 : Form { public Form1() { InitializeComponent(); } 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; 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; /// summary /// 选择图片 /// /summary /// param namesender/param /// param namee/param private void button1_Click(object sender, EventArgs e) { OpenFileDialog ofd new OpenFileDialog(); ofd.Filter fileFilter; if (ofd.ShowDialog() ! DialogResult.OK) return; pictureBox1.Image null; image_path ofd.FileName; pictureBox1.Image new Bitmap(image_path); textBox1.Text ; pictureBox2.Image null; } /// summary /// 推理 /// /summary /// param namesender/param /// param namee/param private void button2_Click(object sender, EventArgs e) { if (image_path ) { return; } button2.Enabled false; pictureBox2.Image null; textBox1.Text ; Application.DoEvents(); Mat image new Mat(image_path); //图片缩放 int height image.Rows; int width image.Cols; 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(image, temp_image, new_size); } ratio_height (float)height / temp_image.Rows; ratio_width (float)width / temp_image.Cols; Mat input_img new Mat(); Cv2.CopyMakeBorder(temp_image, input_img, 0, input_height - temp_image.Rows, 0, input_width - temp_image.Cols, BorderTypes.Constant, 0); //Cv2.ImShow(input_img, input_img); //输入Tensor TensorFloat16 input_tensor new DenseTensorFloat16(new[] { 1, 3, input_width, input_height }); for (int y 0; y input_img.Height; y) { for (int x 0; x input_img.Width; x) { input_tensor[0, 0, y, x] (Float16)(input_img.AtVec3b(y, x)[0] / 255f); input_tensor[0, 1, y, x] (Float16)(input_img.AtVec3b(y, x)[1] / 255f); input_tensor[0, 2, y, x] (Float16)(input_img.AtVec3b(y, x)[2] / 255f); } } ListNamedOnnxValue input_container new ListNamedOnnxValue { NamedOnnxValue.CreateFromTensor(images, input_tensor) }; //推理 dt1 DateTime.Now; var ort_outputs onnx_session.Run(input_container).ToArray(); dt2 DateTime.Now; Float16[] data Transpose(ort_outputs[0].AsTensorFloat16().ToArray(), 4 class_num, box_num); Float16[] confidenceInfo new Float16[class_num]; Float16[] rectData new Float16[4]; ListDetectionResult detResults new ListDetectionResult(); 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); Float16 score confidenceInfo.Max(); // 获取最大值 int maxIndex Array.IndexOf(confidenceInfo, score); // 获取最大值的位置 if (maxIndex -1) maxIndex 0; int _centerX (int)((float)rectData[0] * ratio_width); int _centerY (int)((float)rectData[1] * ratio_height); int _width (int)((float)rectData[2] * ratio_width); int _height (int)((float)rectData[3] * ratio_height); detResults.Add(new DetectionResult( maxIndex, class_names[maxIndex], new Rect(_centerX - _width / 2, _centerY - _height / 2, _width, _height), (float)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(); //绘制结果 Mat result_image image.Clone(); foreach (DetectionResult r in detResults) { Cv2.PutText(result_image, ${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(result_image, r.Rect, Scalar.Red, thickness: 2); } pictureBox2.Image new Bitmap(result_image.ToMemoryStream()); textBox1.Text 推理耗时: (dt2 - dt1).TotalMilliseconds ms; button2.Enabled true; } /// summary ///窗体加载 /// /summary /// param namesender/param /// param namee/param private void Form1_Load(object sender, EventArgs e) { model_path model/v8-head-fp16.onnx; //创建输出会话用于输出模型读取信息 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 800; input_width 800; box_num 13125; conf_threshold 0.25f; nms_threshold 0.5f; classer_path model/lable.txt; class_names File.ReadAllLines(classer_path, Encoding.UTF8); class_num class_names.Length; image_path test_img/1.jpg; pictureBox1.Image new Bitmap(image_path); } /// summary /// 保存 /// /summary /// param namesender/param /// param namee/param private void button3_Click(object sender, EventArgs e) { if (pictureBox2.Image null) { return; } Bitmap output new Bitmap(pictureBox2.Image); SaveFileDialog sdf new SaveFileDialog(); sdf.Title 保存; sdf.Filter Images (*.jpg)|*.jpg|Images (*.png)|*.png|Images (*.bmp)|*.bmp|Images (*.emf)|*.emf|Images (*.exif)|*.exif|Images (*.gif)|*.gif|Images (*.ico)|*.ico|Images (*.tiff)|*.tiff|Images (*.wmf)|*.wmf; 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; } case 4: { output.Save(sdf.FileName, ImageFormat.Emf); break; } case 5: { output.Save(sdf.FileName, ImageFormat.Exif); break; } case 6: { output.Save(sdf.FileName, ImageFormat.Gif); break; } case 7: { output.Save(sdf.FileName, ImageFormat.Icon); break; } case 8: { output.Save(sdf.FileName, ImageFormat.Tiff); break; } case 9: { output.Save(sdf.FileName, ImageFormat.Wmf); break; } } MessageBox.Show(保存成功位置 sdf.FileName); } } private void pictureBox1_DoubleClick(object sender, EventArgs e) { ShowNormalImg(pictureBox1.Image); } private void pictureBox2_DoubleClick(object sender, EventArgs e) { ShowNormalImg(pictureBox2.Image); } public void ShowNormalImg(Image img) { if (img null) return; frmShow frm new frmShow(); frm.Width Screen.PrimaryScreen.Bounds.Width; frm.Height Screen.PrimaryScreen.Bounds.Height; if (frm.Width img.Width) { frm.Width img.Width; } if (frm.Height img.Height) { frm.Height img.Height; } bool b frm.richTextBox1.ReadOnly; Clipboard.SetDataObject(img, true); frm.richTextBox1.ReadOnly false; frm.richTextBox1.Paste(DataFormats.GetFormat(DataFormats.Bitmap)); frm.richTextBox1.ReadOnly b; frm.ShowDialog(); } public unsafe Float16[] Transpose(Float16[] tensorData, int rows, int cols) { Float16[] transposedTensorData new Float16[tensorData.Length]; fixed (Float16* pTensorData tensorData) { fixed (Float16* pTransposedData transposedTensorData) { for (int i 0; i rows; i) { for (int j 0; j cols; j) { int index i * cols j; int transposedIndex j * rows i; pTransposedData[transposedIndex] pTensorData[index]; } } } } return transposedTensorData; } } public class DetectionResult { public DetectionResult(int ClassId, string Class, Rect Rect, float Confidence) { this.ClassId ClassId; this.Confidence Confidence; this.Rect Rect; this.Class Class; } public string Class { get; set; } public int ClassId { get; set; } public float Confidence { get; set; } public Rect Rect { get; set; } } }下载源码下载