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");}}}

下載

源碼下載

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/36481.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/36481.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/36481.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

遠程服務器配置(堡壘機samba/ssh等)

分配了新的服務器后&#xff0c;要下載代碼首先要配置ssh。有以下兩種方式&#xff1a; 拷貝原本服務器的在本地的重新生成ssh&#xff0c;再跟服務器密鑰配對&#xff08;如未備份.gitconfig&#xff0c;還需重新配置git賬號郵箱。&#xff09; ssh配置 如果是拷貝過來的.ss…

【win11】Mouse without Borders安裝問題以管理員權限安裝msi文件

【win11】Mouse without Borders安裝問題&以管理員權限安裝msi文件 Mouse without Borders安裝問題解決&以管理員權限安裝msi文件啟動Windows Installer服務以管理員權限安裝msi文件 參考文獻 Mouse without Borders安裝問題 在win11下我雙擊MouseWithoutBorders2.2.1…

nodejs使用mysql模塊自動斷開

背景 第二天早上來的時候&#xff0c;發現接口返回異常Cannot enqueue Query after fatal error 從日志看上去&#xff0c;接口是正常運行的&#xff0c;搜索一下之后發現是數據庫的問題&#xff0c;連接斷開了 原因 MySQL中有一個名叫wait_timeout的變量&#xff0c;表示操…

由監官要求下架docker hub鏡像導致無法正常拉取鏡像

問題&#xff1a;下載docker鏡像超時 error pulling image configuration: download failed after attempts6: dial tcp 202.160.128.205:443: i/o timeout解決辦法&#xff1a;配置daemon.json [rootbogon aihuidi]# cat /etc/docker/daemon.json {"registry-mirrors&qu…

java springboot過濾器

在Spring Boot應用中添加自定義過濾器&#xff0c;可以通過實現Filter接口或繼承OncePerRequestFilter類來創建過濾器&#xff0c;并使用FilterRegistrationBean將其注冊到Spring容器中。 以下是一個簡單的示例&#xff1a; 1. 創建過濾器類 首先&#xff0c;創建一個實現Fil…

C++基礎語法:類構造函數

前言 "打牢基礎,萬事不愁" .C的基礎語法的學習 引入 類是實現面向對象思想的主要方法.前面提到:類是函數的變種,類可以通過調用靜態方法或者成員函數來實現邏輯.多數情況下使用成員函數.構造函數是生成類對象成員的必須條件,對此做一些構造函數的歸納 構造函數的目…

【日志消息類的編寫】

日志消息類編寫 由于上篇的代碼比較簡單&#xff0c;今天就多寫兩段代碼順便把日志消息類編寫完成。 這個類的實現就是&#xff1a;什么時間&#xff0c;哪個線程&#xff0c;哪個文件的哪一行&#xff0c;發生了什么等級的日志&#xff0c;日志機器名字是什么&#xff0c;日…

20240628 每日AI必讀資訊

&#x1f4da; Hugging Face 推出新版開源大模型排行榜&#xff0c;中國模型 Qwen-72B 奪冠 - 阿里Qwen-2-72B指令微調版本問鼎全球開源大模型排行榜榜首 - Llama-3-70B 微調版本排名第二&#xff0c;而 Mixtral-8x22B 微調版本位居第四。 - 另外&#xff0c;微軟的 Phi-3-M…

三種分布式鎖實現方式

目錄 1、數據庫自增 2、Redis自增 3、Zookeeper 4、其他 4.1、雪花算法 4.2、Tinyid 4.3、Leaf 4.4、數據庫號段 1、數據庫自增 利用數據庫表的自增特性&#xff0c;或主鍵唯一性&#xff0c;實現分布式ID REPLACE INTO id_table (stub) values (’a‘) ; SELECT LA…

社交App廣告優化新篇章:Xinstall引領用戶體驗升級,助力買量效果提升

隨著移動互聯網的快速發展&#xff0c;社交App已經成為人們生活中不可或缺的一部分。然而&#xff0c;在競爭激烈的市場環境下&#xff0c;如何有效地進行廣告投放&#xff0c;吸引并留住用戶&#xff0c;成為了每個社交App運營者面臨的重大挑戰。今天&#xff0c;我們就來談談…

自費5K,測評安德邁、小米、希喂三款寵物空氣凈化器誰才是高性價比之王

最近&#xff0c;家里的貓咪掉毛嚴重&#xff0c;簡直成了一個活生生的蒲公英&#xff0c;家中、空氣中各處都彌漫著貓浮毛甚至所有衣物都覆蓋著一層厚厚的貓毛。令人難以置信的是&#xff0c;有時我甚至在摳出的眼屎中都能發現夾雜著幾根貓毛。真的超級困擾了。但其實最空氣中…

Packer-Fuzzer一款好用的前端高效安全掃描工具

★★免責聲明★★ 文章中涉及的程序(方法)可能帶有攻擊性&#xff0c;僅供安全研究與學習之用&#xff0c;讀者將信息做其他用途&#xff0c;由Ta承擔全部法律及連帶責任&#xff0c;文章作者不承擔任何法律及連帶責任。 1、Packer Fuzzer介紹 Packer Fuzzer是一款針對Webpack…

4.if 條件判斷

1.if-else語句 if #判斷條件 :pass else:pass2.if - elif- else if #判斷條件 :pass elif #判斷條件:pass else:pass3.if語句可以嵌套 if #判斷條件 :passif #判斷條件 :pass 4.邏輯運算符 and 兩個都為真,才是真 or 一個為真 即是真 not 取反 and從左到右,所有值為真,返回…

麒麟系統安裝MySQL

搞了一整天&#xff0c;終于搞定了&#xff0c;記錄一下。 一、背景 項目的原因&#xff0c;基于JeecgBoot開發的系統需要國產化支持&#xff0c;這就需要在電腦上安裝MySQL等支撐軟件。 國產化項目的操作系統多是麒麟系統&#xff0c;我的系統如下&#xff1a; arm64架構。…

C#快速開發OPCUA服務器

為方便演示&#xff0c;此時創建一個控制臺應用程序。第三方dll(C編寫的庫opcsrv.dll&#xff0c;他人實現)。 拷貝dll到運行目錄下&#xff1a; 拷貝二次封裝后的文件到項目目錄下&#xff1a; 第一步&#xff1a;創建OpcUa服務器 //第一步&#xff1a;創建OpcUa服務器 OPCSr…

java.util.Optional類介紹

java.util.Optional 是 Java 8 引入的一個容器類,用于表示可能包含或不包含非空值的對象。它的設計初衷是為了減少程序中的空指針異常(NullPointerException),并使代碼更加簡潔和易讀。 Optional 類的介紹 1. 特點 避免顯式的 null 檢查:使用 Optional 可以避免顯式的 n…

基于ssh框架的個人博客源碼

基于ssh的個人博客源碼&#xff0c;頁面清爽簡潔&#xff0c;原先有部分bug,運行不了&#xff0c;現已修復 1.博客首頁 &#xff08;本地訪問地址 :localhost:8080/Blog/index/index&#xff09; 2.關于我 3.慢生活 4.留言板 5.我的相冊 微信掃碼下載源碼

商場配電新思維:智能網關驅動的自動化管理系統

在商場配電室監控系統中&#xff0c;主要是以無線網絡為載體&#xff0c;目的就是便于對變電站等實時監測與控制。其中&#xff0c;4G配電網關非常關鍵&#xff0c;可以將配電室系統終端上的信息數據及時上傳到服務器&#xff0c;再由服務器下達控制指令到各模塊中&#xff0c;…

Oracle Database 23ai新特性之INTERVAL聚合函數增強

Oracle Database 23ai 開始 AVG 以及 SUM 函數支持 INTERVAL 數據類型&#xff0c;它們可以作為聚合函數或者分析函數使用。 示例表 本文將會使用以下示例表&#xff1a; create table t1 (id integer,start_time timestamp,end_time timestamp,duration in…

超越規模的冒險之旅:引導人工智能價值對齊

在茫茫技術之林中&#xff0c;人工智能憑借大模型占據了重要地位。人們已經不再局限于人機對弈和AI識圖&#xff0c;開始探索那些能夠模仿人類思考的機器。無論是日常聊天、文本寫作&#xff0c;還是[在完美的提示詞引導下創作出驚艷的詩歌]&#xff0c;我們不得不承認AI工具已…