YOlOv8 ONNXRunTime-gpu 推理

YOLO(You Only Look Once)是一种流行的物体检测和图像分割模型,由华盛顿大学的约瑟夫-雷德蒙(Joseph Redmon)和阿里-法哈迪(Ali Farhadi)开发。YOLO 于 2015 年推出,因其高速度和高精确度而迅速受到欢迎。

  • YOLOv8是YOLO 的最新版本,由Ultralytics 提供。YOLOv8 YOLOv8 支持全方位的视觉 AI 任务,包括检测分割姿态估计跟踪分类。这种多功能性使用户能够在各种应用和领域中利用YOLOv8 的功能。

根据YOLOv8官方文档介绍,通过使用model.export()将.pt文件转为.onnx文件。

from ultralytics import YOLO

# Load a model
model = YOLO('yolov8n.pt')  # load an official model
model = YOLO('path/to/best.pt')  # load a custom trained model

# Export the model
model.export(format='onnx')

YOLOv8预测目标检测模型

from ultralytics import YOLO

# Load a pretrained YOLOv8n model
model = YOLO('yolov8n.pt')

# Run inference on 'bus.jpg' with arguments
model.predict('bus.jpg', save=True, imgsz=320, conf=0.5)

将yolov8目标检测过程转移到C#中,调用GPU处理目标图像需提前引用一下模块:

using System;

using Microsoft.ML.OnnxRuntime.Tensors;
using Microsoft.ML.OnnxRuntime;
using OpenCvSharp;
using System.Runtime.InteropServices;

using Cv = OpenCvSharp.Cv2;

using System.Diagnostics;

将检测模型转到GPU中推理

        public OnnxRuntimeTest(string OnnxPATH, string DetectSavePath)
        {

            int gpuDeviceId = 0; // The GPU device ID to execute on
            using var gpuSessionOptoins = SessionOptions.MakeSessionOptionWithCudaProvider(gpuDeviceId);
            DetectSurface = new InferenceSession(OnnxPATH, gpuSessionOptoins);
            SavePath = DetectSavePath;

        }

定义模型参数:

        private int DetectBatch = 1;
        private int DetectChannl = 1;
        private int DetectWith = 512;
        private int DetectHeight = 512;

结合Opencv修改图片:

 List<Predict> out_res = new List<Predict>();
 //int class_max = 80;
 Mat mat_ori = Cv2.ImRead(readimg);
 int width = mat_ori.Width; 
 int height = mat_ori.Height;
 //double r = Math.Min(640.0 / width, 640.0 / height);
 //int scale_w = Convert.ToInt32(width * r) / 2 * 2;
 //int scale_h = Convert.ToInt32(height * r) / 2 * 2;
 //int dw = (int)((640 - scale_w) / 2f);
 //int dh = (int)((640 - scale_h) / 2f);
 Mat mat = new Mat();
 Cv.Resize(mat_ori, mat, new Size(512, 512));
 //Cv2.CopyMakeBorder(mat, mat, dh, dh, dw, dw, BorderTypes.Constant, new Scalar(114, 114, 114));
 DetectHeight = mat.Width;
 DetectWith = mat.Height;
 List<Predict> predicts = new List<Predict>();
 
 // 分类识别
 int[] dimensions = {DetectBatch, DetectChannl, DetectHeight, DetectWith };
 // int *dimensions :Numpy Array 数组每一维度数据的个数。
 int length = DetectChannl * DetectHeight * DetectWith;

彩色图像通道转换,并行加速赋值

            //并行运算加速赋值
            Parallel.For(0, total_pixel_count, (p_idx, state) =>
            {
                int r = p_idx;
                int g = r + total_pixel_count;
                int b = g + total_pixel_count;
                fbuff[r] = buffer[r * 3 + 2] / 255f;
                fbuff[g] = buffer[r * 3 + 1] / 255f;
                fbuff[b] = buffer[r * 3] / 255f;
            });

引入ONNX模型输入,输出参数

            Memory<float> memory = new Memory<float>(fbuff);
            DenseTensor<float> input = new DenseTensor<float>(memory, dimensions);
            string OutputMetadataName = DetectSurface!.OutputNames[0];
            string InputMetadataName = DetectSurface!.InputNames[0];
            // 将图片传至YOLO模型输入层
            var ClassInputs = new List<NamedOnnxValue>()
            {
                NamedOnnxValue.CreateFromTensor(InputMetadataName, input)
            };
            float[] res = ClassResults.First(item => item.Name == OutputMetadataName).AsEnumerable<float>().ToArray();

创建模型推理

            // 创建计时实例
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();

            IDisposableReadOnlyCollection<DisposableNamedOnnxValue> ClassResults = DetectSurface.Run(ClassInputs);

            stopwatch.Stop();
            // 计算时差
            TimeSpan elapsed = stopwatch.Elapsed;
            Console.WriteLine("runTime:" + elapsed.TotalMilliseconds + "ms");

获取模型推理结果,遍历检测参数,筛选符合条件(符合置信度要求)的目标:

                    double maxVal = 0;
                    int Index0 = 0;
                    for (int j = 4; j < length0; j++)
                    {
                        if (classValue[0, j, i] > 0.25f && classValue[0, j, i] > maxVal)
                        {
                            maxVal = classValue[0, j, i];
                            Index0 = j;
                        }                    
                    }

将符合检测要求的目标框,添加至预测坐标中

                    if (Index0 != 0)
                    {
                        predicts.Add(new()
                        {
                            CenterX = (int)classValue[0, 0, i],
                            CenterY = (int)classValue[0, 1, i],
                            Width = (int)classValue[0, 2, i],
                            Height = (int)classValue[0, 3, i],
                            Class = Index0 - 4,
                            Confidence = classValue[0, Index0, i]
                        });
                    }

显示检测结果,获取检测目标框,输出检测框,打印检测标签,保存检测结果为.bmp(其它格式文件会降低算法执行保存速率,其它格式需要系统会进行压缩,影响执行速率)

          if (have)
          {
              int a = 0;
              foreach (Predict emu_pre in predicts)
              {
                  //if (x_max < emu_pre.CenterX)
                  //{
                  //    x_max = emu_pre.CenterX;
                  //    i_max = a;
                  //}
                  int widthmax = (int)(width / 512f * predicts[a].Width);
                  int heightmax = (int)(height / 512f * predicts[a].Height);
                  int centerx = (int)(width / 512f * predicts[a].CenterX);
                  int centery = (int)(height / 512f * (predicts[a].CenterY));

                  // 检测目标坐标提取
                  Point point1 = new Point(centerx - (widthmax / 2), centery - (heightmax / 2));
                  Point point2 = new Point(centerx + (widthmax / 2), centery + (heightmax / 2));
                  Point point3 = new Point(centerx + (widthmax / 2), centery);
                  // 输出检测框
                  Cv.Rectangle(mat_ori, point1, point2, new Scalar(0, 0, 255), 2);
                  // 打印标签
                  string outtext = lableName[predicts[a].Class];
                  Cv.PutText(mat_ori, outtext, point3, HersheyFonts.HersheySimplex, 1, new Scalar(0, 255, 255));
                  //class_path = SavePath + "class\\" + predicts[a].Class.ToString() + "\\";
                  a++;
              }
                class_path = SavePath + "class\\" + predicts[i_max].Class.ToString() + "\\";
                if (!Directory.Exists(class_path))
                {
                    //创建文件夹
                    try
                    {
                        Directory.CreateDirectory(class_path);
                    }
                    catch (Exception e)
                    {

                    }
                }
                SaveFileName = class_path + data_time + ".bmp";
}

设置检测结果参数信息

            public int CenterX {  get; set; }
            public int CenterY { get; set; }

            public int Width {  get; set; }
            public int Height { get; set; }

            public float Confidence { get; set; }
            public int Class {  get; set; }

            public int CompareTo(Predict? other)
            {
                if (other?.Confidence - Confidence <= 0)
                {
                    return -1;
                }
                else
                {
                    return 1;
                }
            }

模型IOU计算

            public float IOU(Predict predict)
            {
                float w_2 = Width / 2;
                float h_2 = Height / 2;
                float x1 = CenterX - w_2, x2 = CenterX + w_2;
                float y1 = CenterY - h_2, y2 = CenterY + h_2;

                w_2 = predict.Width / 2;
                h_2 = predict.Height / 2;
                float x3 = predict.CenterX - w_2, x4 = predict.CenterX + w_2;
                float y3 = predict.CenterY - h_2, y4 = predict.CenterY + h_2;

                float minX = Math.Max(x1, x3);
                float maxX = Math.Min(x2, x4);
                float minY = Math.Max(y1, y3);
                float maxY = Math.Min(y2, y4);

                float w = Math.Max(0, maxX - minX);
                float h = Math.Max(0, maxY - minY);

                float jiao = w * h;
                float bing = Width * Height + predict.Width * predict.Height - jiao;
                return jiao / bing;
            }

NMS计算过程

            public static bool NMS(IList<Predict> predicts, float ioc_threshold = 0.25f)
            {
                bool flag = false;
                int index = -1;
                for (int i = 0; i < predicts.Count; i++)
                {

                    for (int j = i + 1; j < predicts.Count; j++)
                    {
                        float iou = predicts[i].IOU(predicts[j]);
                        if (iou >= ioc_threshold)
                        {
                            index = j;
                            flag = true;
                            break;
                        }
                    }
                    if (flag)
                    {
                        break;
                    }
                }
                if (flag)
                {
                    predicts.RemoveAt(index);
                }
                return flag;
            }

完整代码如下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.ML.OnnxRuntime.Tensors;
using Microsoft.ML.OnnxRuntime;
using OpenCvSharp;
using System.Runtime.InteropServices;
using System.Numerics.Tensors;
using System.Runtime.CompilerServices;
using Cv = OpenCvSharp.Cv2;
using System.Security.Cryptography.X509Certificates;
using Microsoft.VisualBasic;
using static System.Collections.Specialized.BitVector32;
using System.Data.Common;
using System.Data;
using System.Timers;
using System.Diagnostics;


namespace YoloOnnxProject
{
    // 创建检测类
    public  class OnnxRuntimeTest
    {
        private InferenceSession DetectSurface;
               
        public OnnxRuntimeTest(string OnnxPATH, string DetectSavePath)
        {

            int gpuDeviceId = 0; // The GPU device ID to execute on
            using var gpuSessionOptoins = SessionOptions.MakeSessionOptionWithCudaProvider(gpuDeviceId);
            DetectSurface = new InferenceSession(OnnxPATH, gpuSessionOptoins);
            SavePath = DetectSavePath;

        }
        public void Dispose()
        {
            DetectSurface?.Dispose();
        }

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

        };


        private int DetectBatch = 1;
        private int DetectChannl = 1;
        private int DetectWith = 512;
        private int DetectHeight = 512;

        //private string OnnxPATH;
        private string SavePath;
        private string SaveFileName;
        private string class_path;
       

        public List<Predict> UnionInference(string readimg)
        {
            List<Predict> out_res = new List<Predict>();
            //int class_max = 80;
            Mat mat_ori = Cv2.ImRead(readimg);
            int width = mat_ori.Width; 
            int height = mat_ori.Height;
            //double r = Math.Min(640.0 / width, 640.0 / height);
            //int scale_w = Convert.ToInt32(width * r) / 2 * 2;
            //int scale_h = Convert.ToInt32(height * r) / 2 * 2;
            //int dw = (int)((640 - scale_w) / 2f);
            //int dh = (int)((640 - scale_h) / 2f);
            Mat mat = new Mat();
            Cv.Resize(mat_ori, mat, new Size(512, 512));
            //Cv2.CopyMakeBorder(mat, mat, dh, dh, dw, dw, BorderTypes.Constant, new Scalar(114, 114, 114));
            DetectHeight = mat.Width;
            DetectWith = mat.Height;
            List<Predict> predicts = new List<Predict>();
            
            // 分类识别
            int[] dimensions = {DetectBatch, DetectChannl, DetectHeight, DetectWith };
            // int *dimensions :Numpy Array 数组每一维度数据的个数。
            int length = DetectChannl * DetectHeight * DetectWith;


            byte[] buffer = new byte[length];

            Marshal.Copy(mat.Data, buffer, 0, length);
            float[] fbuff = new float[length];
            int total_pixel_count = mat.Rows * mat.Cols;
            //并行运算加速赋值
            Parallel.For(0, total_pixel_count, (p_idx, state) =>
            {
                int r = p_idx;
                int g = r + total_pixel_count;
                int b = g + total_pixel_count;
                fbuff[r] = buffer[r * 3 + 2] / 255f;
                fbuff[g] = buffer[r * 3 + 1] / 255f;
                fbuff[b] = buffer[r * 3] / 255f;
            });

            Memory<float> memory = new Memory<float>(fbuff);
            DenseTensor<float> input = new DenseTensor<float>(memory, dimensions);
            string OutputMetadataName = DetectSurface!.OutputNames[0];
            string InputMetadataName = DetectSurface!.InputNames[0];
            // 将图片传至YOLO模型输入层
            var ClassInputs = new List<NamedOnnxValue>()
            {
                NamedOnnxValue.CreateFromTensor(InputMetadataName, input)
            };
            // 创建计时实例
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();

            IDisposableReadOnlyCollection<DisposableNamedOnnxValue> ClassResults = DetectSurface.Run(ClassInputs);

            stopwatch.Stop();
            // 计算时差
            TimeSpan elapsed = stopwatch.Elapsed;
            Console.WriteLine("runTime:" + elapsed.TotalMilliseconds + "ms");


            float[] res = ClassResults.First(item => item.Name == OutputMetadataName).AsEnumerable<float>().ToArray();

            var classValue = (DenseTensor<float>)ClassResults.ToArray().First().Value;
            //ClassResults.Dispose();

            if (ClassResults?.Any() == true)
            {
                //int[] dimen = [classValue.Dimensions[0], classValue.Dimensions[2], classValue.Dimensions[1]];
                int length1 = classValue.Dimensions[2]; // 8400
                int length0 = classValue.Dimensions[1]; // 84

                for (int i = 0; i < length1; i++)
                {
                    double maxVal = 0;
                    int Index0 = 0;
                    for (int j = 4; j < length0; j++)
                    {
                        if (classValue[0, j, i] > 0.25f && classValue[0, j, i] > maxVal)
                        {
                            maxVal = classValue[0, j, i];
                            Index0 = j;
                        }                    
                    }
                    if (Index0 != 0)
                    {
                        predicts.Add(new()
                        {
                            CenterX = (int)classValue[0, 0, i],
                            CenterY = (int)classValue[0, 1, i],
                            Width = (int)classValue[0, 2, i],
                            Height = (int)classValue[0, 3, i],
                            Class = Index0 - 4,
                            Confidence = classValue[0, Index0, i]
                        });
                    }

                    //float[] arr = new float[] { classValue[0, 4, i], classValue[0, 5, i], classValue[0, 6, i], classValue[0, 7, i] };
                    //var b = arr.Select((item, indx) => new { Item = item, Index = indx }).OrderByDescending(x => x.Item).Select(x => x.Index).Take(1).ToArray();

                    阈值
                    //if (classValue[0, 4, i] >= 0.5f || classValue[0, 5, i] >= 0.5f || classValue[0, 6, i] >= 0.5f || classValue[0, 7, i] >= 0.5f)
                    //{
                    //    predicts.Add(new()
                    //    {
                    //        CenterX = (int)classValue[0, 0, i],
                    //        CenterY = (int)classValue[0, 1, i],
                    //        Width = (int)classValue[0, 2, i],
                    //        Height = (int)classValue[0, 3, i],
                    //        // ---------------
                    //        Class = b[0],
                    //        Confidence = classValue[0, (4 + b[0]), i]
                    //    });

                    //}
                }
                predicts.Sort();
                while (Predict.NMS(predicts, 0.25f)) ;

                //Stack<int> stack = new Stack<int>();
                //for (int i = 0; i < predicts.Count; i++)
                //{
                //    if (predicts[i].Confidence < 0.25f)
                //    {
                //        stack.Push(i);
                //    }
                //}
                //while (stack.Any())
                //{
                //    int peek = stack.Pop();
                //    predicts.Remove(predicts[peek]);
                //}
            }
            // class处理部分
            int x_max = 0;
            int i_max = 0;
            bool have = (predicts.Count != 0);

            string data_time = System.DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss_ffff");
            if (have)
            {
                int a = 0;
                foreach (Predict emu_pre in predicts)
                {
                    //if (x_max < emu_pre.CenterX)
                    //{
                    //    x_max = emu_pre.CenterX;
                    //    i_max = a;
                    //}
                    int widthmax = (int)(width / 512f * predicts[a].Width);
                    int heightmax = (int)(height / 512f * predicts[a].Height);
                    int centerx = (int)(width / 512f * predicts[a].CenterX);
                    int centery = (int)(height / 512f * (predicts[a].CenterY));

                    // 检测目标坐标提取
                    Point point1 = new Point(centerx - (widthmax / 2), centery - (heightmax / 2));
                    Point point2 = new Point(centerx + (widthmax / 2), centery + (heightmax / 2));
                    Point point3 = new Point(centerx + (widthmax / 2), centery);
                    // 输出检测框
                    Cv.Rectangle(mat_ori, point1, point2, new Scalar(0, 0, 255), 2);
                    // 打印标签
                    string outtext = lableName[predicts[a].Class];
                    Cv.PutText(mat_ori, outtext, point3, HersheyFonts.HersheySimplex, 1, new Scalar(0, 255, 255));
                    //class_path = SavePath + "class\\" + predicts[a].Class.ToString() + "\\";
                    a++;
                }
                //int widthmax = (int)(width / 640f * predicts[i_max].Width);
                //int heightmax = (int)(width / 640f * predicts[i_max].Height);
                //int centerx = (int)(width / 640f * predicts[i_max].CenterX);
                //int centery = (int)(width / 640f * (predicts[i_max].CenterY - dh)); 
                 检测目标坐标提取
                //Point point1 = new Point(centerx - (widthmax / 2), centery - (heightmax / 2));
                //Point point2 = new Point(centerx + (widthmax / 2), centery + (widthmax / 2));
                 输出检测框
                //Cv.Rectangle(mat_ori, point1, point2, new Scalar(0, 0, 255), 2);
                 打印标签
                //string outtext = lableName[predicts[i_max].Class];
                //Cv.PutText(mat_ori, outtext, point1, HersheyFonts.HersheySimplex, 1, new Scalar(0, 0, 255));

                // 裁剪检测目标
                //Mat cropped = mat_ori[centery - heightmax / 2, centery + heightmax / 2, centerx - widthmax / 2, centerx + widthmax / 2];

                //UTC时间

                //转北京时间,毫秒精确后两位

                // 保存检测目标
                class_path = SavePath + "class\\" + predicts[i_max].Class.ToString() + "\\";
                if (!Directory.Exists(class_path))
                {
                    //创建文件夹
                    try
                    {
                        Directory.CreateDirectory(class_path);
                    }
                    catch (Exception e)
                    {

                    }
                }
                SaveFileName = class_path + data_time + ".jpg";
                //Cv2.ImWrite(SaveFileName, mat_ori);
                //class_max = predicts[i_max].Class;
            }
            else
            {
                class_path = SavePath + "NoneObject\\" + "\\";
                if (!Directory.Exists(class_path))
                {
                    //创建文件夹
                    try
                    {
                        Directory.CreateDirectory(class_path);
                    }
                    catch (Exception e)
                    {

                    }
                }
                SaveFileName = class_path + data_time + ".jpg";                
                //Cv2.ImWrite(SaveFileName, mat_ori);
                //Predict re_lable = outputLable(SaveFileName);
            }

            return out_res;
        }

        public class Predict : IComparable<Predict>
        {
            public int CenterX {  get; set; }
            public int CenterY { get; set; }

            public int Width {  get; set; }
            public int Height { get; set; }

            public float Confidence { get; set; }
            public int Class {  get; set; }

            public int CompareTo(Predict? other)
            {
                if (other?.Confidence - Confidence <= 0)
                {
                    return -1;
                }
                else
                {
                    return 1;
                }
            }
            public float IOU(Predict predict)
            {
                float w_2 = Width / 2;
                float h_2 = Height / 2;
                float x1 = CenterX - w_2, x2 = CenterX + w_2;
                float y1 = CenterY - h_2, y2 = CenterY + h_2;

                w_2 = predict.Width / 2;
                h_2 = predict.Height / 2;
                float x3 = predict.CenterX - w_2, x4 = predict.CenterX + w_2;
                float y3 = predict.CenterY - h_2, y4 = predict.CenterY + h_2;

                float minX = Math.Max(x1, x3);
                float maxX = Math.Min(x2, x4);
                float minY = Math.Max(y1, y3);
                float maxY = Math.Min(y2, y4);

                float w = Math.Max(0, maxX - minX);
                float h = Math.Max(0, maxY - minY);

                float jiao = w * h;
                float bing = Width * Height + predict.Width * predict.Height - jiao;
                return jiao / bing;
            }

            public static bool NMS(IList<Predict> predicts, float ioc_threshold = 0.25f)
            {
                bool flag = false;
                int index = -1;
                for (int i = 0; i < predicts.Count; i++)
                {

                    for (int j = i + 1; j < predicts.Count; j++)
                    {
                        float iou = predicts[i].IOU(predicts[j]);
                        if (iou >= ioc_threshold)
                        {
                            index = j;
                            flag = true;
                            break;
                        }
                    }
                    if (flag)
                    {
                        break;
                    }
                }
                if (flag)
                {
                    predicts.RemoveAt(index);
                }
                return flag;
            }
            

        }

    }
}

main.cs

using OpenCvSharp;
using System;
using System.Diagnostics;
using System.Drawing;
using static YoloOnnxProject.OnnxRuntimeTest;
using Cv = OpenCvSharp.Cv2;


namespace YoloOnnxProject
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // Onnx文件地址
            string OnnxPATH = @"E:\DeskTop\Surface_detect\best.onnx";
            // 检测输出文件地址
            string imgSavePath = @"E:\DeskTop\Surface_detect\runs\detect1\";
            // 调用算法
            OnnxRuntimeTest OnnxYoloV8 = new OnnxRuntimeTest(OnnxPATH, imgSavePath);
            // 检测目标地址
            string imgPath = @"E:\DeskTop\Surface_detect\Annotation\val\images\";
            int imgnum = 0;
            // 遍历图片
            foreach (string img in Directory.GetFiles(imgPath))
            {
                // 创建记时实例
                Stopwatch stopwatch = new Stopwatch();

                
                string readimg = img;
                // 开始记时
                stopwatch.Start();

                List<Predict> predicts = OnnxYoloV8.UnionInference(readimg);
                
                // 结束记时
                stopwatch.Stop();
                // 输出时间
                TimeSpan timeSpan = stopwatch.Elapsed;

                //Console.WriteLine("**********************");
                //Console.WriteLine("第 " + imgnum + " 张图像" + "程序执行时间:" + timeSpan.TotalMilliseconds + "ms");
                imgnum++;
            }
            Cv.DestroyAllWindows();
        }

    }
}

  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值