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;
// 获取视频的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");
}
}
}