当前位置: 首页 > news >正文

C# YoloV8 模型效果验证工具(OnnxRuntime+ByteTrack推理)

C# YoloV8 模型效果验证工具(OnnxRuntime+ByteTrack推理)

目录

效果

项目

代码

下载


效果

模型效果验证工具

项目

代码

using ByteTrack;
using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;


namespace C__yolov8_OnnxRuntime_ByteTrack_Demo
{
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }

        string imgFilter = "图片|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";

        YoloV8 yoloV8;
        Mat image;

        string image_path = "";
        string model_path;

        string video_path = "";
        string videoFilter = "视频|*.mp4;*.avi;*.dav";
        VideoCapture vcapture;
        VideoWriter vwriter;
        bool saveDetVideo = false;
        ByteTracker tracker;

        /// <summary>
        /// 单图推理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {

            if (image_path == "")
            {
                return;
            }

            button2.Enabled = false;
            pictureBox2.Image = null;
            textBox1.Text = "";

            Application.DoEvents();

            image = new Mat(image_path);

            List<DetectionResult> detResults = yoloV8.Detect(image);

            //绘制结果
            Mat result_image = image.Clone();
            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);

            }

            if (pictureBox2.Image != null)
            {
                pictureBox2.Image.Dispose();
            }
            pictureBox2.Image = new Bitmap(result_image.ToMemoryStream());
            textBox1.Text = yoloV8.DetectTime();

            button2.Enabled = true;

        }

        /// <summary>
        /// 窗体加载,初始化
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Load(object sender, EventArgs e)
        {
            image_path = "test/dog.jpg";
            pictureBox1.Image = new Bitmap(image_path);

            model_path = "model/yolov8n.onnx";

            yoloV8 = new YoloV8(model_path, "model/lable.txt");
        }

        /// <summary>
        /// 选择图片
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click_1(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = imgFilter;
            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 name="sender"></param>
        /// <param name="e"></param>
        private void button4_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = videoFilter;
            ofd.InitialDirectory = Application.StartupPath + "\\test";
            if (ofd.ShowDialog() != DialogResult.OK) return;

            video_path = ofd.FileName;

            textBox1.Text = video_path;
            //pictureBox1.Image = null;
            //pictureBox2.Image = null;

            //button3_Click(null, null);

        }

        /// <summary>
        /// 视频推理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button3_Click(object sender, EventArgs e)
        {
            if (video_path == "")
            {
                MessageBox.Show("请先选择视频!");
                return;
            }

            textBox1.Text = "开始检测";

            Application.DoEvents();

            Thread thread = new Thread(new ThreadStart(VideoDetection));

            thread.Start();
            thread.Join();

            textBox1.Text = "检测完成!";
        }

        void VideoDetection()
        {
            vcapture = new VideoCapture(video_path);
            if (!vcapture.IsOpened())
            {
                MessageBox.Show("打开视频文件失败");
                return;
            }

            tracker = new ByteTracker((int)vcapture.Fps, 200);

            Mat frame = new Mat();
            List<DetectionResult> detResults;

            // 获取视频的fps
            double videoFps = vcapture.Get(VideoCaptureProperties.Fps);
            // 计算等待时间(毫秒)
            int delay = (int)(1000 / videoFps);
            Stopwatch _stopwatch = new Stopwatch();

            if (checkBox1.Checked)
            {
                vwriter = new VideoWriter("out.mp4", FourCC.X264, vcapture.Fps, new OpenCvSharp.Size(vcapture.FrameWidth, vcapture.FrameHeight));
                saveDetVideo = true;
            }
            else
            {
                saveDetVideo = false;
            }

            Cv2.NamedWindow("DetectionResult 按下ESC,退出", WindowFlags.Normal);
            Cv2.ResizeWindow("DetectionResult 按下ESC,退出", vcapture.FrameWidth / 2, vcapture.FrameHeight / 2);

            while (vcapture.Read(frame))
            {
                if (frame.Empty())
                {
                    MessageBox.Show("读取失败");
                    return;
                }
                Mat mat_temp = frame.Clone();
                _stopwatch.Restart();

                delay = (int)(1000 / videoFps);

                detResults = yoloV8.Detect(frame);

                //绘制结果
                //foreach (DetectionResult r in detResults)
                //{
                //    Cv2.PutText(frame, $"{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(frame, r.Rect, Scalar.Red, thickness: 2);
                //}

                Cv2.PutText(frame, "preprocessTime:" + yoloV8.preprocessTime.ToString("F2") + "ms", new OpenCvSharp.Point(10, 30), HersheyFonts.HersheySimplex, 1, Scalar.Red, 2);
                Cv2.PutText(frame, "inferTime:" + yoloV8.inferTime.ToString("F2") + "ms", new OpenCvSharp.Point(10, 70), HersheyFonts.HersheySimplex, 1, Scalar.Red, 2);
                Cv2.PutText(frame, "postprocessTime:" + yoloV8.postprocessTime.ToString("F2") + "ms", new OpenCvSharp.Point(10, 110), HersheyFonts.HersheySimplex, 1, Scalar.Red, 2);
                Cv2.PutText(frame, "totalTime:" + yoloV8.totalTime.ToString("F2") + "ms", new OpenCvSharp.Point(10, 150), HersheyFonts.HersheySimplex, 1, Scalar.Red, 2);
                Cv2.PutText(frame, "video fps:" + videoFps.ToString("F2"), new OpenCvSharp.Point(10, 190), HersheyFonts.HersheySimplex, 1, Scalar.Red, 2);
                Cv2.PutText(frame, "det fps:" + yoloV8.detFps.ToString("F2"), new OpenCvSharp.Point(10, 230), HersheyFonts.HersheySimplex, 1, Scalar.Red, 2);

                List<Track> track = new List<Track>();
                Track temp;
                foreach (DetectionResult r in detResults)
                {
                    RectBox _box = new RectBox(r.Rect.X, r.Rect.Y, r.Rect.Width, r.Rect.Height);
                    temp = new Track(_box, r.Confidence, ("label", r.ClassId), ("name", r.Class));
                    track.Add(temp);
                }

                var trackOutputs = tracker.Update(track);

                foreach (var t in trackOutputs)
                {
                    int x = (int)t.RectBox.X;
                    int y = (int)t.RectBox.Y;
                    int width = (int)t.RectBox.Width;
                    int height = (int)t.RectBox.Height;

                    if (x < 0)
                    {
                        x = 0;
                    }

                    if (y < 0)
                    {
                        y = 0;
                    }

                    if (x + width > mat_temp.Width)
                    {
                        width = mat_temp.Width - x;
                    }

                    if (y + height > mat_temp.Height)
                    {
                        height = mat_temp.Height - y;
                    }

                    Rect rect = new Rect(x, y, width, height);

                    string txt = $"{t["name"]}-{t.TrackId}:{t.Score:P0}";
                    
                    //if (t["name"].ToString() != "Plate" && t["name"].ToString() != "Person")
                    //{
                    //    Mat mat_car = new Mat(mat_temp, rect);
                    //    KeyValuePair<string, float> cls = yoloV8_Cls.Detect(mat_car);
                    //    mat_car.Dispose();
                    //    txt += $" {cls.Key}:{cls.Value:P0}";
                    //}

                    //string txt = $"{t["name"]}-{t.TrackId}";
                    Cv2.PutText(frame, txt, new OpenCvSharp.Point(rect.TopLeft.X, rect.TopLeft.Y - 10), HersheyFonts.HersheySimplex, 1, Scalar.Red, 2);
                    Cv2.Rectangle(frame, rect, Scalar.Red, thickness: 2);
                }
                mat_temp.Dispose();


                if (saveDetVideo)
                {
                    vwriter.Write(frame);
                }

                Cv2.ImShow("DetectionResult 按下ESC,退出", frame);

                // for test
                // delay = 1;
                delay = (int)(delay - _stopwatch.ElapsedMilliseconds);
                if (delay <= 0)
                {
                    delay = 1;
                }
                //Console.WriteLine("delay:" + delay.ToString()) ;
                if (Cv2.WaitKey(delay) == 27 || Cv2.GetWindowProperty("DetectionResult 按下ESC,退出", WindowPropertyFlags.Visible) < 1.0)
                {
                    Cv2.DestroyAllWindows();
                    vcapture.Release();
                    break;
                }
            }

            Cv2.DestroyAllWindows();
            vcapture.Release();
            if (saveDetVideo)
            {
                vwriter.Release();
            }

        }

        string model_path1 = "";
        string model_path2 = "";
        string onnxFilter = "onnx模型|*.onnx;";

        private void button5_Click(object sender, EventArgs e)
        {
            if (video_path == "")
            {
                MessageBox.Show("请先选择视频!");
                return;
            }

            if (model_path1 == "")
            {
                MessageBox.Show("选择模型1");
                OpenFileDialog ofd = new OpenFileDialog();
                ofd.Filter = onnxFilter;
                ofd.InitialDirectory = Application.StartupPath + "\\model";
                if (ofd.ShowDialog() != DialogResult.OK) return;
                model_path1 = ofd.FileName;
            }

            if (model_path2 == "")
            {
                MessageBox.Show("选择模型2");
                OpenFileDialog ofd1 = new OpenFileDialog();
                ofd1.Filter = onnxFilter;
                ofd1.InitialDirectory = Application.StartupPath + "\\model";
                if (ofd1.ShowDialog() != DialogResult.OK) return;
                model_path2 = ofd1.FileName;
            }

            textBox1.Text = "开始检测";
            Application.DoEvents();

            Task task = new Task(() =>
            {
                VideoCapture vcapture = new VideoCapture(video_path);
                if (!vcapture.IsOpened())
                {
                    MessageBox.Show("打开视频文件失败");
                    return;
                }

                YoloV8_Compare yoloV8 = new YoloV8_Compare(model_path1, model_path2, "model/lable.txt");

                Mat frame = new Mat();

                // 获取视频的fps
                double videoFps = vcapture.Get(VideoCaptureProperties.Fps);
                // 计算等待时间(毫秒)
                int delay = (int)(1000 / videoFps);
                Stopwatch _stopwatch = new Stopwatch();

                Cv2.NamedWindow("DetectionResult 按下ESC,退出", WindowFlags.Normal);
                Cv2.ResizeWindow("DetectionResult 按下ESC,退出", vcapture.FrameWidth, vcapture.FrameHeight / 2);

                while (vcapture.Read(frame))
                {
                    if (frame.Empty())
                    {
                        MessageBox.Show("读取失败");
                        return;
                    }

                    _stopwatch.Restart();

                    delay = (int)(1000 / videoFps);

                    Mat result = yoloV8.Detect(frame, videoFps.ToString("F2"));

                    Cv2.ImShow("DetectionResult 按下ESC,退出", result);

                    // for test
                    // delay = 1;
                    delay = (int)(delay - _stopwatch.ElapsedMilliseconds);
                    if (delay <= 0)
                    {
                        delay = 1;
                    }
                    //Console.WriteLine("delay:" + delay.ToString()) ;
                    // 如果按下ESC或点击关闭,退出循环
                    if (Cv2.WaitKey(delay) == 27 || Cv2.GetWindowProperty("DetectionResult 按下ESC,退出", WindowPropertyFlags.Visible) < 1.0)
                    {
                        Cv2.DestroyAllWindows();
                        vcapture.Release();
                        break;
                    }
                }

                textBox1.Invoke(new Action(() =>
                {
                    textBox1.Text = "检测结束!";

                }));

            });
            task.Start();

        }

        //保存
        SaveFileDialog sdf = new SaveFileDialog();
        private void button6_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";
            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);
            }

        }

        /// <summary>
        /// 选择模型
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button7_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = onnxFilter;
            ofd.InitialDirectory = Application.StartupPath + "\\model";
            if (ofd.ShowDialog() != DialogResult.OK) return;
            model_path = ofd.FileName;
            yoloV8 = new YoloV8(model_path, "model/lable.txt");

        }
    }

}

using ByteTrack;
using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;namespace C__yolov8_OnnxRuntime_ByteTrack_Demo
{public partial class Form2 : Form{public Form2(){InitializeComponent();}string imgFilter = "图片|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";YoloV8 yoloV8;Mat image;string image_path = "";string model_path;string video_path = "";string videoFilter = "视频|*.mp4;*.avi;*.dav";VideoCapture vcapture;VideoWriter vwriter;bool saveDetVideo = false;ByteTracker tracker;/// <summary>/// 单图推理/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void button2_Click(object sender, EventArgs e){if (image_path == ""){return;}button2.Enabled = false;pictureBox2.Image = null;textBox1.Text = "";Application.DoEvents();image = new Mat(image_path);List<DetectionResult> detResults = yoloV8.Detect(image);//绘制结果Mat result_image = image.Clone();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);}if (pictureBox2.Image != null){pictureBox2.Image.Dispose();}pictureBox2.Image = new Bitmap(result_image.ToMemoryStream());textBox1.Text = yoloV8.DetectTime();button2.Enabled = true;}/// <summary>/// 窗体加载,初始化/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void Form1_Load(object sender, EventArgs e){image_path = "test/dog.jpg";pictureBox1.Image = new Bitmap(image_path);model_path = "model/yolov8n.onnx";yoloV8 = new YoloV8(model_path, "model/lable.txt");}/// <summary>/// 选择图片/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void button1_Click_1(object sender, EventArgs e){OpenFileDialog ofd = new OpenFileDialog();ofd.Filter = imgFilter;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 name="sender"></param>/// <param name="e"></param>private void button4_Click(object sender, EventArgs e){OpenFileDialog ofd = new OpenFileDialog();ofd.Filter = videoFilter;ofd.InitialDirectory = Application.StartupPath + "\\test";if (ofd.ShowDialog() != DialogResult.OK) return;video_path = ofd.FileName;textBox1.Text = video_path;//pictureBox1.Image = null;//pictureBox2.Image = null;//button3_Click(null, null);}/// <summary>/// 视频推理/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void button3_Click(object sender, EventArgs e){if (video_path == ""){MessageBox.Show("请先选择视频!");return;}textBox1.Text = "开始检测";Application.DoEvents();Thread thread = new Thread(new ThreadStart(VideoDetection));thread.Start();thread.Join();textBox1.Text = "检测完成!";}void VideoDetection(){vcapture = new VideoCapture(video_path);if (!vcapture.IsOpened()){MessageBox.Show("打开视频文件失败");return;}tracker = new ByteTracker((int)vcapture.Fps, 200);Mat frame = new Mat();List<DetectionResult> detResults;// 获取视频的fpsdouble videoFps = vcapture.Get(VideoCaptureProperties.Fps);// 计算等待时间(毫秒)int delay = (int)(1000 / videoFps);Stopwatch _stopwatch = new Stopwatch();if (checkBox1.Checked){vwriter = new VideoWriter("out.mp4", FourCC.X264, vcapture.Fps, new OpenCvSharp.Size(vcapture.FrameWidth, vcapture.FrameHeight));saveDetVideo = true;}else{saveDetVideo = false;}Cv2.NamedWindow("DetectionResult 按下ESC,退出", WindowFlags.Normal);Cv2.ResizeWindow("DetectionResult 按下ESC,退出", vcapture.FrameWidth / 2, vcapture.FrameHeight / 2);while (vcapture.Read(frame)){if (frame.Empty()){MessageBox.Show("读取失败");return;}Mat mat_temp = frame.Clone();_stopwatch.Restart();delay = (int)(1000 / videoFps);detResults = yoloV8.Detect(frame);//绘制结果//foreach (DetectionResult r in detResults)//{//    Cv2.PutText(frame, $"{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(frame, r.Rect, Scalar.Red, thickness: 2);//}Cv2.PutText(frame, "preprocessTime:" + yoloV8.preprocessTime.ToString("F2") + "ms", new OpenCvSharp.Point(10, 30), HersheyFonts.HersheySimplex, 1, Scalar.Red, 2);Cv2.PutText(frame, "inferTime:" + yoloV8.inferTime.ToString("F2") + "ms", new OpenCvSharp.Point(10, 70), HersheyFonts.HersheySimplex, 1, Scalar.Red, 2);Cv2.PutText(frame, "postprocessTime:" + yoloV8.postprocessTime.ToString("F2") + "ms", new OpenCvSharp.Point(10, 110), HersheyFonts.HersheySimplex, 1, Scalar.Red, 2);Cv2.PutText(frame, "totalTime:" + yoloV8.totalTime.ToString("F2") + "ms", new OpenCvSharp.Point(10, 150), HersheyFonts.HersheySimplex, 1, Scalar.Red, 2);Cv2.PutText(frame, "video fps:" + videoFps.ToString("F2"), new OpenCvSharp.Point(10, 190), HersheyFonts.HersheySimplex, 1, Scalar.Red, 2);Cv2.PutText(frame, "det fps:" + yoloV8.detFps.ToString("F2"), new OpenCvSharp.Point(10, 230), HersheyFonts.HersheySimplex, 1, Scalar.Red, 2);List<Track> track = new List<Track>();Track temp;foreach (DetectionResult r in detResults){RectBox _box = new RectBox(r.Rect.X, r.Rect.Y, r.Rect.Width, r.Rect.Height);temp = new Track(_box, r.Confidence, ("label", r.ClassId), ("name", r.Class));track.Add(temp);}var trackOutputs = tracker.Update(track);foreach (var t in trackOutputs){int x = (int)t.RectBox.X;int y = (int)t.RectBox.Y;int width = (int)t.RectBox.Width;int height = (int)t.RectBox.Height;if (x < 0){x = 0;}if (y < 0){y = 0;}if (x + width > mat_temp.Width){width = mat_temp.Width - x;}if (y + height > mat_temp.Height){height = mat_temp.Height - y;}Rect rect = new Rect(x, y, width, height);string txt = $"{t["name"]}-{t.TrackId}:{t.Score:P0}";//if (t["name"].ToString() != "Plate" && t["name"].ToString() != "Person")//{//    Mat mat_car = new Mat(mat_temp, rect);//    KeyValuePair<string, float> cls = yoloV8_Cls.Detect(mat_car);//    mat_car.Dispose();//    txt += $" {cls.Key}:{cls.Value:P0}";//}//string txt = $"{t["name"]}-{t.TrackId}";Cv2.PutText(frame, txt, new OpenCvSharp.Point(rect.TopLeft.X, rect.TopLeft.Y - 10), HersheyFonts.HersheySimplex, 1, Scalar.Red, 2);Cv2.Rectangle(frame, rect, Scalar.Red, thickness: 2);}mat_temp.Dispose();if (saveDetVideo){vwriter.Write(frame);}Cv2.ImShow("DetectionResult 按下ESC,退出", frame);// for test// delay = 1;delay = (int)(delay - _stopwatch.ElapsedMilliseconds);if (delay <= 0){delay = 1;}//Console.WriteLine("delay:" + delay.ToString()) ;if (Cv2.WaitKey(delay) == 27 || Cv2.GetWindowProperty("DetectionResult 按下ESC,退出", WindowPropertyFlags.Visible) < 1.0){Cv2.DestroyAllWindows();vcapture.Release();break;}}Cv2.DestroyAllWindows();vcapture.Release();if (saveDetVideo){vwriter.Release();}}string model_path1 = "";string model_path2 = "";string onnxFilter = "onnx模型|*.onnx;";private void button5_Click(object sender, EventArgs e){if (video_path == ""){MessageBox.Show("请先选择视频!");return;}if (model_path1 == ""){MessageBox.Show("选择模型1");OpenFileDialog ofd = new OpenFileDialog();ofd.Filter = onnxFilter;ofd.InitialDirectory = Application.StartupPath + "\\model";if (ofd.ShowDialog() != DialogResult.OK) return;model_path1 = ofd.FileName;}if (model_path2 == ""){MessageBox.Show("选择模型2");OpenFileDialog ofd1 = new OpenFileDialog();ofd1.Filter = onnxFilter;ofd1.InitialDirectory = Application.StartupPath + "\\model";if (ofd1.ShowDialog() != DialogResult.OK) return;model_path2 = ofd1.FileName;}textBox1.Text = "开始检测";Application.DoEvents();Task task = new Task(() =>{VideoCapture vcapture = new VideoCapture(video_path);if (!vcapture.IsOpened()){MessageBox.Show("打开视频文件失败");return;}YoloV8_Compare yoloV8 = new YoloV8_Compare(model_path1, model_path2, "model/lable.txt");Mat frame = new Mat();// 获取视频的fpsdouble videoFps = vcapture.Get(VideoCaptureProperties.Fps);// 计算等待时间(毫秒)int delay = (int)(1000 / videoFps);Stopwatch _stopwatch = new Stopwatch();Cv2.NamedWindow("DetectionResult 按下ESC,退出", WindowFlags.Normal);Cv2.ResizeWindow("DetectionResult 按下ESC,退出", vcapture.FrameWidth, vcapture.FrameHeight / 2);while (vcapture.Read(frame)){if (frame.Empty()){MessageBox.Show("读取失败");return;}_stopwatch.Restart();delay = (int)(1000 / videoFps);Mat result = yoloV8.Detect(frame, videoFps.ToString("F2"));Cv2.ImShow("DetectionResult 按下ESC,退出", result);// for test// delay = 1;delay = (int)(delay - _stopwatch.ElapsedMilliseconds);if (delay <= 0){delay = 1;}//Console.WriteLine("delay:" + delay.ToString()) ;// 如果按下ESC或点击关闭,退出循环if (Cv2.WaitKey(delay) == 27 || Cv2.GetWindowProperty("DetectionResult 按下ESC,退出", WindowPropertyFlags.Visible) < 1.0){Cv2.DestroyAllWindows();vcapture.Release();break;}}textBox1.Invoke(new Action(() =>{textBox1.Text = "检测结束!";}));});task.Start();}//保存SaveFileDialog sdf = new SaveFileDialog();private void button6_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";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);}}/// <summary>/// 选择模型/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void button7_Click(object sender, EventArgs e){OpenFileDialog ofd = new OpenFileDialog();ofd.Filter = onnxFilter;ofd.InitialDirectory = Application.StartupPath + "\\model";if (ofd.ShowDialog() != DialogResult.OK) return;model_path = ofd.FileName;yoloV8 = new YoloV8(model_path, "model/lable.txt");}}}

下载

源码下载

相关文章:

C# YoloV8 模型效果验证工具(OnnxRuntime+ByteTrack推理)

C# YoloV8 模型效果验证工具(OnnxRuntimeByteTrack推理) 目录 效果 项目 代码 下载 效果 模型效果验证工具 项目 代码 using ByteTrack; using OpenCvSharp; using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using Sys…...

什么是Cookie?有什么用?如何清除浏览器中的Cookie?

互联网上的每一次点击和每一个选择都可能被一种名为Cookie的技术记录下来。但Cookie是什么&#xff1f;我们在网站上登录时&#xff0c;为什么经常会被问及是否接受Cookie&#xff1f;接受Cookie登录会不会影响我们的在线隐私&#xff1f; Cookie是什么&#xff1f; Cookie是一…...

数据库基本管理

数据完整性&#xff1a; 实体完整性&#xff1a;每一行必须是唯一的实体域完整性&#xff1a;检查每一列是否有效引用完整性&#xff1a;确保所有表中数据的一致性&#xff0c;不允许引用不存在的值用户定义的完整性&#xff1a;制定特定的业务规则 主键&#xff1a; 用于唯…...

43.三倍游戏

上海市计算机学会竞赛平台 | YACSYACS 是由上海市计算机学会于2019年发起的活动,旨在激发青少年对学习人工智能与算法设计的热情与兴趣,提升青少年科学素养,引导青少年投身创新发现和科研实践活动。https://www.iai.sh.cn/problem/390 题目描述 三倍游戏是一种单人游戏。玩…...

LoadBalance 负载均衡

什么是负载均衡 负载均衡(Load Balance&#xff0c;简称 LB),是⾼并发,⾼可⽤系统必不可少的关键组件. 当服务流量增⼤时,通常会采⽤增加机器的⽅式进⾏扩容,负载均衡就是⽤来在多个机器或者其他资源中,按照⼀定的规则合理分配负载. 负载均衡的⼀些实现 服务多机部署时,开发⼈…...

Wails 安装初体验

文章目录 Wails 安装说明1. 系统要求2. 安装步骤3. 构建应用 结论 Wails 安装说明 Wails 是一个用于构建桌面应用的 Go 框架&#xff0c;结合了现代前端技术。以下是安装步骤&#xff1a; 1. 系统要求 Go 1.16 或更高版本Node.js 和 npm可选&#xff1a;适用于 Windows、mac…...

架构师篇-10、DDD实战篇:通过领域模型落地系统

基于领域模型的设计与开发 数据库设计程序设计微服务设计 在线订餐系统的领域事件通知 微服务拆分 事件风暴会议 梳理领域事件进行领域建模识别聚合关系划分限界上下文 用户下单领域模型 更新后的模型 领域模型的设计实现过程 数据库设计 数据库映射&#xff1a;一对一关系…...

C++ | Leetcode C++题解之第190题颠倒二进制位

题目&#xff1a; 题解&#xff1a; class Solution { private:const uint32_t M1 0x55555555; // 01010101010101010101010101010101const uint32_t M2 0x33333333; // 00110011001100110011001100110011const uint32_t M4 0x0f0f0f0f; // 000011110000111100001111000011…...

Git安装与使用及整合IDEA使用的详细教程

1. 版本控制软件介绍 版本控制软件提供完备的版本管理功能&#xff0c;用于存储、追踪目录&#xff08;文件夹&#xff09;和文件的修改历史&#xff0c;是软件开发者的必备工具&#xff0c;是软件公司的基础设施。版本控制软件的最高目标&#xff0c;是支持软件公司的配置管理…...

高效办公秘诀:使用Excel超级处理器提高工作效率,提升职场竞争力

在现今快节奏的工作环境中&#xff0c;如何高效地完成工作任务&#xff0c;减少加班时间&#xff0c;成为了许多职场人士关注的焦点。其中&#xff0c;Excel作为一款功能强大的电子表格软件&#xff0c;被广泛应用于数据处理、分析以及报表制作等领域。然而&#xff0c;仅仅依赖…...

深入探讨Python中的元编程:装饰器与元类

Python以其简洁明了的语法和强大的标准库&#xff0c;成为许多开发者的首选语言。而在高级开发中&#xff0c;元编程&#xff08;Metaprogramming&#xff09;是一个非常强大的工具&#xff0c;可以极大地提升代码的灵活性和可复用性。本文将深入探讨Python中的元编程&#xff…...

MaxKb/open-webui+Ollama运行模型

准备&#xff1a;虚拟机&#xff1a;centos7 安装Docker&#xff1a;首先&#xff0c;需要安装Docker&#xff0c;因为Ollama和MaxKB都是基于Docker的容器。使用以下命令安装Docker&#xff1a; sudo yum install -y yum-utils device-mapper-persistent-data lvm2 sudo yum…...

2-requests模块(6节课学会爬虫)

2-requests模块&#xff08;6节课学会爬虫&#xff09; 1&#xff0c;安装requests2&#xff0c;发送get&#xff0c;post请求&#xff0c;获取响应3&#xff0c;response的方法方法一&#xff08;Response.text&#xff09;方法二&#xff08;response.content.decode()&#…...

使用ECharts创建动态数据可视化图表

使用ECharts创建动态数据可视化图表 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 在现代Web应用开发中&#xff0c;数据可视化是至关重要的一环。ECharts作…...

Nacos配置中心客户端源码分析(一): 客户端如何初始化配置

本文收录于专栏 Nacos 推荐阅读&#xff1a;Nacos 架构 & 原理 文章目录 前言一、NacosConfigBeanDefinitionRegistrar二、NacosPropertySourcePostProcessor三、AbstractNacosPropertySourceBuilder总结「AI生成」 前言 专栏前几篇文章主要讲了Nacos作为服务注册中心相关…...

gin数据解析,绑定和渲染

一. 数据解析和绑定 1.1 Json数据解析和绑定 html文件&#xff1a; <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0&quo…...

Django 对模型创建的两表插入数据

1&#xff0c;添加模型 Test/app8/models.py from django.db import modelsclass User(models.Model):username models.CharField(max_length50, uniqueTrue)email models.EmailField(uniqueTrue)password models.CharField(max_length128) # 使用哈希存储密码first_name …...

Lua: 轻量级多用途脚本语言

Lua 是一种高效而轻量级的脚本语言&#xff0c;具备强大的扩展性和灵活性&#xff0c;广泛应用于游戏开发、嵌入式系统、Web 应用等多个领域。本文将深入探讨 Lua 的特性、应用场景以及如何使用 Lua 进行开发。 1. Lua 的起源与发展 Lua 的发展始于上世纪90年代初&#xff0c;…...

PotPlayer安装及高分辨率设置

第1步&#xff1a; 下载安装PotPlayer软件 PotPlayer链接&#xff1a;https://pan.baidu.com/s/1hW168dJrLBonUnpLI6F3qQ 提取码&#xff1a;z8xd 第2步&#xff1a; 下载插件&#xff0c;选择系统对应的位数进行运行&#xff0c;该文件不能删除&#xff0c;删除后将失效。 …...

实现写入缓存策略的最佳方法探讨

实现写入缓存策略的最佳方法探讨 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天我们将探讨在软件开发中实现写入缓存策略的最佳方法。缓存在提升应用性能和…...

家政维修平台实战20:权限设计

目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系&#xff0c;主要是分成几个表&#xff0c;用户表我们是记录用户的基础信息&#xff0c;包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题&#xff0c;不同的角色&#xf…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享

文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的&#xff0c;根据Excel列的需求预估的工时直接打骨折&#xff0c;不要问我为什么&#xff0c;主要…...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案&#xff0c;允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

Rapidio门铃消息FIFO溢出机制

关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系&#xff0c;以下是深入解析&#xff1a; 门铃FIFO溢出的本质 在RapidIO系统中&#xff0c;门铃消息FIFO是硬件控制器内部的缓冲区&#xff0c;用于临时存储接收到的门铃消息&#xff08;Doorbell Message&#xff09;。…...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI&#xff0c;使用客户端或是内部自己搭建集成大模型的终端&#xff0c;加速与大型语言模型&#xff08;LLM&#xff09;的结合&#xff0c;同时使用检索增强生成&#xff08;Retrieval Augmented Generation &#…...

比较数据迁移后MySQL数据库和OceanBase数据仓库中的表

设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...

上位机开发过程中的设计模式体会(1):工厂方法模式、单例模式和生成器模式

简介 在我的 QT/C 开发工作中&#xff0c;合理运用设计模式极大地提高了代码的可维护性和可扩展性。本文将分享我在实际项目中应用的三种创造型模式&#xff1a;工厂方法模式、单例模式和生成器模式。 1. 工厂模式 (Factory Pattern) 应用场景 在我的 QT 项目中曾经有一个需…...

macOS 终端智能代理检测

&#x1f9e0; 终端智能代理检测&#xff1a;自动判断是否需要设置代理访问 GitHub 在开发中&#xff0c;使用 GitHub 是非常常见的需求。但有时候我们会发现某些命令失败、插件无法更新&#xff0c;例如&#xff1a; fatal: unable to access https://github.com/ohmyzsh/oh…...

react菜单,动态绑定点击事件,菜单分离出去单独的js文件,Ant框架

1、菜单文件treeTop.js // 顶部菜单 import { AppstoreOutlined, SettingOutlined } from ant-design/icons; // 定义菜单项数据 const treeTop [{label: Docker管理,key: 1,icon: <AppstoreOutlined />,url:"/docker/index"},{label: 权限管理,key: 2,icon:…...

五、jmeter脚本参数化

目录 1、脚本参数化 1.1 用户定义的变量 1.1.1 添加及引用方式 1.1.2 测试得出用户定义变量的特点 1.2 用户参数 1.2.1 概念 1.2.2 位置不同效果不同 1.2.3、用户参数的勾选框 - 每次迭代更新一次 总结用户定义的变量、用户参数 1.3 csv数据文件参数化 1、脚本参数化 …...