C# YoloV8 OpenVINO 视频抽帧 自动标注 预标注工具

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

下载

源码下载

相关推荐
古希腊掌管学习的神几秒前
[机器学习]XGBoost(3)——确定树的结构
人工智能·机器学习
ZHOU_WUYI29 分钟前
4.metagpt中的软件公司智能体 (ProjectManager 角色)
人工智能·metagpt
靴子学长1 小时前
基于字节大模型的论文翻译(含免费源码)
人工智能·深度学习·nlp
AI_NEW_COME2 小时前
知识库管理系统可扩展性深度测评
人工智能
海棠AI实验室2 小时前
AI的进阶之路:从机器学习到深度学习的演变(一)
人工智能·深度学习·机器学习
hunteritself2 小时前
AI Weekly『12月16-22日』:OpenAI公布o3,谷歌发布首个推理模型,GitHub Copilot免费版上线!
人工智能·gpt·chatgpt·github·openai·copilot
IT古董3 小时前
【机器学习】机器学习的基本分类-强化学习-策略梯度(Policy Gradient,PG)
人工智能·机器学习·分类
centurysee3 小时前
【最佳实践】Anthropic:Agentic系统实践案例
人工智能
mahuifa3 小时前
混合开发环境---使用编程AI辅助开发Qt
人工智能·vscode·qt·qtcreator·编程ai
四口鲸鱼爱吃盐3 小时前
Pytorch | 从零构建GoogleNet对CIFAR10进行分类
人工智能·pytorch·分类