C# YoloV8 OpenVINO 视频抽帧 自动标注 预标注工具
目录
效果
视频抽帧 自动标注 预标注工具 效果
项目
代码
using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace yolov8_OpenVINO_Demo
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
YoloV8 yoloV8;
YoloV8Async yoloV8Async;
string model_path;
string video_path = "";
string video_name = "";
string videoFilter = "*.mp4|*.mp4;";
VideoCapture vcapture;
string output_path = "";
string images_path = "";
string labels_path = "";
StringBuilder sb = new StringBuilder();
/// <summary>
/// 窗体加载,初始化
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Form1_Load(object sender, EventArgs e)
{
model_path = "model/yolov8n.onnx";
yoloV8 = new YoloV8(model_path, "model/lable.txt");
yoloV8Async = new YoloV8Async(model_path, "model/lable.txt");
}
/// <summary>
/// 选择输出目录
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button2_Click(object sender, EventArgs e)
{
output_path = "";
using (FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog())
{
folderBrowserDialog.Description = "选择目录";
DialogResult dialogResult = folderBrowserDialog.ShowDialog();
if (dialogResult == DialogResult.OK)
{
output_path = folderBrowserDialog.SelectedPath;
}
}
}
/// <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;
video_name = System.IO.Path.GetFileNameWithoutExtension(video_path);
textBox1.Text = "";
}
/// <summary>
/// 同步接口-视频推理
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button3_Click(object sender, EventArgs e)
{
if (video_path == "")
{
MessageBox.Show("请先选择视频!");
return;
}
if (output_path == "")
{
MessageBox.Show("请先选择输出目录!");
return;
}
images_path = output_path + "\\output\\images";
labels_path = output_path + "\\output\\labels";
if (!Directory.Exists(images_path))
{
Directory.CreateDirectory(images_path);
}
if (!Directory.Exists(labels_path))
{
Directory.CreateDirectory(labels_path);
}
sb.Clear();
sb.AppendLine($"images path:{images_path}");
sb.AppendLine($"labels path:{labels_path}");
textBox1.Text = sb.ToString();
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;
}
Mat frame = new Mat();
List<DetectionResult> detResults;
// 获取视频的fps
double videoFps = vcapture.Get(VideoCaptureProperties.Fps);
// 计算等待时间(毫秒)
int delay = (int)(1000 / videoFps);
Stopwatch _stopwatch = new Stopwatch();
int frameCount = (int)vcapture.Get(VideoCaptureProperties.FrameCount);
Cv2.NamedWindow("DetectionResult 按下ESC,退出", WindowFlags.Normal);
Cv2.ResizeWindow("DetectionResult 按下ESC,退出", vcapture.FrameWidth / 2, vcapture.FrameHeight / 2);
int FrameWidth = vcapture.FrameWidth;
int FrameHeight = vcapture.FrameHeight;
int index = 0;
while (vcapture.Read(frame))
{
if (frame.Empty())
{
MessageBox.Show("读取失败");
return;
}
_stopwatch.Restart();
delay = (int)(1000 / videoFps);
detResults = yoloV8.Detect(frame);
//输出图片
Task.Factory.StartNew(() =>
{
Cv2.ImWrite(images_path + "\\" + video_name + "_" + index.ToString() + ".jpg", frame);
});
StringBuilder sbLabels = new StringBuilder();
//绘制结果
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);
//class, x_center, y_center, width, height
double width = Math.Round(r.Rect.Width / (double)FrameWidth, 6);
double height = Math.Round(r.Rect.Height / (double)FrameHeight, 6);
double x_center = Math.Round((r.Rect.Right - (r.Rect.Width / 2)) / (double)FrameWidth, 6);
double y_center = Math.Round((r.Rect.Bottom - (r.Rect.Height / 2)) / (double)FrameHeight, 6);
sbLabels.Append($"{r.ClassId} {x_center} {y_center} {width} {height}\n");
}
//生成不带BOM格式
using (FileStream fs = new FileStream(labels_path + "\\" + video_name + "_" + index.ToString() + ".txt", FileMode.Create))
{
using (StreamWriter sw = new StreamWriter(fs, new UTF8Encoding(false)))
{
sw.Write(sbLabels.ToString());
}
}
//Cv2.ImWrite(images_path + "\\" + index.ToString() + ".jpg", frame);
index++;
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);
Cv2.PutText(frame, "progress:" + index.ToString() + "/" + frameCount.ToString(), new OpenCvSharp.Point(10, 270), HersheyFonts.HersheySimplex, 1, Scalar.Red, 2);
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; // 如果按下ESC,退出循环
}
}
Cv2.DestroyAllWindows();
vcapture.Release();
}
/// <summary>
/// 异步接口-视频推理
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
if (video_path == "")
{
MessageBox.Show("请先选择视频!");
return;
}
if (output_path == "")
{
MessageBox.Show("请先选择输出目录!");
return;
}
images_path = output_path + "\\output\\images";
labels_path = output_path + "\\output\\labels";
if (!Directory.Exists(images_path))
{
Directory.CreateDirectory(images_path);
}
if (!Directory.Exists(labels_path))
{
Directory.CreateDirectory(labels_path);
}
textBox1.Text = "开始异步推理检测";
Application.DoEvents();
Thread thread = new Thread(new ThreadStart(VideoDetectionAsync));
thread.Start();
thread.Join();
textBox1.Text = "异步推理检测完成!";
}
void VideoDetectionAsync()
{
vcapture = new VideoCapture(video_path);
if (!vcapture.IsOpened())
{
MessageBox.Show("打开视频文件失败");
return;
}
Mat frame = new Mat();
List<DetectionResult> detResults;
// 获取视频的fps
double videoFps = vcapture.Get(VideoCaptureProperties.Fps);
// 计算等待时间(毫秒)
int delay = (int)(1000 / videoFps);
Stopwatch _stopwatch = new Stopwatch();
int frameCount = (int)vcapture.Get(VideoCaptureProperties.FrameCount);
Cv2.NamedWindow("DetectionResult 按下ESC,退出", WindowFlags.Normal);
Cv2.ResizeWindow("DetectionResult 按下ESC,退出", vcapture.FrameWidth / 2, vcapture.FrameHeight / 2);
int FrameWidth = vcapture.FrameWidth;
int FrameHeight = vcapture.FrameHeight;
int index = 0;
while (vcapture.Read(frame))
{
if (frame.Empty())
{
MessageBox.Show("读取失败");
return;
}
//输出图片
Task.Factory.StartNew(() =>
{
Cv2.ImWrite(images_path + "\\" + video_name + "_" + index.ToString() + ".jpg", frame);
});
detResults = yoloV8Async.Detect(frame);
StringBuilder sbLabels = new StringBuilder();
//绘制结果
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);
//class, x_center, y_center, width, height
double width = Math.Round(r.Rect.Width / (double)FrameWidth, 6);
double height = Math.Round(r.Rect.Height / (double)FrameHeight, 6);
double x_center = Math.Round((r.Rect.Right - (r.Rect.Width / 2)) / (double)FrameWidth, 6);
double y_center = Math.Round((r.Rect.Bottom - (r.Rect.Height / 2)) / (double)FrameHeight, 6);
sbLabels.Append($"{r.ClassId} {x_center} {y_center} {width} {height}\n");
}
//生成不带BOM格式
using (FileStream fs = new FileStream(labels_path + "\\" + video_name + "_" + index.ToString() + ".txt", FileMode.Create))
{
using (StreamWriter sw = new StreamWriter(fs, new UTF8Encoding(false)))
{
sw.Write(sbLabels.ToString());
}
}
//Cv2.ImWrite(images_path + "\\" + index.ToString() + ".jpg", frame);
index++;
Cv2.PutText(frame, "preprocessTime:" + yoloV8Async.preprocessTime.ToString("F2") + "ms", new OpenCvSharp.Point(10, 30), HersheyFonts.HersheySimplex, 1, Scalar.Red, 2);
Cv2.PutText(frame, "inferTime:" + yoloV8Async.inferTime.ToString("F2") + "ms", new OpenCvSharp.Point(10, 70), HersheyFonts.HersheySimplex, 1, Scalar.Red, 2);
Cv2.PutText(frame, "postprocessTime:" + yoloV8Async.postprocessTime.ToString("F2") + "ms", new OpenCvSharp.Point(10, 110), HersheyFonts.HersheySimplex, 1, Scalar.Red, 2);
Cv2.PutText(frame, "totalTime:" + yoloV8Async.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:" + yoloV8Async.detFps.ToString("F2"), new OpenCvSharp.Point(10, 230), HersheyFonts.HersheySimplex, 1, Scalar.Red, 2);
Cv2.PutText(frame, "progress:" + index.ToString() + "/" + frameCount.ToString(), new OpenCvSharp.Point(10, 270), HersheyFonts.HersheySimplex, 1, Scalar.Red, 2);
//Cv2.ImWrite(images_path + "\\" + index.ToString() + ".jpg", 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; // 如果按下ESC,退出循环
}
}
Cv2.DestroyAllWindows();
vcapture.Release();
}
}
}
using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace yolov8_OpenVINO_Demo
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
YoloV8 yoloV8;
YoloV8Async yoloV8Async;
string model_path;
string video_path = "";
string video_name = "";
string videoFilter = "*.mp4|*.mp4;";
VideoCapture vcapture;
string output_path = "";
string images_path = "";
string labels_path = "";
StringBuilder sb = new StringBuilder();
/// <summary>
/// 窗体加载,初始化
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Form1_Load(object sender, EventArgs e)
{
model_path = "model/yolov8n.onnx";
yoloV8 = new YoloV8(model_path, "model/lable.txt");
yoloV8Async = new YoloV8Async(model_path, "model/lable.txt");
}
/// <summary>
/// 选择输出目录
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button2_Click(object sender, EventArgs e)
{
output_path = "";
using (FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog())
{
folderBrowserDialog.Description = "选择目录";
DialogResult dialogResult = folderBrowserDialog.ShowDialog();
if (dialogResult == DialogResult.OK)
{
output_path = folderBrowserDialog.SelectedPath;
}
}
}
/// <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;
video_name = System.IO.Path.GetFileNameWithoutExtension(video_path);
textBox1.Text = "";
}
/// <summary>
/// 同步接口-视频推理
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button3_Click(object sender, EventArgs e)
{
if (video_path == "")
{
MessageBox.Show("请先选择视频!");
return;
}
if (output_path == "")
{
MessageBox.Show("请先选择输出目录!");
return;
}
images_path = output_path + "\\output\\images";
labels_path = output_path + "\\output\\labels";
if (!Directory.Exists(images_path))
{
Directory.CreateDirectory(images_path);
}
if (!Directory.Exists(labels_path))
{
Directory.CreateDirectory(labels_path);
}
sb.Clear();
sb.AppendLine($"images path:{images_path}");
sb.AppendLine($"labels path:{labels_path}");
textBox1.Text = sb.ToString();
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;
}
Mat frame = new Mat();
List<DetectionResult> detResults;
// 获取视频的fps
double videoFps = vcapture.Get(VideoCaptureProperties.Fps);
// 计算等待时间(毫秒)
int delay = (int)(1000 / videoFps);
Stopwatch _stopwatch = new Stopwatch();
int frameCount = (int)vcapture.Get(VideoCaptureProperties.FrameCount);
Cv2.NamedWindow("DetectionResult 按下ESC,退出", WindowFlags.Normal);
Cv2.ResizeWindow("DetectionResult 按下ESC,退出", vcapture.FrameWidth / 2, vcapture.FrameHeight / 2);
int FrameWidth = vcapture.FrameWidth;
int FrameHeight = vcapture.FrameHeight;
int index = 0;
while (vcapture.Read(frame))
{
if (frame.Empty())
{
MessageBox.Show("读取失败");
return;
}
_stopwatch.Restart();
delay = (int)(1000 / videoFps);
detResults = yoloV8.Detect(frame);
//输出图片
Task.Factory.StartNew(() =>
{
Cv2.ImWrite(images_path + "\\" + video_name + "_" + index.ToString() + ".jpg", frame);
});
StringBuilder sbLabels = new StringBuilder();
//绘制结果
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);
//class, x_center, y_center, width, height
double width = Math.Round(r.Rect.Width / (double)FrameWidth, 6);
double height = Math.Round(r.Rect.Height / (double)FrameHeight, 6);
double x_center = Math.Round((r.Rect.Right - (r.Rect.Width / 2)) / (double)FrameWidth, 6);
double y_center = Math.Round((r.Rect.Bottom - (r.Rect.Height / 2)) / (double)FrameHeight, 6);
sbLabels.Append($"{r.ClassId} {x_center} {y_center} {width} {height}\n");
}
//生成不带BOM格式
using (FileStream fs = new FileStream(labels_path + "\\" + video_name + "_" + index.ToString() + ".txt", FileMode.Create))
{
using (StreamWriter sw = new StreamWriter(fs, new UTF8Encoding(false)))
{
sw.Write(sbLabels.ToString());
}
}
//Cv2.ImWrite(images_path + "\\" + index.ToString() + ".jpg", frame);
index++;
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);
Cv2.PutText(frame, "progress:" + index.ToString() + "/" + frameCount.ToString(), new OpenCvSharp.Point(10, 270), HersheyFonts.HersheySimplex, 1, Scalar.Red, 2);
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; // 如果按下ESC,退出循环
}
}
Cv2.DestroyAllWindows();
vcapture.Release();
}
/// <summary>
/// 异步接口-视频推理
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
if (video_path == "")
{
MessageBox.Show("请先选择视频!");
return;
}
if (output_path == "")
{
MessageBox.Show("请先选择输出目录!");
return;
}
images_path = output_path + "\\output\\images";
labels_path = output_path + "\\output\\labels";
if (!Directory.Exists(images_path))
{
Directory.CreateDirectory(images_path);
}
if (!Directory.Exists(labels_path))
{
Directory.CreateDirectory(labels_path);
}
textBox1.Text = "开始异步推理检测";
Application.DoEvents();
Thread thread = new Thread(new ThreadStart(VideoDetectionAsync));
thread.Start();
thread.Join();
textBox1.Text = "异步推理检测完成!";
}
void VideoDetectionAsync()
{
vcapture = new VideoCapture(video_path);
if (!vcapture.IsOpened())
{
MessageBox.Show("打开视频文件失败");
return;
}
Mat frame = new Mat();
List<DetectionResult> detResults;
// 获取视频的fps
double videoFps = vcapture.Get(VideoCaptureProperties.Fps);
// 计算等待时间(毫秒)
int delay = (int)(1000 / videoFps);
Stopwatch _stopwatch = new Stopwatch();
int frameCount = (int)vcapture.Get(VideoCaptureProperties.FrameCount);
Cv2.NamedWindow("DetectionResult 按下ESC,退出", WindowFlags.Normal);
Cv2.ResizeWindow("DetectionResult 按下ESC,退出", vcapture.FrameWidth / 2, vcapture.FrameHeight / 2);
int FrameWidth = vcapture.FrameWidth;
int FrameHeight = vcapture.FrameHeight;
int index = 0;
while (vcapture.Read(frame))
{
if (frame.Empty())
{
MessageBox.Show("读取失败");
return;
}
//输出图片
Task.Factory.StartNew(() =>
{
Cv2.ImWrite(images_path + "\\" + video_name + "_" + index.ToString() + ".jpg", frame);
});
detResults = yoloV8Async.Detect(frame);
StringBuilder sbLabels = new StringBuilder();
//绘制结果
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);
//class, x_center, y_center, width, height
double width = Math.Round(r.Rect.Width / (double)FrameWidth, 6);
double height = Math.Round(r.Rect.Height / (double)FrameHeight, 6);
double x_center = Math.Round((r.Rect.Right - (r.Rect.Width / 2)) / (double)FrameWidth, 6);
double y_center = Math.Round((r.Rect.Bottom - (r.Rect.Height / 2)) / (double)FrameHeight, 6);
sbLabels.Append($"{r.ClassId} {x_center} {y_center} {width} {height}\n");
}
//生成不带BOM格式
using (FileStream fs = new FileStream(labels_path + "\\" + video_name + "_" + index.ToString() + ".txt", FileMode.Create))
{
using (StreamWriter sw = new StreamWriter(fs, new UTF8Encoding(false)))
{
sw.Write(sbLabels.ToString());
}
}
//Cv2.ImWrite(images_path + "\\" + index.ToString() + ".jpg", frame);
index++;
Cv2.PutText(frame, "preprocessTime:" + yoloV8Async.preprocessTime.ToString("F2") + "ms", new OpenCvSharp.Point(10, 30), HersheyFonts.HersheySimplex, 1, Scalar.Red, 2);
Cv2.PutText(frame, "inferTime:" + yoloV8Async.inferTime.ToString("F2") + "ms", new OpenCvSharp.Point(10, 70), HersheyFonts.HersheySimplex, 1, Scalar.Red, 2);
Cv2.PutText(frame, "postprocessTime:" + yoloV8Async.postprocessTime.ToString("F2") + "ms", new OpenCvSharp.Point(10, 110), HersheyFonts.HersheySimplex, 1, Scalar.Red, 2);
Cv2.PutText(frame, "totalTime:" + yoloV8Async.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:" + yoloV8Async.detFps.ToString("F2"), new OpenCvSharp.Point(10, 230), HersheyFonts.HersheySimplex, 1, Scalar.Red, 2);
Cv2.PutText(frame, "progress:" + index.ToString() + "/" + frameCount.ToString(), new OpenCvSharp.Point(10, 270), HersheyFonts.HersheySimplex, 1, Scalar.Red, 2);
//Cv2.ImWrite(images_path + "\\" + index.ToString() + ".jpg", 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; // 如果按下ESC,退出循环
}
}
Cv2.DestroyAllWindows();
vcapture.Release();
}
}
}