赞
踩
在之前的四节中,我们尝试解决:
1,球员识别、足球识别、裁判识别;
2,队伍的分类
3,平面坐标的换算
存在关键的问题是:每一帧的画面,每次都是重新识别,无法将特定的人与坐标对应上。
我们需要知道每个球员、裁判的实时位置,并将实时位置记录对应到关键帧,能够通过世界坐标的变换,得到想要的足球参数。
利用对象跟踪,实现定人的实时追踪。
1)初始帧画面,利用对象检测识别球员、裁判、球,并生成编号便于跟踪。
2)利用CSRT实现多目标追踪,跟踪检测到的对象,确保不丢失。
3)设计简单的刷新算法,确保视频范围内人员进出画面进行新的目标检测。
4)探讨当跟踪丢失(如对象离开画面、人员重叠后的跟踪丢失)
Nuget Install OpenCvSharp4
Nuget Install OpenCvSharp4.Extensions
Nuget Install OpenCvSharp4.runtime.win
Nuget Install Numpy.Bare
其中OpenCvSharp包中,提供了类TrackerCSRT的实现。
CSRT概念性的内容需要大家翻阅数据,在此不再详述,本系列主要是实操内容。
internal class TrackerObject
{
public TrackerObject(Tracker tracker, YoloPrediction prediction)
{
Tracker = tracker;
Prediction = prediction;
}
public Tracker Tracker{ get;set;}
public Rect Rect { get;set;}
public YoloPrediction Prediction { get; set; }
}
该数据结构,将首次对象检测到的球员Bound,存储在YoloPrediction中。
因采用了多跟踪器的实现,所以每个球员、裁判、球对应一个Tracker对象。
public interface ITracker<T> : IDisposable
{
bool NeedFlush { get;}
public int MaxCount { get; set; }
void Init(List<T> detections, Mat frame);
List<T>? Update(Mat frame);
}
1, 对于人的跟踪,我们设计的简单的算法,假设视频首帧中检测到14人,其它球员在视频的视界范围外。存在以下情况:
1),新的人员跑进视界;
2),既有人员从视界中跑出去;
3),跟踪器丢失了跟踪。
算法中每格60帧重新对象检测,通过人员总数的变化率大于30%,则重设跟踪(已有跟踪没有进行鉴别)。
当触发了30%阈值情况,则NeedFlush标志为True;MaxCount用来定义视界中的人员总数。
2, 对于球的跟踪,仅适用于跟踪丢失的情况。
internal class MutiTrackerCV : ITracker<YoloPrediction> { private List<TrackerObject> trackers; private int MissCount=0; /// <summary> /// <inheritdoc/> /// </summary> public int MaxCount { get; set; } /// <summary> /// <inheritdoc/> /// </summary> public bool NeedFlush { get => MaxCount == 0 ? true : ((float)MissCount / MaxCount > 0.3); } public MutiTrackerCV() { trackers = new List<TrackerObject>(); } public void Dispose() { for (int i = 0; i < trackers?.Count; i++) { TrackerObject? tracker = trackers[i]; tracker.Tracker?.Dispose(); tracker = null; } } /// <summary> /// <inheritdoc/> /// </summary> public void Init(List<YoloPrediction> detections, Mat frame) { trackers = new List<TrackerObject>(); int i = 0; foreach (var d in detections) { i++; var tracker = TrackerCSRT.Create(); var rect = new Rect((int)d.Rectangle.X, (int)d.Rectangle.Y, (int)d.Rectangle.Width, (int)d.Rectangle.Height); tracker.Init(frame, rect); if (null != d.Label) d.Label = new YoloLabel() { Color = d.Label.Color, Kind = d.Label.Kind, Name = d.Label.Name, Id = i}; var trackerObject = new TrackerObject(tracker, d) { Rect = rect}; trackers?.Add(trackerObject); } MaxCount = trackers.Count; } /// <summary> /// <inheritdoc/> /// </summary> public List<YoloPrediction>? Update(Mat frame) { var missObjects = new List<TrackerObject>(); foreach (var tracker in trackers) { var rect = (Rect)tracker.Rect; var ismiss = tracker.Tracker?.Update(frame, ref rect); if (ismiss == null || ismiss == false) missObjects.Add(tracker); else tracker.Prediction.Rectangle = new System.Drawing.RectangleF(rect.X, rect.Y, rect.Width, rect.Height); } foreach (var tracker in missObjects) trackers.Remove(tracker); MissCount = missObjects.Count; return trackers?.Select(p => p.Prediction).ToList(); } }
其中,Tracker?.Update函数返回的是单个跟踪对象是否丢失的标志位。
当为false时说明跟踪对象丢失——例如白色的足球,滚动仅纯白色区域后。再出现时跟踪会丢失。
[Fact] public void TestPlayerTracker() { var detector = new DetectorYolov7(); var mutiTracker = new MutiTrackerCV(); var mats = LoadImages.LoadVideo("test.mp4"); int frameNumber = 0; //逐帧处理 foreach (var mat in mats) { if ((frameNumber % 60) == 0) { //目标检测 var predictions = detector.Detect(mat); var playerNumber = 1; //绘制对象Bound predictions.ForEach(item=> { //略...区分人、球 //略...原始视频CV绘制球员Bound //原始视频CV绘制球员号码 Cv2.PutText(mat, $"{item.Label?.Id}", new OpenCvSharp.Point(item.Rectangle.X, item.Rectangle.Y), HersheyFonts.HersheySimplex, 0.5, Scalar.AliceBlue, 1); //略...平面投影坐标点绘制,参见《足球视频AI(一)——位置与平面坐标的转换》 //略...平面投影球员号码绘制 playerNumber++; }); //跟踪人员 if (mutiTracker.NeedFlush || (predictions.Count > mutiTracker.MaxCount * 1.3)) mutiTracker.Init(predictions, mat); } //刷新跟踪 mutiTracker.Update(mat); frameNumber++; } Assert.True(mutiTracker?.MaxCount >0); }
通过目标跟踪的实现,确定球员、裁判、球三个要素的唯一性。
结合二维平面投影,记录顺时的位置,便可以统计相关的比赛数据。
其中,总移动距离、顺时速度、持球速度、传射、防守等换算信息,不是我们研究的重点,属于工程化问题。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。