足球视频AI(二)——球员与球的目标检测

news2024/9/27 17:14:13

一、基础概念

在这里插入图片描述

1.1 识别目标:

1)固定机位的视频中球员逐帧识别

2)固定机位的视频中球逐帧识别

3)位置换算与记录

1.2 实现思路

1,利用OpenCV的相邻帧差异识别移动物体

2,利用YOLO7的机器学习识别对象,本文主要介绍YOLO7方案

二、代码实现

依赖项:

Nuget Install IVilson.AI.Yolov7net
Nuget Install OpenCvSharp4
Nuget Install OpenCvSharp4.Extensions
Nuget Install OpenCvSharp4.runtime.win
Nuget Install Numpy.Bare

2.1 接口定义

    public interface IDetector<T> :IDisposable
    {
        List<T> Detect(Mat mat);
    }

2.2 OpenCV实现

 public class DetectOpenCV : IDetector<YoloPrediction>
    {
        private readonly BackgroundSubtractorGMG fgbg;
        public DetectOpenCV()
        {
            fgbg = BackgroundSubtractorGMG.Create(5);
        }

        public event EventHandler<byte[]>? OnMiddelTime;

        /// <inheritdoc/>
        public List<YoloPrediction> Detect(Mat mat)
        {
            Point[][] contours;
            HierarchyIndex[] hierarchies;
            List<YoloPrediction> predictions;
            var topRows = (int)mat.Rows / 8;
            var midleRows = Convert.ToInt32(mat.Rows / 3.5);
            predictions = new List<YoloPrediction>();
            //高斯处理
            Cv2.GaussianBlur(mat, mat, new Size(13, 13), 0);
            //二值化
            var thresh = BackgroundSubtract(mat);
            OnMiddelTime?.Invoke(null, thresh.ToBytes());
            //视距最远端处理
            var k1 = np.array(new[,]{ {1, 1, 1, 1},
                    {1,1,1,1},
                    {1,1,1,1},
                    {0,1,1,0},
                    {0,1,1,0},
                    {1,1,1,1},
                    {1,1,1,1},
                    {1,1,1,1}}, np.uint8);
            var k1m = InputArray.Create(k1.GetData<int>(), MatType.CV_8U);
            var k2 = Mat.Ones(25, 15, MatType.CV_8UC1);
            var up_area = new Mat(thresh, new Rect(0, 0, thresh.Rows, topRows));
            Cv2.Erode(up_area, up_area, k1m);
            Cv2.Dilate(up_area, up_area, k2);
            //视距中间处理
            k1 = np.array(new[,]{ {1, 1, 1, 1},
                    {1,1,1,1},
                    {0,1,1,0},
                    {0,1,1,0},
                    {0,1,1,0},
                    {1,1,1,1}}, np.uint8);
            k1m = InputArray.Create(k1.GetData<int>(), MatType.CV_8U);
            k2 = Mat.Ones(30, 20, MatType.CV_8UC1);
            var middel_area = new Mat(thresh, new Rect(0, topRows, thresh.Rows, midleRows - topRows));
            Cv2.Erode(middel_area, middel_area, k1m);
            Cv2.Dilate(middel_area, middel_area, k2);

            //视距近景处理
            var down_area = new Mat(thresh, new Rect(0, midleRows, thresh.Rows, thresh.Height - midleRows));
            k2 = Mat.Ones(60, 30, MatType.CV_8UC1);
            Cv2.MorphologyEx(down_area, down_area, MorphTypes.Close, k2);
            //边缘检测
            Cv2.FindContours(thresh, out contours, out hierarchies, RetrievalModes.List, ContourApproximationModes.ApproxNone);
            //检测对象的转换
            var lable = new YoloLabel() { Id = 0, Kind = YoloLabelKind.Generic, Name = "person" };
            foreach (var c in contours)
            {
                var rect = Cv2.BoundingRect(c);
                if (rect.Width < 20 || rect.Height < 30)
                    continue;
                if (rect.Y >= midleRows && rect.Height <= 50)
                    continue;
                if (midleRows >= rect.Y && rect.Y >= topRows && rect.Height <= 35)
                    continue;

                var prediction = new YoloPrediction(lable);
                prediction.Rectangle = new System.Drawing.RectangleF(rect.X, rect.Y, rect.Width, rect.Height);
                predictions.Add(prediction);
            }
            return predictions;
        }

        /// <summary>
        /// 球场去背景
        /// </summary>
        /// <param name="frame"></param>
        public Mat BackgroundSubtract(Mat frame)
        {
            var fg = new Mat();
            fgbg.Apply(frame, fg);
            return fg;
        }

        public void Dispose()
        {
            fgbg?.Dispose();
        }
    }

调用目标检测

        [Fact]
        public void TestCVFindContours()
        {
            var detector = new DetectOpenCV();
            List<YoloPrediction> lst;
            using (var mat = LoadImages.Load("field_2.jpg"))
            {
                lst = detector.Detect(mat);
            }
            Assert.True(lst.Count > 0);
        }

2.3 YoloV7实现

https://github.com/WongKinYiu/yolov7

YOLOv7:可训练的免费赠品袋为实时物体检测器设置了新的最先进技术

2.3.1 编译yolov7-tiny.onnx

1, Github 源码下载到本地并安装Python环境。

2, 下载yolov7-tiny.pt

安装Visual Studio Code 开发工具
打开工具->文件->打开目录...  选择yolov7目录
      ->终端->新建终端
将下载的yolov7-tiny.pt 拷贝到yolov7根目录

按yolov7官网的说明,在新建的命令终端执行以下指令

python export.py --weights=yolov7.pt --grid --simplify

查看输出的yolov7-tiny.onnx 文件,拷贝到C#项目中

2.3.2 集成C#

    public class DetectorYolov7 : IDetector<YoloPrediction>
    {
        private readonly Yolov7 _yolo;
        public DetectorYolov7()
        {
            _yolo = new Yolov7(Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "Assets/yolov7-tiny.onnx"));
            _yolo.SetupYoloDefaultLabels();
        }

        /// <inheritdoc/>
        public List<YoloPrediction> Detect(Mat mat)
        {
            var items = _yolo.Predict(mat.ToBitmap());
            return items;
        }

        public void Dispose()
        {
            _yolo?.Dispose();
        }
    }

调用目标检测

        [Fact]
        public void TestYoloDetect()
        {
            var detector = new DetectorYolov7();
            List<YoloPrediction> lst;
            using (var mat = LoadImages.Load("field_2.jpg"))
            {
                lst = detector.Detect(mat);
            }
            Assert.True(lst.Count > 0);
        }

2.4 标记人或球

        /// <summary>
        /// 单个对象上画矩形框
        /// </summary>
        /// <param name="item"></param>
        /// <param name="image"></param>
        protected virtual void PlotBox(YoloPrediction item, Mat image)
        {
            var x = item.Rectangle.X;
            var y = item.Rectangle.Y;
            var width = item.Rectangle.Width;
            var height = item.Rectangle.Height;
            var lineSize = (int)Math.Floor((double)image.Cols / 1000);
            lineSize = lineSize <1 ? 1: lineSize;

            if (item.Label?.Name?.Equals("sports ball") == true)
                Cv2.Rectangle(image, new OpenCvSharp.Rect((int)Math.Floor(x), (int)Math.Floor(y), (int)Math.Floor(width), (int)Math.Floor(height)), Scalar.White, lineSize);
            else if (item.Label?.Name?.Equals("person") == true)
                Cv2.Rectangle(image, new OpenCvSharp.Rect((int)Math.Floor(x), (int)Math.Floor(y), (int)Math.Floor(width), (int)Math.Floor(height)), Scalar.Yellow, lineSize);
            else
                Cv2.Rectangle(image, new OpenCvSharp.Rect((int)Math.Floor(x), (int)Math.Floor(y), (int)Math.Floor(width), (int)Math.Floor(height)), Scalar.Green, lineSize);
            if (item.Label?.Id > 0)
                Cv2.PutText(image, $"{item.Label?.Id}", new OpenCvSharp.Point(x, y), HersheyFonts.HersheySimplex, 0.5, Scalar.AliceBlue, lineSize);
        }

三、总结

实际应用中,Yolov7的目标检测的优势:

1,在广角、侧面、固定机位的镜头下(如足球转播)效果比Opencv明显较好。

2,识别准确率高

劣势:

1,在无人机(高空人物非常小)效果不好,需要训练

2,在广角(鱼眼)效果不好,需要训练

3,在帧处理性能,尤其是CPU设备上处理能力较慢(300毫秒一帧),而GPU能达到30毫秒。

存在不足的地方是,高分辨率、远景的足球视频中,对于足球的识别非常不准确。

因此,后续我们介绍如何自训练Yolov7的模型。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LNPS递送辅料,DOPE,4004-05-1,二油酰磷脂酰乙醇胺

LNPS递送辅料&#xff0c;DOPE&#xff0c;4004-05-1&#xff0c;二油酰磷脂酰乙醇胺 中文名称 &#xff1a;1,2-二油酰-sn-甘油-3-磷酸乙醇胺 中文别称 &#xff1a;二油酰磷脂酰乙醇胺 英 文 名 &#xff1a;DOPE 英文别称 &#xff1a;1,2-Dioleoyl-sn-glycero-3-phospho…

数据仓库介绍

数据仓库数据仓库的概念数据仓库的主要特征数据仓库的主流开发语言-sql结构化数据sql语句数据仓库的概念 数据仓库&#xff08;英语&#xff1a;Data Warehouse&#xff0c;简称数仓、DW&#xff09;,是一个用于存储、分析、报告的数据系统。 数据仓库的目的是构建面向分析的集…

一、MyBatis-Plus简介

文章目录一、MyBatis-Plus简介1、简介2、特性3、支持数据库4、框架结构5、代码及文档地址【尚硅谷】MyBatisPlus教程-讲师&#xff1a;杨博超 失败&#xff0c;是正因你在距成功一步之遥的时候停住了脚步。 一、MyBatis-Plus简介 1、简介 MyBatis-Plus&#xff08;简称 MP&am…

吴恩达【神经网络和深度学习】Week2——神经网络基础

文章目录1、Logistic Regression as a Neural Network1.1、Binary Classification1.1.1、Introduction1.1.2、Notations1.2、Logistic Regression1.3、Logistic Regression Cost Function1.4、Gradient Descent1.5、Derivatives&#xff08;导数&#xff09;1.6、More derivati…

基于支持向量回归(SVR)和PROSAIL模拟光谱数据的叶面积指数反演

前言本博客利用PROSAIL模型模拟出MODIS的光谱数据和LAI&#xff0c;然后采用支持向量回归&#xff08;SVR&#xff09;方法建立NDVI与LAI 的回归模型&#xff0c;用于LAI的反演。训练和测试数据的拟合效果还是比较好的&#xff0c;这表明SVR在模拟的光谱数据与LAI回归方面的可行…

NXP EMDA学习(2):串口eDMA接收和发送流程详解

在单片机中&#xff0c;最基础的一个驱动就是串口&#xff0c;本文就以NXP中串口eDMA的收发为例&#xff0c;通过分析源代码来理解eDMA的执行过程。 参考代码&#xff1a;Kinetis K64 Sub-Family SDK 2.11中的uart_edma_transfer.c 文章目录1 串口基本初始化2 DMAMUX初始化3 初…

Go语言 WaitGroup 源码知多少

前面的文章我们写协程的时候有用到 WaitGroup 我们的写法大概是这样的 func main() {...dothing()wg : sync.WaitGroup{}// 控制 多个子协程的声明周期wg.Add(xx)for i : 0; i < xx; i {go func(ctx context.Context) {defer wg.Done()...dothing()}(ctx)}...dothing()// …

【Android春招】Android基础

一、填空题 1&#xff0e;Android是基于__ 的移动端开源操作系统。 Linux 2&#xff0e;Android系统是由__公司推出的。 谷歌 3&#xff0e;Android 11对应的API编号是__。 30 4&#xff0e;App除了在手机上运行&#xff0c;还能在电脑的__上运行。 模拟器&#xff08;AVD&…

Pytorch SoftMax回归

目录 数据集 从零实现 简单实现 数据集 导入所需库 torchvision计算机视觉所用torch的库 %matplotlib inline import torch import torchvision from torch.utils import data from torchvision import transforms from d2l import torch as d2l # 用SVG清晰度高 d2l.use_…

华为交换机OSPF对接思科交换机EIGRP,牛逼配置!

简介 思科交换机OSPF分别与华为交换机OSPF以及思科交换机EIGRP进行路由交互&#xff0c;间接实现华为交换机OSPF对接思科交换机EIGRP的功能。 配置注意事项 该案例适用于支持OSPF的华为交换机。该案例仅提供OSPF对接EIGRP的基本配置。思科交换机与华为交换机对接替换时&…

固定资产年结操作步骤 及常见问题处理:AJAB 关闭资产年度报错问题处理

目录 第一步、打开新的资产会计年度 TCODE &#xff1a; AJRW 第二步、 关闭资产年度 TCODE&#xff1a;AJAB 三、结果校验 四、 常见问题 分析 第一步、打开新的资产会计年度 TCODE &#xff1a; AJRW 输入公司编码&#xff0c;输入新的资产会计年度 先测试运行&a…

【计算机网络-数据链路层】差错控制(检错编码、纠错编码)

文章目录1 检错编码——奇偶校验码1.1 奇偶校验码1.2 相关例题2 检错编码——循环冗余码&#xff08;CRC&#xff09;2.1 发送端——生成冗余码2.2 接收端——检错2.3 相关例题3 纠错编码——海明码3.1 确定海明码的位数3.2 确定校验位的分布3.3 对校验码进行分组3.4 求出校验码…

LCHub:中国企业数字化门槛持续降低,数字化转型成本下降达80%

12月27日,钉钉联合中国信息通信研究院发布《“小快轻准”持续降低数字化转型门槛》研究报告(以下简称“报告”)。报告指出,中国企业数字化门槛正持续降低,数字化转型成本已降低80%;以钉钉为代表的数字平台,为中小企业提供了一条普惠、敏捷、低成本的数字化转型新路径;中国…

一种可远程监控的无线压力传感器

压力是工业生产中的重要参数之一&#xff0c;压力传感器是工业实践中最为常用的一种传感器。无线压力传感器TSM-04P是一款外接电源供电、具有无线通讯功能的高精度智能测压设备&#xff0c;采用4G通信方式&#xff0c;可选太阳能供电或电源供电。内置扩散硅传感器&#xff0c;能…

【java入门系列二】java基础

学习记录&#x1f914;变量&#xff08;小数计算为近似值&#xff09;运算符Scanner类接收输入进制位运算&#xff08;对补码进行操作再输出原码&#xff09;JavaAPI异常类型命名规范讨论总结谢谢点赞交流&#xff01;(❁◡❁)更多代码&#xff1a; Gitee主页&#xff1a;https…

Exynos_4412——ADC实验

目录 一、ADC简介 二、Exynos_4412下的ADC控制器 三、ADC寄存器详解 四、ADC编程 一、ADC简介 ADC(Analog to Digital Converter)即模数转换器&#xff0c;指一个能将模拟信号转化为数字信号的电子元件 对于CPU来说只能处理数字信号&#xff0c;而很多外围输入信号都是模拟…

CADD药物设计;QSAR模型

1、CADD药物设计 计算药物设计&#xff08;CADD&#xff09;是一个使用计算技术来帮助设计和开发新药的领域。它涉及使用计算机程序来模拟潜在药物分子与体内靶蛋白之间的相互作用&#xff0c;以及预测这些分子的性质和行为。这可以帮助研究人员识别新的药物候选物&#xff0c;…

STM32使用红外测温

红外测温 文章目录红外测温前言一、原理二、STM32代码1.MLX90614.c2.MLX90614.h总结前言 一、原理 红外测温的原理可以直接去看卖家的手册&#xff0c;手册多余的话太多了&#xff0c;知道他是IIC通信的就行了&#xff0c; 下面直接给出代码 二、STM32代码 1.MLX90614.c …

synchronzied

synchronzied的作用 原子性&#xff1a;所谓原子性就是一个操作或者多个操作&#xff0c;要么全部执行并且执行的过程不会被任何因素打断&#xff0c;要么都不执行。被synchronzied修饰的类或对象的所有操作都是原子的&#xff0c;因为在执行之前必须先获得类或对象的锁、直到…

直播运营|如何打造可复制的直播增长闭环?

作为当下最热门的营销模式&#xff0c;直播带货对人员、场地及流程的把控等都提出了严格要求。而要提升直播运营、促成更高转化&#xff0c;直播复盘是关键的一环。 那么&#xff0c;直播后到底该如何高效复盘&#xff0c;为带货提效呢&#xff1f; 「帷幄开播 Whale Cast」新功…