C#开发者必备!快速掌握onnxruntime实现YOWOv2视频动作检测技术!

C#开发者必备!快速掌握onnxruntime实现YOWOv2视频动作检测技术!

目录

介绍

效果

模型信息

项目

代码

Form1.cs

YOWOv2.cs

下载


介绍

YOWOv2: A Stronger yet Efficient Multi-level Detection Framework for Real-time Spatio-temporal Action

代码实现参考

https://github.com/hpc203/YOWOv2-video-action-detect-onnxrun

训练源码

GitHub - yjh0410/YOWOv2: The second generation of YOWO action detector.

YOWOv2介绍

https://blog.csdn.net/weixin_46687145/article/details/136488363

效果

C# Onnx YOWOv2 视频动作检测

模型信息

Model Properties
-------------------------
---------------------------------------------------------------

Inputs
-------------------------
name:input
tensor:Float[1, 3, 16, 224, 224]
---------------------------------------------------------------

Outputs
-------------------------
name:conf_preds0
tensor:Float[1, 784, 1]
name:conf_preds1
tensor:Float[1, 196, 1]
name:conf_preds2
tensor:Float[1, 49, 1]
name:cls_preds0
tensor:Float[1, 784, 80]
name:cls_preds1
tensor:Float[1, 196, 80]
name:cls_preds2
tensor:Float[1, 49, 80]
name:reg_preds0
tensor:Float[1, 784, 4]
name:reg_preds1
tensor:Float[1, 196, 4]
name:erg_preds2
tensor:Float[1, 49, 4]
---------------------------------------------------------------

项目

代码

Form1.cs

using OpenCvSharp;
using OpenCvSharp.Extensions;
using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace C__Onnx_YOWOv2视频动作检测
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        YOWOv2 mynet = new YOWOv2("model/yowo_v2_nano_ava.onnx", "ava");
        string videopath = "";
        Mat currentFrame = new Mat();
        VideoCapture capture;

        private void button1_Click(object sender, EventArgs e)
        {

            if (videopath == "")
            {
                return;
            }

            int len_clip = mynet.len_clip;
            float vis_thresh = 0.2f;

            textBox1.Text = "正在检测,请稍后……";

            //videopath = "dataset/ucf24_demo/v_Basketball_g01_c02.mp4";
            string savepath = "result.mp4";
            VideoCapture vcapture = new VideoCapture(videopath);
            if (!vcapture.IsOpened())
            {
                MessageBox.Show("打开视频文件失败");
                return;
            }

            VideoWriter vwriter = new VideoWriter(savepath, FourCC.X264, vcapture.Fps, new OpenCvSharp.Size(vcapture.FrameWidth, vcapture.FrameHeight));

            Mat frame = new Mat();
            List<Mat> video_clip = new List<Mat>();
            int index = 0;
            while (vcapture.Read(frame))
            {
                if (frame.Empty())
                {
                    MessageBox.Show("打开视频文件失败");
                    return;
                }

                if (video_clip.Count <= 0)
                {
                    for (int i = 0; i < len_clip; i++)
                    {
                        video_clip.Add(frame);
                    }
                }
                video_clip.Add(frame);
                video_clip.RemoveAt(0);

                if (mynet.multi_hot)
                {
                    List<Bbox> boxes = new List<Bbox>();
                    List<float> det_conf = new List<float>();
                    List<List<float>> cls_conf = new List<List<float>>();
                    List<int> keep_inds = mynet.detect_multi_hot(video_clip, boxes, det_conf, cls_conf); //keep_inds记录vector里面的有效检测框的序号

                    Mat dstimg = Common.vis_multi_hot(frame, boxes, det_conf, cls_conf, keep_inds, vis_thresh);

                    //Cv2.ImWrite("img/" + (index++).ToString() + ".jpg", dstimg);

                    vwriter.Write(dstimg);

                    dstimg.Dispose();
                }
                else
                {
                    List<Bbox> boxes = new List<Bbox>();
                    List<float> det_conf = new List<float>();
                    List<int> cls_id = new List<int>();
                    List<int> keep_inds = mynet.detect_one_hot(video_clip, boxes, det_conf, cls_id); //keep_inds记录vector里面的有效检测框的序号
                    Mat dstimg = Common.vis_one_hot(frame, boxes, det_conf, cls_id, keep_inds, vis_thresh, 0.4f);
                    vwriter.Write(dstimg);
                    dstimg.Dispose();
                }
            }
            vcapture.Release();
            vwriter.Release();
            MessageBox.Show("检测完成,点击确认后播放检测后效果!");

            textBox1.Text = "播放result.mp4";
            videopath = "result.mp4";
            capture = new VideoCapture(videopath);
            if (!capture.IsOpened())
            {
                MessageBox.Show("打开视频文件失败");
                return;
            }
            capture.Read(currentFrame);
            if (!currentFrame.Empty())
            {
                pictureBox1.Image = BitmapConverter.ToBitmap(currentFrame);
                timer1.Interval = (int)(1000.0 / capture.Fps);
                timer1.Enabled = true;
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "Video files MP4 files (*.mp4)|*.mp4";
            ofd.InitialDirectory = Application.StartupPath;
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                videopath = ofd.FileName;
                capture = new VideoCapture(videopath);
                if (!capture.IsOpened())
                {
                    MessageBox.Show("打开视频文件失败");
                    return;
                }
                capture.Read(currentFrame);
                if (!currentFrame.Empty())
                {
                    pictureBox1.Image = BitmapConverter.ToBitmap(currentFrame);
                    timer1.Interval = (int)(1000.0 / capture.Fps);
                    timer1.Enabled = true;
                }
            }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            capture.Read(currentFrame);
            if (currentFrame.Empty())
            {
                //pictureBox1.Image = null;
                timer1.Enabled = false;
                capture.Release();
                textBox1.Text = "播放完毕。";
                return;
            }
            pictureBox1.Image = BitmapConverter.ToBitmap(currentFrame);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            videopath = "dataset/ucf24_demo/v_Basketball_g01_c02.mp4";
            capture = new VideoCapture(videopath);
            if (!capture.IsOpened())
            {
                MessageBox.Show("打开视频文件失败");
                return;
            }
            textBox1.Text = "播放v_Basketball_g01_c02.mp4";
            capture.Read(currentFrame);
            if (!currentFrame.Empty())
            {
                pictureBox1.Image = BitmapConverter.ToBitmap(currentFrame);
                timer1.Interval = (int)(1000.0 / capture.Fps);
                timer1.Enabled = true;
            }
        }
    }
}

using OpenCvSharp;
using OpenCvSharp.Extensions;
using System;
using System.Collections.Generic;
using System.Windows.Forms;namespace C__Onnx_YOWOv2视频动作检测
{public partial class Form1 : Form{public Form1(){InitializeComponent();}YOWOv2 mynet = new YOWOv2("model/yowo_v2_nano_ava.onnx", "ava");string videopath = "";Mat currentFrame = new Mat();VideoCapture capture;private void button1_Click(object sender, EventArgs e){if (videopath == ""){return;}int len_clip = mynet.len_clip;float vis_thresh = 0.2f;textBox1.Text = "正在检测,请稍后……";//videopath = "dataset/ucf24_demo/v_Basketball_g01_c02.mp4";string savepath = "result.mp4";VideoCapture vcapture = new VideoCapture(videopath);if (!vcapture.IsOpened()){MessageBox.Show("打开视频文件失败");return;}VideoWriter vwriter = new VideoWriter(savepath, FourCC.X264, vcapture.Fps, new OpenCvSharp.Size(vcapture.FrameWidth, vcapture.FrameHeight));Mat frame = new Mat();List<Mat> video_clip = new List<Mat>();int index = 0;while (vcapture.Read(frame)){if (frame.Empty()){MessageBox.Show("打开视频文件失败");return;}if (video_clip.Count <= 0){for (int i = 0; i < len_clip; i++){video_clip.Add(frame);}}video_clip.Add(frame);video_clip.RemoveAt(0);if (mynet.multi_hot){List<Bbox> boxes = new List<Bbox>();List<float> det_conf = new List<float>();List<List<float>> cls_conf = new List<List<float>>();List<int> keep_inds = mynet.detect_multi_hot(video_clip, boxes, det_conf, cls_conf); //keep_inds记录vector里面的有效检测框的序号Mat dstimg = Common.vis_multi_hot(frame, boxes, det_conf, cls_conf, keep_inds, vis_thresh);//Cv2.ImWrite("img/" + (index++).ToString() + ".jpg", dstimg);vwriter.Write(dstimg);dstimg.Dispose();}else{List<Bbox> boxes = new List<Bbox>();List<float> det_conf = new List<float>();List<int> cls_id = new List<int>();List<int> keep_inds = mynet.detect_one_hot(video_clip, boxes, det_conf, cls_id); //keep_inds记录vector里面的有效检测框的序号Mat dstimg = Common.vis_one_hot(frame, boxes, det_conf, cls_id, keep_inds, vis_thresh, 0.4f);vwriter.Write(dstimg);dstimg.Dispose();}}vcapture.Release();vwriter.Release();MessageBox.Show("检测完成,点击确认后播放检测后效果!");textBox1.Text = "播放result.mp4";videopath = "result.mp4";capture = new VideoCapture(videopath);if (!capture.IsOpened()){MessageBox.Show("打开视频文件失败");return;}capture.Read(currentFrame);if (!currentFrame.Empty()){pictureBox1.Image = BitmapConverter.ToBitmap(currentFrame);timer1.Interval = (int)(1000.0 / capture.Fps);timer1.Enabled = true;}}private void button2_Click(object sender, EventArgs e){OpenFileDialog ofd = new OpenFileDialog();ofd.Filter = "Video files MP4 files (*.mp4)|*.mp4";ofd.InitialDirectory = Application.StartupPath;if (ofd.ShowDialog() == DialogResult.OK){videopath = ofd.FileName;capture = new VideoCapture(videopath);if (!capture.IsOpened()){MessageBox.Show("打开视频文件失败");return;}capture.Read(currentFrame);if (!currentFrame.Empty()){pictureBox1.Image = BitmapConverter.ToBitmap(currentFrame);timer1.Interval = (int)(1000.0 / capture.Fps);timer1.Enabled = true;}}}private void timer1_Tick(object sender, EventArgs e){capture.Read(currentFrame);if (currentFrame.Empty()){//pictureBox1.Image = null;timer1.Enabled = false;capture.Release();textBox1.Text = "播放完毕。";return;}pictureBox1.Image = BitmapConverter.ToBitmap(currentFrame);}private void Form1_Load(object sender, EventArgs e){videopath = "dataset/ucf24_demo/v_Basketball_g01_c02.mp4";capture = new VideoCapture(videopath);if (!capture.IsOpened()){MessageBox.Show("打开视频文件失败");return;}textBox1.Text = "播放v_Basketball_g01_c02.mp4";capture.Read(currentFrame);if (!currentFrame.Empty()){pictureBox1.Image = BitmapConverter.ToBitmap(currentFrame);timer1.Interval = (int)(1000.0 / capture.Fps);timer1.Enabled = true;}}}
}

YOWOv2.cs

using Microsoft.ML.OnnxRuntime;
using Microsoft.ML.OnnxRuntime.Tensors;
using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;namespace C__Onnx_YOWOv2视频动作检测
{public class YOWOv2{public int len_clip;public bool multi_hot;List<float> input_tensor_data = new List<float>();int inpWidth;int inpHeight;float nms_thresh;float conf_thresh;int num_class;int topk = 40;int[] strides = new int[] { 8, 16, 32 };bool act_pose;SessionOptions options;InferenceSession onnx_session;public YOWOv2(string modelpath, string dataset = "ava_v2.2", float nms_thresh_ = 0.5f, float conf_thresh_ = 0.1f, bool act_pose_ = false){// 创建输出会话,用于输出模型读取信息options = new SessionOptions();options.LogSeverityLevel = OrtLoggingLevel.ORT_LOGGING_LEVEL_INFO;options.AppendExecutionProvider_CPU(0);// 设置为CPU上运行// 创建推理模型类,读取本地模型文件onnx_session = new InferenceSession(modelpath, options);//model_path 为onnx模型文件的路径this.len_clip = 16;this.inpHeight = 224;this.inpWidth = 224;if (dataset == "ava_v2.2" || dataset == "ava"){this.num_class = 80;this.multi_hot = true;}else{this.num_class = 24;this.multi_hot = false;}this.conf_thresh = conf_thresh_;this.nms_thresh = nms_thresh_;this.act_pose = act_pose_;}float[] ExtractMat(Mat src){OpenCvSharp.Size size = src.Size();int channels = src.Channels();float[] result = new float[size.Width * size.Height * channels];GCHandle resultHandle = default;try{resultHandle = GCHandle.Alloc(result, GCHandleType.Pinned);IntPtr resultPtr = resultHandle.AddrOfPinnedObject();for (int i = 0; i < channels; ++i){Mat cmat = new Mat(src.Height, src.Width,MatType.CV_32FC1,resultPtr + i * size.Width * size.Height * sizeof(float));Cv2.ExtractChannel(src, cmat, i);cmat.Dispose();}}finally{resultHandle.Free();}return result;}void preprocess(List<Mat> video_clip){input_tensor_data.Clear();for (int i = 0; i < this.len_clip; i++){Mat resizeimg = new Mat();Cv2.Resize(video_clip[i], resizeimg, new Size(this.inpWidth, this.inpHeight));resizeimg.ConvertTo(resizeimg, MatType.CV_32FC3);var data = ExtractMat(resizeimg);resizeimg.Dispose();input_tensor_data.AddRange(data.ToList());}}void generate_proposal_multi_hot(int stride, float[] conf_pred, float[] cls_pred, float[] reg_pred, List<Bbox> boxes, List<float> det_conf, List<List<float>> cls_conf){int feat_h = (int)Math.Ceiling((float)this.inpHeight / stride);int feat_w = (int)Math.Ceiling((float)this.inpWidth / stride);int area = feat_h * feat_w;float[] conf_pred_i = new float[area];for (int i = 0; i < area; i++){conf_pred_i[i] = Common.sigmoid(conf_pred[i]);}List<int> topk_inds = Common.TopKIndex(conf_pred_i.ToList(), this.topk);int length = this.num_class;if (this.act_pose){length = 14;}for (int i = 0; i < topk_inds.Count; i++){int ind = topk_inds[i];if (conf_pred_i[ind] > this.conf_thresh){int row = 0, col = 0;Common.ind2sub(ind, feat_w, feat_h, ref row, ref col);float cx = (col + 0.5f + reg_pred[ind * 4]) * stride;float cy = (row + 0.5f + reg_pred[ind * 4 + 1]) * stride;float w = (float)(Math.Exp(reg_pred[ind * 4 + 2]) * stride);float h = (float)(Math.Exp(reg_pred[ind * 4 + 3]) * stride);boxes.Add(new Bbox((int)(cx - 0.5 * w), (int)(cy - 0.5 * h), (int)(cx + 0.5 * w), (int)(cy + 0.5 * h)));det_conf.Add(conf_pred_i[ind]);float[] cls_conf_i = new float[length];for (int j = 0; j < length; j++){cls_conf_i[j] = Common.sigmoid(cls_pred[ind * this.num_class + j]);}cls_conf.Add(cls_conf_i.ToList());}}}void generate_proposal_one_hot(int stride, float[] conf_pred, float[] cls_pred, float[] reg_pred, List<Bbox> boxes, List<float> det_conf, List<int> cls_id){int feat_h = (int)Math.Ceiling((float)inpHeight / stride);int feat_w = (int)Math.Ceiling((float)inpWidth / stride);int area = feat_h * feat_w;float[] det_scores_i = new float[area * this.num_class];for (int i = 0; i < area; i++){for (int j = 0; j < this.num_class; j++){det_scores_i[i * this.num_class + j] = (float)Math.Sqrt(Common.sigmoid(conf_pred[i]) * Common.sigmoid(cls_pred[i * this.num_class + j]));}}int num_topk = Math.Min(this.topk, area);List<int> topk_inds = Common.TopKIndex(det_scores_i.ToList(), num_topk);for (int i = 0; i < topk_inds.Count; i++){int ind = topk_inds[i];if (det_scores_i[ind] > this.conf_thresh){det_conf.Add(det_scores_i[ind]);int idx = ind % this.num_class;cls_id.Add(idx);int row_ind = ind / this.num_class;int row = 0, col = 0;Common.ind2sub(row_ind, feat_w, feat_h, ref row, ref col);float cx = (col + 0.5f + reg_pred[row_ind * 4]) * stride;float cy = (row + 0.5f + reg_pred[row_ind * 4 + 1]) * stride;float w = (float)(Math.Exp(reg_pred[row_ind * 4 + 2]) * stride);float h = (float)(Math.Exp(reg_pred[row_ind * 4 + 3]) * stride);boxes.Add(new Bbox((int)(cx - 0.5 * w), (int)(cy - 0.5 * h), (int)(cx + 0.5 * w), (int)(cy + 0.5 * h)));}}}public List<int> detect_multi_hot(List<Mat> video_clip, List<Bbox> boxes, List<float> det_conf, List<List<float>> cls_conf){if (video_clip.Count != this.len_clip){Console.WriteLine("input frame number is not " + this.len_clip);throw new Exception("input frame number is not " + this.len_clip);}int origin_h = video_clip[0].Rows;int origin_w = video_clip[0].Cols;this.preprocess(video_clip);Tensor<float> input_tensor = new DenseTensor<float>(input_tensor_data.ToArray(), new[] { 1, 3, this.len_clip, this.inpHeight, this.inpWidth });List<NamedOnnxValue> input_container = new List<NamedOnnxValue>{NamedOnnxValue.CreateFromTensor("input", input_tensor)};var ort_outputs = onnx_session.Run(input_container).ToArray();float[] conf_preds0 = ort_outputs[0].AsTensor<float>().ToArray();float[] conf_preds1 = ort_outputs[1].AsTensor<float>().ToArray();float[] conf_preds2 = ort_outputs[2].AsTensor<float>().ToArray();float[] cls_preds0 = ort_outputs[3].AsTensor<float>().ToArray();float[] cls_preds1 = ort_outputs[4].AsTensor<float>().ToArray();float[] cls_preds2 = ort_outputs[5].AsTensor<float>().ToArray();float[] reg_preds0 = ort_outputs[6].AsTensor<float>().ToArray();float[] reg_preds1 = ort_outputs[7].AsTensor<float>().ToArray();float[] reg_preds2 = ort_outputs[8].AsTensor<float>().ToArray();this.generate_proposal_multi_hot(this.strides[0], conf_preds0, cls_preds0, reg_preds0, boxes, det_conf, cls_conf);this.generate_proposal_multi_hot(this.strides[1], conf_preds1, cls_preds1, reg_preds1, boxes, det_conf, cls_conf);this.generate_proposal_multi_hot(this.strides[2], conf_preds2, cls_preds2, reg_preds2, boxes, det_conf, cls_conf);List<int> keep_inds = Common.multiclass_nms_class_agnostic(boxes, det_conf, this.nms_thresh);int max_hw = Math.Max(this.inpHeight, this.inpWidth);float ratio_h = (float)((float)origin_h / max_hw);float ratio_w = (float)((float)origin_w / max_hw);for (int i = 0; i < keep_inds.Count; i++){int ind = keep_inds[i];boxes[ind].xmin = (int)(boxes[ind].xmin * ratio_w);boxes[ind].ymin = (int)(boxes[ind].ymin * ratio_h);boxes[ind].xmax = (int)(boxes[ind].xmax * ratio_w);boxes[ind].ymax = (int)(boxes[ind].ymax * ratio_h);}return keep_inds;}public List<int> detect_one_hot(List<Mat> video_clip, List<Bbox> boxes, List<float> det_conf, List<int> cls_id){if (video_clip.Count != this.len_clip){Console.WriteLine("input frame number is not " + this.len_clip);throw new Exception("input frame number is not " + this.len_clip);}int origin_h = video_clip[0].Rows;int origin_w = video_clip[0].Cols;this.preprocess(video_clip);// 输入TensorTensor<float> input_tensor = new DenseTensor<float>(input_tensor_data.ToArray(), new[] { 1, 3, this.len_clip, this.inpHeight, this.inpWidth });List<NamedOnnxValue> input_container = new List<NamedOnnxValue>{//将 input_tensor 放入一个输入参数的容器,并指定名称NamedOnnxValue.CreateFromTensor("input", input_tensor)};var ort_outputs = onnx_session.Run(input_container).ToArray();float[] conf_preds0 = ort_outputs[0].AsTensor<float>().ToArray();float[] conf_preds1 = ort_outputs[1].AsTensor<float>().ToArray();float[] conf_preds2 = ort_outputs[2].AsTensor<float>().ToArray();float[] cls_preds0 = ort_outputs[3].AsTensor<float>().ToArray();float[] cls_preds1 = ort_outputs[4].AsTensor<float>().ToArray();float[] cls_preds2 = ort_outputs[5].AsTensor<float>().ToArray();float[] reg_preds0 = ort_outputs[6].AsTensor<float>().ToArray();float[] reg_preds1 = ort_outputs[7].AsTensor<float>().ToArray();float[] reg_preds2 = ort_outputs[8].AsTensor<float>().ToArray();this.generate_proposal_one_hot(this.strides[0], conf_preds0, cls_preds0, reg_preds0, boxes, det_conf, cls_id);this.generate_proposal_one_hot(this.strides[1], conf_preds1, cls_preds1, reg_preds1, boxes, det_conf, cls_id);this.generate_proposal_one_hot(this.strides[2], conf_preds2, cls_preds2, reg_preds2, boxes, det_conf, cls_id);List<int> keep_inds = Common.multiclass_nms_class_aware(boxes, det_conf, cls_id,this.nms_thresh, 24);int max_hw = Math.Max(this.inpHeight, this.inpWidth);float ratio_h = (float)((float)origin_h / max_hw);float ratio_w = (float)((float)origin_w / max_hw);for (int i = 0; i < keep_inds.Count; i++){int ind = keep_inds[i];boxes[ind].xmin = (int)(boxes[ind].xmin * ratio_w);boxes[ind].ymin = (int)(boxes[ind].ymin * ratio_h);boxes[ind].xmax = (int)(boxes[ind].xmax * ratio_w);boxes[ind].ymax = (int)(boxes[ind].ymax * ratio_h);}return keep_inds;}}
}

下载

源码下载

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/576432.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024.3.28学习笔记

今日学习韩顺平java0200_韩顺平Java_对象机制练习_哔哩哔哩_bilibili 今日学习p286-p294 继承 继承可以解决代码复用&#xff0c;让我们的编程更加靠近人类思维&#xff0c;当多个类存在相同的属性和方法时&#xff0c;可以从这些类中抽象出父类&#xff0c;在父类中定义这些…

SQL Server 实验二:数据库视图的创建和使用

目录 第一关 相关知识 什么是表 操作数据表 创建数据表 插入数据 修改表结构 删除数据表 编程要求 第一关实验代码&#xff1a; 第二关 相关知识 视图是什么 视图的优缺点 视图的优点 视图的缺点 操作视图 创建视图 通过视图向基本表中插入数据 通过视图修改基本表的…

骗子查询系统源码

源码简介 小权云黑管理系统 V1.0 功能如下&#xff1a; 1.添加骗子&#xff0c;查询骗子 2.可添加团队后台方便审核用 3.在线反馈留言系统 4.前台提交骗子&#xff0c;后台需要审核才能过 5.后台使用光年UI界面 6.新增导航列表&#xff0c;可给网站添加导航友链 7.可添加云黑类…

某某消消乐增加步数漏洞分析

一、漏洞简介 1&#xff09; 漏洞所属游戏名及基本介绍&#xff1a;某某消消乐&#xff0c;三消游戏&#xff0c;类似爱消除。 2&#xff09; 漏洞对应游戏版本及平台&#xff1a;某某消消乐Android 1.22.22。 3&#xff09; 漏洞功能&#xff1a;增加游戏步数。 4&#xf…

基于Colab训练的yolov4-tiny自定义数据集(可用于OpenCV For Unity)

参考资料文档和视频&#xff0c;Google colab、Goolge云端硬盘 1.打开文档&#xff0c;点击【文件】【在云端硬盘中保存一份副本】&#xff0c;即将文档复制到自己云端硬盘。 2.打开该文件&#xff0c;按文中提示进行。 【代码执行程序】【更改运行时类型】修改运行时为GPU&am…

学习JavaEE的日子 Day32 线程池

Day32 线程池 1.引入 一个线程完成一项任务所需时间为&#xff1a; 创建线程时间 - Time1线程中执行任务的时间 - Time2销毁线程时间 - Time3 2.为什么需要线程池(重要) 线程池技术正是关注如何缩短或调整Time1和Time3的时间&#xff0c;从而提高程序的性能。项目中可以把Time…

【文本】正则 | 正则表达式收录

1、匹配数字加右括号 1&#xff09;正则 \d\) 2&#xff09;效果 ~~

FPGA 图像边缘检测(Canny算子)

1 顶层代码 timescale 1ns / 1ps //边缘检测二阶微分算子&#xff1a;canny算子module image_canny_edge_detect (input clk,input reset, //复位高电平有效input [10:0] img_width,input [ 9:0] img_height,input [ 7:0] low_threshold,input [ 7:0] high_threshold,input va…

蓝桥杯23年第十四届省赛真题-填充|DFS,贪心

题目链接&#xff1a; 1.填充 - 蓝桥云课 (lanqiao.cn) 蓝桥杯2023年第十四届省赛真题-填充 - C语言网 (dotcpp.com) 说明&#xff1a; dfs就不再多说了&#xff0c;对于每个?都有0和1两个分支&#xff0c;数据范围是&#xff1a; 那么有m个 ?&#xff0c;时间复杂度就是…

C++初阶:2_类与对象(下)

类与对象(下) 一.再谈构造函数 1. 构造函数体赋值 在创建对象时&#xff0c;编译器通过调用构造函数&#xff0c;给对象中各个成员变量一个合适的初始值。 class Date { public:Date(int year, int month, int day){_year year;_month month;_day day;} private:int _ye…

38.网络游戏逆向分析与漏洞攻防-游戏网络通信数据解析-解码器类的优化调试

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 如果看不懂、不知道现在做的什么&#xff0c;那就跟着做完看效果 内容参考于&#xff1a;易道云信息技术研究院VIP课 上一个内容&#xff1a;37.解码器细化类…

“光学行业正被量子颠覆”——行业巨头齐聚,展示量子成果

OFC是全球最大的光网络和通信盛会&#xff0c;代表一系列产品&#xff0c;从光学元件和设备到系统、测试设备、软件和特种光纤&#xff0c;代表整个供应链&#xff0c;并提供业界学习、连接、建立网络和达成交易的首要市场&#xff0c;于2024年3月24日至28日在圣地亚哥会议中心…