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");}}}
下載
源碼下載