效果

模型信息
Model Properties-------------------------author:Ultralyticsversion:8.1.29task:detectlicense:AGPL-3.0 License (https://ultralytics.com/license)docs:https://docs.ultralytics.comstride:32batch:1imgsz:[640, 640]names:{0: 'carton'}---------------------------------------------------------------Inputs-------------------------name:imagestensor:Float[1, 3, 640, 640]---------------------------------------------------------------Outputs-------------------------name:output0tensor:Float[1, 5, 8400]---------------------------------------------------------------
项目

数据集

代码
using Microsoft.ML.OnnxRuntimeusing Microsoft.ML.OnnxRuntime.Tensorsusing OpenCvSharpusing OpenCvSharp.Dnnusing Systemusing System.Collections.Genericusing System.Drawingusing System.Drawing.Imagingusing System.Linqusing System.Textusing System.Windows.Formsnamespace Onnx_Yolov8_Demo{ public partial class Form1 : Form { public Form1() { InitializeComponent() } string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png" string image_path = "" string startupPath string classer_path DateTime dt1 = DateTime.Now DateTime dt2 = DateTime.Now string model_path Mat image DetectionResult result_pro Mat result_image Result result SessionOptions options InferenceSession onnx_session Tensor<float> input_tensor List<NamedOnnxValue> input_container IDisposableReadOnlyCollection<DisposableNamedOnnxValue> result_infer DisposableNamedOnnxValue[] results_onnxvalue Tensor<float> result_tensors 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 = "" image = new Mat(image_path) pictureBox2.Image = null } private void button2_Click(object sender, EventArgs e) { if (image_path == "") { return } float score_threshold = 0.5f float nms_threshold = 0.5f button2.Enabled = false pictureBox2.Image = null textBox1.Text = "" Application.DoEvents() //图片缩放 image = new Mat(image_path) int max_image_length = image.Cols > image.Rows ? image.Cols : image.Rows Mat max_image = Mat.Zeros(new OpenCvSharp.Size(max_image_length, max_image_length), MatType.CV_8UC3) Rect roi = new Rect(0, 0, image.Cols, image.Rows) image.CopyTo(new Mat(max_image, roi)) float[] result_array = new float[8400 * 84] float[] factors = new float[2] factors[0] = factors[1] = (float)(max_image_length / 640.0) // 将图片转为RGB通道 Mat image_rgb = new Mat() Cv2.CvtColor(max_image, image_rgb, ColorConversionCodes.BGR2RGB) Mat resize_image = new Mat() Cv2.Resize(image_rgb, resize_image, new OpenCvSharp.Size(640, 640)) // 输入Tensor for (int y = 0 { for (int x = 0 { input_tensor[0, 0, y, x] = resize_image.At<Vec3b>(y, x)[0] / 255f input_tensor[0, 1, y, x] = resize_image.At<Vec3b>(y, x)[1] / 255f input_tensor[0, 2, y, x] = resize_image.At<Vec3b>(y, x)[2] / 255f } } //将 input_tensor 放入一个输入参数的容器,并指定名称 input_container.Add(NamedOnnxValue.CreateFromTensor("images", input_tensor)) dt1 = DateTime.Now //运行 Inference 并获取结果 result_infer = onnx_session.Run(input_container) dt2 = DateTime.Now // 将输出结果转为DisposableNamedOnnxValue数组 results_onnxvalue = result_infer.ToArray() // 读取第一个节点输出并转为Tensor数据 result_tensors = results_onnxvalue[0].AsTensor<float>() result_array = result_tensors.ToArray() resize_image.Dispose() image_rgb.Dispose() result_pro = new DetectionResult(classer_path, factors, score_threshold, nms_threshold) result = result_pro.process_result(result_array) result_image = result_pro.draw_result(result, image.Clone()) StringBuilder sb = new StringBuilder() if (!result_image.Empty()) { pictureBox2.Image = new Bitmap(result_image.ToMemoryStream()) //textBox1.Text = "推理耗时:" + (dt2 - dt1).TotalMilliseconds + "ms" sb.AppendLine("推理耗时:" + (dt2 - dt1).TotalMilliseconds + "ms") sb.AppendLine("--------------------------------------------------") sb.AppendLine("{lable}{scores}({X},{Y},{Width},{Height})") sb.AppendLine("--------------------------------------------------") // 识别结果 for (int i = 0 { //Scalar color= Scalar.RandomColor() Scalar color = new Scalar(0, 0, 255) string lable = string.Format("{0}\t{1}\t({2},{3},{4},{5})" , result.classes[i] , result.scores[i].ToString("P2") , result.rects[i].X , result.rects[i].Y , result.rects[i].Width , result.rects[i].Height ) sb.AppendLine(lable) //Cv2.Rectangle(image, result.rects[i], color, 2, LineTypes.Link8) //Cv2.Rectangle(image // , new Point(result.rects[i].TopLeft.X - 1, result.rects[i].TopLeft.Y - 20) // , new Point(result.rects[i].TopLeft.X - 1 + lable.Length * 12, result.rects[i].TopLeft.Y) // , color // , -1) //Cv2.PutText(image, lable, new Point(result.rects[i].X, result.rects[i].Y - 4), HersheyFonts.HersheySimplex, 0.6, new Scalar(0, 0, 0), 1) } textBox1.Text = sb.ToString() } else { textBox1.Text = "无信息" } button2.Enabled = true } private void Form1_Load(object sender, EventArgs e) { startupPath = System.Windows.Forms.Application.StartupPath model_path = "model/carton.onnx" classer_path = "model/lable.txt" // 创建输出会话,用于输出模型读取信息 options = new SessionOptions() options.LogSeverityLevel = OrtLoggingLevel.ORT_LOGGING_LEVEL_INFO options.AppendExecutionProvider_CPU(0) // 创建推理模型类,读取本地模型文件 onnx_session = new InferenceSession(model_path, options) // 输入Tensor input_tensor = new DenseTensor<float>(new[] { 1, 3, 640, 640 }) // 创建输入容器 input_container = new List<NamedOnnxValue>() image_path = "test_img/4.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 == null) { return } Bitmap output = new Bitmap(pictureBox2.Image) 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) } } } public class DetectionResult : ResultBase { /// <summary> /// 结果处理类构造 /// </summary> /// <param name="path">识别类别文件地址</param> /// <param name="scales">缩放比例</param> /// <param name="score_threshold">分数阈值</param> /// <param name="nms_threshold">非极大值抑制阈值</param> public DetectionResult(string path, float[] scales, float score_threshold = 0.25f, float nms_threshold = 0.5f) { read_class_names(path) this.scales = scales this.score_threshold = score_threshold this.nms_threshold = nms_threshold } /// <summary> /// 结果处理 /// </summary> /// <param name="result">模型预测输出</param> /// <returns>模型识别结果</returns> public Result process_result(float[] result) { Mat result_data = new Mat(4 + class_num, 8400, MatType.CV_32F, result) result_data = result_data.T() // 存放结果list List<Rect> position_boxes = new List<Rect>() List<int> class_ids = new List<int>() List<float> confidences = new List<float>() // 预处理输出结果 for (int i = 0 { Mat classes_scores = result_data.Row(i).ColRange(4, 4 + class_num) OpenCvSharp.Point max_classId_point, min_classId_point double max_score, min_score // 获取一组数据中最大值及其位置 Cv2.MinMaxLoc(classes_scores, out min_score, out max_score, out min_classId_point, out max_classId_point) // 置信度 0~1之间 // 获取识别框信息 if (max_score > this.score_threshold) { float cx = result_data.At<float>(i, 0) float cy = result_data.At<float>(i, 1) float ow = result_data.At<float>(i, 2) float oh = result_data.At<float>(i, 3) int x = (int)((cx - 0.5 * ow) * this.scales[0]) int y = (int)((cy - 0.5 * oh) * this.scales[1]) int width = (int)(ow * this.scales[0]) int height = (int)(oh * this.scales[1]) Rect box = new Rect() box.X = x box.Y = y box.Width = width box.Height = height position_boxes.Add(box) class_ids.Add(max_classId_point.X) confidences.Add((float)max_score) } } // NMS非极大值抑制 int[] indexes = new int[position_boxes.Count] CvDnn.NMSBoxes(position_boxes, confidences, this.score_threshold, this.nms_threshold, out indexes) Result re_result = new Result() // 将识别结果绘制到图片上 for (int i = 0 { int index = indexes[i] int idx = class_ids[index] re_result.add(confidences[index], position_boxes[index], this.class_names[class_ids[index]]) } return re_result } /// <summary> /// 结果绘制 /// </summary> /// <param name="result">识别结果</param> /// <param name="image">绘制图片</param> /// <returns></returns> public Mat draw_result(Result result, Mat image) { // 将识别结果绘制到图片上 for (int i = 0 { //Scalar color= Scalar.RandomColor() Scalar color = new Scalar(0, 0, 255) string lable = result.classes[i] + "-" + result.scores[i].ToString("0.00") Cv2.Rectangle(image, result.rects[i], color, 2, LineTypes.Link8) Cv2.Rectangle(image , new OpenCvSharp.Point(result.rects[i].TopLeft.X - 1, result.rects[i].TopLeft.Y - 20) , new OpenCvSharp.Point(result.rects[i].TopLeft.X - 1 + lable.Length * 12, result.rects[i].TopLeft.Y) , color , -1) Cv2.PutText(image, lable, new OpenCvSharp.Point(result.rects[i].X, result.rects[i].Y - 4), HersheyFonts.HersheySimplex, 0.6, new Scalar(0, 0, 0), 1) } return image } }}
下载
download.csdn.net/download/lw…
download.csdn.net/download/lw…