update:代码合并&函数修改
This commit is contained in:
commit
68078a2294
@ -113,8 +113,6 @@ public partial class MainWindow : Window
|
|||||||
//var ip = config.Ip;
|
//var ip = config.Ip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var host = this.host.Text.Trim();
|
var host = this.host.Text.Trim();
|
||||||
if (string.IsNullOrWhiteSpace(host))
|
if (string.IsNullOrWhiteSpace(host))
|
||||||
{
|
{
|
||||||
|
|||||||
@ -14,6 +14,7 @@ using System.Windows.Controls;
|
|||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using System.Windows.Media.Animation;
|
using System.Windows.Media.Animation;
|
||||||
|
using Views.JumpLong;
|
||||||
using Views.JumpRope;
|
using Views.JumpRope;
|
||||||
using Wpf_AiSportsMicrospace;
|
using Wpf_AiSportsMicrospace;
|
||||||
using Wpf_AiSportsMicrospace.Common;
|
using Wpf_AiSportsMicrospace.Common;
|
||||||
@ -150,7 +151,7 @@ namespace Wpf_AiSportsMicrospace
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var newPage = new TrainingRecords();
|
var newPage = new StandingLeap();
|
||||||
mainWin?.SwitchPageWithMaskAnimation(newPage, true);
|
mainWin?.SwitchPageWithMaskAnimation(newPage, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
15
Wpf_AiSportsMicrospace/Views/JumpLong/StandingLeap.xaml
Normal file
15
Wpf_AiSportsMicrospace/Views/JumpLong/StandingLeap.xaml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<UserControl x:Class="Views.JumpLong.StandingLeap"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:local="clr-namespace:Views.JumpLong"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
Height="1080" Width="1920" Loaded="UserControl_Loaded" Unloaded="UserControl_Unloaded">
|
||||||
|
<Grid>
|
||||||
|
<Grid Height="1080" Width="1920" x:Name="userBox">
|
||||||
|
<Label x:Name="sportCounts" Height="50" Width="200" HorizontalAlignment="Left" BorderBrush="Black" BorderThickness="2"></Label>
|
||||||
|
<Label x:Name="sportTimes" Height="50" Width="200" HorizontalAlignment="Center" BorderBrush="Black" BorderThickness="2" ></Label>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
||||||
257
Wpf_AiSportsMicrospace/Views/JumpLong/StandingLeap.xaml.cs
Normal file
257
Wpf_AiSportsMicrospace/Views/JumpLong/StandingLeap.xaml.cs
Normal file
@ -0,0 +1,257 @@
|
|||||||
|
using Dto;
|
||||||
|
using Enum;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Animation;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.Windows.Navigation;
|
||||||
|
using System.Windows.Shapes;
|
||||||
|
using Wpf_AiSportsMicrospace;
|
||||||
|
using Wpf_AiSportsMicrospace.Common;
|
||||||
|
using Wpf_AiSportsMicrospace.Enum;
|
||||||
|
using Wpf_AiSportsMicrospace.MyUserControl;
|
||||||
|
using Wpf_AiSportsMicrospace.Views;
|
||||||
|
using Yztob.AiSports.Inferences.Abstractions;
|
||||||
|
using Yztob.AiSports.Inferences.Implement;
|
||||||
|
using Yztob.AiSports.Inferences.Things;
|
||||||
|
using Yztob.AiSports.Postures.Sports;
|
||||||
|
using Yztob.AiSports.Postures.Things;
|
||||||
|
using Yztob.AiSports.Sensors.Abstractions;
|
||||||
|
using Yztob.AiSports.Sensors.Things;
|
||||||
|
|
||||||
|
namespace Views.JumpLong
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// StandingLeap.xaml 的交互逻辑
|
||||||
|
/// </summary>
|
||||||
|
public partial class StandingLeap : UserControl
|
||||||
|
{
|
||||||
|
#region 私有成员
|
||||||
|
private Main _mainWin => Application.Current.MainWindow as Main;
|
||||||
|
private IHumanPredictor _humanPredictor;
|
||||||
|
private IObjectDetector _objectDetector;
|
||||||
|
private HumanGraphicsRenderer _humanGraphicsRenderer;
|
||||||
|
private SportBase _sport;
|
||||||
|
private ApparatusLongJumpDelineation _measureApparatus;
|
||||||
|
private MediaPlayer _mediaPlayer = new MediaPlayer();
|
||||||
|
private readonly SportDetectionQueue _detectQueue;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public StandingLeap()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
Loaded += UserControl_Loaded;
|
||||||
|
Unloaded += UserControl_Unloaded;
|
||||||
|
|
||||||
|
_humanPredictor = HumanPredictorFactory.Create(HumanPredictorType.SingleHigh);
|
||||||
|
_humanGraphicsRenderer = new HumanGraphicsRenderer();
|
||||||
|
_humanGraphicsRenderer.DrawLabel = false;
|
||||||
|
_objectDetector = ObjectDetectorFactory.CreateSportGoodsDetector();
|
||||||
|
_detectQueue = new SportDetectionQueue();
|
||||||
|
|
||||||
|
_sport = SportBase.Create("standing-long-jump");
|
||||||
|
_sport.OnTicked += this.OnSportTick;
|
||||||
|
//if (_sport?.IsCounting == true)
|
||||||
|
_sport.Start();
|
||||||
|
|
||||||
|
_measureApparatus = new ApparatusLongJumpDelineation();
|
||||||
|
_measureApparatus.MeasureLength = 300;
|
||||||
|
var _isCalibrated = this.ReactangleCalibrating(1920, 1080);
|
||||||
|
_sport.MeasureApparatus = _measureApparatus;
|
||||||
|
|
||||||
|
_detectQueue.Sport = _sport;
|
||||||
|
_detectQueue.Start();
|
||||||
|
|
||||||
|
// 开始抽帧线程
|
||||||
|
_mainWin.FacialRecognitionEvent += HumanPredicting;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void UserControl_Loaded(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
// 播放音乐
|
||||||
|
PlayMusic("raisehand.mp3");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UserControl_Unloaded(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
_sport.Stop();
|
||||||
|
_humanPredictor?.Dispose();
|
||||||
|
_objectDetector?.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void HumanPredicting(VideoFrame frame)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var buffer = frame.GetImageBuffer(ImageFormat.Jpeg).ToArray();
|
||||||
|
var humanResult = await Task.Run<HumanInferenceResult>(() => _humanPredictor.Predicting(buffer, frame.Number));
|
||||||
|
var objects = _sport.Equipment ? await Task.Run<List<BoundingBox>>(() => _objectDetector.Detecting(buffer)) : new List<BoundingBox>();
|
||||||
|
if (_sport.MeasureApparatus != null)
|
||||||
|
objects.AddRange(_sport.MeasureApparatus.Apparatuses);
|
||||||
|
|
||||||
|
//运动需要保证时序
|
||||||
|
var human = humanResult?.Humans?.FirstOrDefault();
|
||||||
|
_detectQueue.Enqueue(frame.Number, human, objects);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine("ProcessFrame error: " + ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PlayMusic(string musicFileName)
|
||||||
|
{
|
||||||
|
// 获取项目根目录
|
||||||
|
string projectRoot = System.IO.Path.Combine(AppContext.BaseDirectory, @"..\..\..");
|
||||||
|
string musicPath = System.IO.Path.Combine(projectRoot, "Resources", "Music", musicFileName);
|
||||||
|
string imgPath = System.IO.Path.Combine(projectRoot, "Resources", "Img", "提示图.png");
|
||||||
|
|
||||||
|
if (!File.Exists(musicPath))
|
||||||
|
{
|
||||||
|
Console.WriteLine($"音乐文件不存在: {musicPath}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_mediaPlayer.Open(new Uri(musicPath, UriKind.Absolute));
|
||||||
|
|
||||||
|
ShowCenterTip(imgPath, TimeSpan.FromSeconds(3));
|
||||||
|
|
||||||
|
// 监听播放完成事件
|
||||||
|
_mediaPlayer.MediaEnded += MediaPlayer_MediaEnded;
|
||||||
|
//_mainWin.WebcamClient.StartExtract();
|
||||||
|
_mediaPlayer.Play();
|
||||||
|
}
|
||||||
|
private void ShowCenterTip(string imagePath, TimeSpan duration)
|
||||||
|
{
|
||||||
|
var tipImage = new Image
|
||||||
|
{
|
||||||
|
Source = new BitmapImage(new Uri(imagePath, UriKind.Absolute)),
|
||||||
|
HorizontalAlignment = HorizontalAlignment.Center,
|
||||||
|
VerticalAlignment = VerticalAlignment.Center,
|
||||||
|
Opacity = 0,
|
||||||
|
Margin = new Thickness(0, -100, 0, 0),
|
||||||
|
};
|
||||||
|
|
||||||
|
// 增加图片的大小,调整比例
|
||||||
|
tipImage.Width = 1920 * 0.9; // 宽度为 Canvas 宽度的 90%
|
||||||
|
tipImage.Height = 1080 * 0.6; // 高度为 Canvas 高度的 60%
|
||||||
|
|
||||||
|
// 将图片添加到 Overlay Canvas
|
||||||
|
userBox.Children.Add(tipImage);
|
||||||
|
|
||||||
|
// 渐变出现动画
|
||||||
|
var fadeInAnimation = new DoubleAnimation
|
||||||
|
{
|
||||||
|
From = 0,
|
||||||
|
To = 1,
|
||||||
|
Duration = TimeSpan.FromSeconds(1.5)
|
||||||
|
};
|
||||||
|
tipImage.BeginAnimation(UIElement.OpacityProperty, fadeInAnimation);
|
||||||
|
|
||||||
|
// 定时移除,并且渐变消失
|
||||||
|
Task.Delay(duration).ContinueWith(_ =>
|
||||||
|
{
|
||||||
|
Dispatcher.Invoke(() =>
|
||||||
|
{
|
||||||
|
// 渐变消失动画
|
||||||
|
var fadeOutAnimation = new DoubleAnimation
|
||||||
|
{
|
||||||
|
From = 1,
|
||||||
|
To = 0,
|
||||||
|
Duration = TimeSpan.FromSeconds(1.5)
|
||||||
|
};
|
||||||
|
tipImage.BeginAnimation(UIElement.OpacityProperty, fadeOutAnimation);
|
||||||
|
|
||||||
|
// 完成后移除图片
|
||||||
|
fadeOutAnimation.Completed += (s, e) =>
|
||||||
|
{
|
||||||
|
userBox.Children.Remove(tipImage);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
private void MediaPlayer_MediaEnded(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
// 音乐播放完成后的逻辑
|
||||||
|
Console.WriteLine("音乐播放完成!");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnSportTick(int counts, int times)
|
||||||
|
{
|
||||||
|
var ts = TimeSpan.FromSeconds(times);
|
||||||
|
Dispatcher.BeginInvoke(() =>
|
||||||
|
{
|
||||||
|
sportCounts.Content = _sport.GetFormatCounts(); //counts.ToString();
|
||||||
|
sportTimes.Content = _sport.GetFormatTimes();//ts.ToString(@"mm\'ss\""");
|
||||||
|
|
||||||
|
//触发停止
|
||||||
|
if (!_sport.IsCounting)
|
||||||
|
{
|
||||||
|
_sport.Stop();
|
||||||
|
_sport.Start();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
private bool ReactangleCalibrating(int frameWidth, int frameHeight)
|
||||||
|
{
|
||||||
|
var boxes = new List<BoundingBox>()
|
||||||
|
{
|
||||||
|
new BoundingBox(){
|
||||||
|
ImageWidth = frameWidth,
|
||||||
|
ImageHeight = frameHeight,
|
||||||
|
Label = new PredictionLabel(){
|
||||||
|
Key = "begin"
|
||||||
|
},
|
||||||
|
MaskLayer = new MaskLayer(){
|
||||||
|
Contours = new List<SixLabors.ImageSharp.PointF>(){
|
||||||
|
new SixLabors.ImageSharp.PointF(1722, 909),
|
||||||
|
new SixLabors.ImageSharp.PointF(1689, 724),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new BoundingBox(){
|
||||||
|
ImageWidth = frameWidth,
|
||||||
|
ImageHeight = frameHeight,
|
||||||
|
Label = new PredictionLabel{
|
||||||
|
Key = "end"
|
||||||
|
},
|
||||||
|
MaskLayer = new MaskLayer(){
|
||||||
|
Contours = new List<SixLabors.ImageSharp.PointF>(){
|
||||||
|
new SixLabors.ImageSharp.PointF(1516, 918),
|
||||||
|
new SixLabors.ImageSharp.PointF(1498, 730)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
boxes[1].Label.Key = "take-off";
|
||||||
|
boxes.Add(new BoundingBox()
|
||||||
|
{
|
||||||
|
ImageWidth = frameWidth,
|
||||||
|
ImageHeight = frameHeight,
|
||||||
|
Label = new PredictionLabel
|
||||||
|
{
|
||||||
|
Key = "end"
|
||||||
|
},
|
||||||
|
MaskLayer = new MaskLayer()
|
||||||
|
{
|
||||||
|
Contours = new List<SixLabors.ImageSharp.PointF>(){
|
||||||
|
new SixLabors.ImageSharp.PointF(191, 918),
|
||||||
|
new SixLabors.ImageSharp.PointF(245, 741)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return _measureApparatus.Calibrating(boxes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -40,6 +40,7 @@ using Yztob.AiSports.Inferences.Things;
|
|||||||
using Yztob.AiSports.Postures.Sports;
|
using Yztob.AiSports.Postures.Sports;
|
||||||
using Yztob.AiSports.Sensors.Abstractions;
|
using Yztob.AiSports.Sensors.Abstractions;
|
||||||
using Yztob.AiSports.Sensors.Things;
|
using Yztob.AiSports.Sensors.Things;
|
||||||
|
using static System.Formats.Asn1.AsnWriter;
|
||||||
|
|
||||||
namespace Wpf_AiSportsMicrospace.Views
|
namespace Wpf_AiSportsMicrospace.Views
|
||||||
{
|
{
|
||||||
@ -52,7 +53,6 @@ namespace Wpf_AiSportsMicrospace.Views
|
|||||||
private MediaPlayer _mediaPlayer = new MediaPlayer();
|
private MediaPlayer _mediaPlayer = new MediaPlayer();
|
||||||
List<RankItem> RankingItemList = new();
|
List<RankItem> RankingItemList = new();
|
||||||
|
|
||||||
private readonly SportDetectionQueue _detectQueue;
|
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||||
{
|
{
|
||||||
@ -62,18 +62,19 @@ namespace Wpf_AiSportsMicrospace.Views
|
|||||||
private readonly object _updateLock = new object();
|
private readonly object _updateLock = new object();
|
||||||
private readonly Dictionary<int, (string lastNumber, DateTime lastChangeTime, string currentState)> _jumpStatus = new Dictionary<int, (string, DateTime, string)>();
|
private readonly Dictionary<int, (string lastNumber, DateTime lastChangeTime, string currentState)> _jumpStatus = new Dictionary<int, (string, DateTime, string)>();
|
||||||
private GroupJumpRopeContext _groupJumpRopeContext;
|
private GroupJumpRopeContext _groupJumpRopeContext;
|
||||||
|
|
||||||
public GroupJumpRope()
|
public GroupJumpRope()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
_detectQueue = new SportDetectionQueue();
|
|
||||||
Loaded += UserControl_Loaded;
|
Loaded += UserControl_Loaded;
|
||||||
Unloaded += UserControl_Unloaded;
|
Unloaded += UserControl_Unloaded;
|
||||||
_groupJumpRopeContext = new GroupJumpRopeContext();
|
_groupJumpRopeContext = new GroupJumpRopeContext();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void UserControl_Loaded(object sender, RoutedEventArgs e)
|
private async void UserControl_Loaded(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
|
// 使用局部变量保存事件处理方法,以便解绑
|
||||||
|
Action<VideoFrame> handler = null;
|
||||||
|
|
||||||
var app = (App)Application.Current;
|
var app = (App)Application.Current;
|
||||||
using var scope = App.AppHost.Services.CreateScope();
|
using var scope = App.AppHost.Services.CreateScope();
|
||||||
@ -87,7 +88,6 @@ namespace Wpf_AiSportsMicrospace.Views
|
|||||||
(cfg.point5.X, cfg.point5.Y),(cfg.point6.X, cfg.point6.Y)];
|
(cfg.point5.X, cfg.point5.Y),(cfg.point6.X, cfg.point6.Y)];
|
||||||
_groupJumpRopeContext.CirclePositions = pointlist;
|
_groupJumpRopeContext.CirclePositions = pointlist;
|
||||||
|
|
||||||
|
|
||||||
DrawCirclesWithText();
|
DrawCirclesWithText();
|
||||||
|
|
||||||
// 播放音乐
|
// 播放音乐
|
||||||
@ -251,10 +251,11 @@ namespace Wpf_AiSportsMicrospace.Views
|
|||||||
Utils.PlayBackgroundMusic("countdown_3.mp3", false);
|
Utils.PlayBackgroundMusic("countdown_3.mp3", false);
|
||||||
|
|
||||||
//开始人脸识别=============================================
|
//开始人脸识别=============================================
|
||||||
EventHandler<byte[]> handler = null;
|
Action<VideoFrame> handler = null;
|
||||||
|
|
||||||
handler = async (sender, buffer) =>
|
handler = async (frame) =>
|
||||||
{
|
{
|
||||||
|
var buffer = frame.GetImageBuffer(ImageFormat.Jpeg).ToArray();
|
||||||
double[] xValues = [.. _groupJumpRopeContext.CirclePositions.Select(p => p.XNorm)];
|
double[] xValues = [.. _groupJumpRopeContext.CirclePositions.Select(p => p.XNorm)];
|
||||||
|
|
||||||
var studentList = Utils.FacialRecognition(buffer, xValues);
|
var studentList = Utils.FacialRecognition(buffer, xValues);
|
||||||
|
|||||||
@ -30,6 +30,7 @@ using Wpf_AiSportsMicrospace.Views;
|
|||||||
using WpfAnimatedGif;
|
using WpfAnimatedGif;
|
||||||
using Yztob.AiSports.Inferences.Things;
|
using Yztob.AiSports.Inferences.Things;
|
||||||
using Yztob.AiSports.Postures.Sports;
|
using Yztob.AiSports.Postures.Sports;
|
||||||
|
using Yztob.AiSports.Sensors.Things;
|
||||||
|
|
||||||
namespace Wpf_AiSportsMicrospace.Views.JumpRope
|
namespace Wpf_AiSportsMicrospace.Views.JumpRope
|
||||||
{
|
{
|
||||||
@ -244,12 +245,12 @@ namespace Wpf_AiSportsMicrospace.Views.JumpRope
|
|||||||
Utils.PlayBackgroundMusic("countdown_3.mp3", false);
|
Utils.PlayBackgroundMusic("countdown_3.mp3", false);
|
||||||
|
|
||||||
//开始人脸识别=============================================
|
//开始人脸识别=============================================
|
||||||
EventHandler<byte[]> handler = null;
|
Action<VideoFrame> handler = null;
|
||||||
|
|
||||||
handler = async (sender, buffer) =>
|
handler = async (frame) =>
|
||||||
{
|
{
|
||||||
double[] xValues = [.. _musicJumpRopeContext.CirclePositions.Select(p => p.XNorm)];
|
double[] xValues = [.. _musicJumpRopeContext.CirclePositions.Select(p => p.XNorm)];
|
||||||
|
var buffer = frame.GetImageBuffer(ImageFormat.Jpeg).ToArray();
|
||||||
var studentList = Utils.FacialRecognition(buffer, xValues);
|
var studentList = Utils.FacialRecognition(buffer, xValues);
|
||||||
|
|
||||||
if (studentList != null && studentList.Count > 0)
|
if (studentList != null && studentList.Count > 0)
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
|
|
||||||
|
using SharpDX.Direct3D9;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@ -38,7 +39,9 @@ namespace Wpf_AiSportsMicrospace.Views
|
|||||||
private readonly object _reconnectLock = new();
|
private readonly object _reconnectLock = new();
|
||||||
|
|
||||||
public event EventHandler<List<Human>> HumanFrameUpdated;
|
public event EventHandler<List<Human>> HumanFrameUpdated;
|
||||||
public event EventHandler<Byte[]> FacialRecognitionEvent;
|
|
||||||
|
public event Action<VideoFrame> FacialRecognitionEvent;
|
||||||
|
|
||||||
|
|
||||||
public Main()
|
public Main()
|
||||||
{
|
{
|
||||||
@ -106,14 +109,14 @@ namespace Wpf_AiSportsMicrospace.Views
|
|||||||
//if (frame.Number % 2 != 0)
|
//if (frame.Number % 2 != 0)
|
||||||
// return;
|
// return;
|
||||||
|
|
||||||
var buffer = frame.GetImageBuffer(ImageFormat.Jpeg).ToArray();
|
|
||||||
|
|
||||||
// 触发全局事件
|
// 触发全局事件
|
||||||
Application.Current.Dispatcher.BeginInvoke(() =>
|
Application.Current.Dispatcher.BeginInvoke(() =>
|
||||||
{
|
{
|
||||||
FacialRecognitionEvent?.Invoke(this, buffer);
|
FacialRecognitionEvent?.Invoke(frame);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
var buffer = frame.GetImageBuffer(ImageFormat.Jpeg).ToArray();
|
||||||
var humanResult = _humanPredictor.Predicting(buffer, frame.Number);
|
var humanResult = _humanPredictor.Predicting(buffer, frame.Number);
|
||||||
|
|
||||||
var humans = humanResult?.Humans?.ToList();
|
var humans = humanResult?.Humans?.ToList();
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@ -6,7 +6,7 @@
|
|||||||
<members>
|
<members>
|
||||||
<member name="T:Yztob.AiSports.Postures.Abstractions.ICalculator">
|
<member name="T:Yztob.AiSports.Postures.Abstractions.ICalculator">
|
||||||
<summary>
|
<summary>
|
||||||
人体姿态计算检测执行器
|
人体姿态检测规则执行计算器
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
<member name="P:Yztob.AiSports.Postures.Abstractions.ICalculator.PointThreshold">
|
<member name="P:Yztob.AiSports.Postures.Abstractions.ICalculator.PointThreshold">
|
||||||
@ -727,6 +727,17 @@
|
|||||||
一些扩展方法
|
一些扩展方法
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:Yztob.AiSports.Postures.Extensions.GravityLine(Yztob.AiSports.Inferences.Things.Human)">
|
||||||
|
<summary>
|
||||||
|
获取当前<seealso cref="T:Yztob.AiSports.Inferences.Things.Human"/>的人体重力线
|
||||||
|
</summary>
|
||||||
|
<param name="human">要计算的人体</param>
|
||||||
|
<returns>
|
||||||
|
返回重力线的上、下起点
|
||||||
|
[0]-为线的上端点
|
||||||
|
[1]-为线的下端点
|
||||||
|
</returns>
|
||||||
|
</member>
|
||||||
<member name="M:Yztob.AiSports.Postures.Extensions.AsPointF(Yztob.AiSports.Inferences.Things.Keypoint)">
|
<member name="M:Yztob.AiSports.Postures.Extensions.AsPointF(Yztob.AiSports.Inferences.Things.Keypoint)">
|
||||||
<summary>
|
<summary>
|
||||||
以<paramref name="keypoint"/>坐标值转换成<seealso cref="T:System.Drawing.PointF"/>
|
以<paramref name="keypoint"/>坐标值转换成<seealso cref="T:System.Drawing.PointF"/>
|
||||||
@ -734,6 +745,13 @@
|
|||||||
<param name="keypoint">要转换的关键点</param>
|
<param name="keypoint">要转换的关键点</param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:Yztob.AiSports.Postures.Extensions.ToCenterPoint(System.Collections.Generic.IEnumerable{Yztob.AiSports.Inferences.Things.Keypoint})">
|
||||||
|
<summary>
|
||||||
|
获取当前关键点集中的中心点位置
|
||||||
|
</summary>
|
||||||
|
<param name="keypoints">关键点集</param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
<member name="T:Yztob.AiSports.Postures.Implement.Calculator">
|
<member name="T:Yztob.AiSports.Postures.Implement.Calculator">
|
||||||
<summary>
|
<summary>
|
||||||
人体姿态计算检测执行器
|
人体姿态计算检测执行器
|
||||||
@ -1326,6 +1344,70 @@
|
|||||||
</summary>
|
</summary>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="T:Yztob.AiSports.Postures.PostureUtility">
|
||||||
|
<summary>
|
||||||
|
姿态分析相关工具函数集
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:Yztob.AiSports.Postures.PostureUtility.GetBodyKeyNameMaps">
|
||||||
|
<summary>
|
||||||
|
获取身体关键点键-名映射字典
|
||||||
|
</summary>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:Yztob.AiSports.Postures.PostureUtility.GetCameraViewName(Yztob.AiSports.Postures.Things.CameraViews)">
|
||||||
|
<summary>
|
||||||
|
获取相机视角名称
|
||||||
|
</summary>
|
||||||
|
<param name="view">当前视角</param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:Yztob.AiSports.Postures.PostureUtility.Angle(System.Nullable{System.Drawing.PointF},System.Nullable{System.Drawing.PointF},System.Nullable{System.Drawing.PointF})">
|
||||||
|
<summary>
|
||||||
|
计算平面三个点的角度
|
||||||
|
</summary>
|
||||||
|
<param name="center">角度点</param>
|
||||||
|
<param name="second">上角点</param>
|
||||||
|
<param name="third">下角点</param>
|
||||||
|
<returns>
|
||||||
|
-1至少一个有一个坐标点是空的;否则返回计算角度;
|
||||||
|
</returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:Yztob.AiSports.Postures.PostureUtility.Angle(Yztob.AiSports.Inferences.Things.Keypoint,Yztob.AiSports.Inferences.Things.Keypoint,Yztob.AiSports.Inferences.Things.Keypoint)">
|
||||||
|
<summary>
|
||||||
|
计算三个人体关键点角度
|
||||||
|
</summary>
|
||||||
|
<param name="center">角度人体关键点</param>
|
||||||
|
<param name="second">上角人体关键点</param>
|
||||||
|
<param name="third">下角人体关键点</param>
|
||||||
|
<returns>
|
||||||
|
计算后的角度
|
||||||
|
</returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:Yztob.AiSports.Postures.PostureUtility.AssertAngle(System.Single,System.Single,System.Single)">
|
||||||
|
<summary>
|
||||||
|
断言<paramref name="angle"/>是否有<paramref name="expect"/>匹配
|
||||||
|
</summary>
|
||||||
|
<param name="angle">实际测量的角度</param>
|
||||||
|
<param name="expect">期望的角度</param>
|
||||||
|
<param name="offset">允许的偏差</param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:Yztob.AiSports.Postures.PostureUtility.IoU(Yztob.AiSports.Inferences.Things.BoundingBox,Yztob.AiSports.Inferences.Things.BoundingBox)">
|
||||||
|
<summary>
|
||||||
|
计算两个边界框的交并比
|
||||||
|
</summary>
|
||||||
|
<param name="box1">框1</param>
|
||||||
|
<param name="box2">框2</param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:Yztob.AiSports.Postures.PostureUtility.CenterPoint(System.Collections.Generic.IEnumerable{Yztob.AiSports.Inferences.Things.Keypoint})">
|
||||||
|
<summary>
|
||||||
|
计算多个关键点之间的中心点位置
|
||||||
|
</summary>
|
||||||
|
<param name="keypoints">关键点集</param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
<member name="T:Yztob.AiSports.Postures.Sports.CounterTicked">
|
<member name="T:Yztob.AiSports.Postures.Sports.CounterTicked">
|
||||||
<summary>
|
<summary>
|
||||||
运动计数器计数变化委托
|
运动计数器计数变化委托
|
||||||
@ -1752,6 +1834,9 @@
|
|||||||
获取或设置垫子长度,单位cm
|
获取或设置垫子长度,单位cm
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:Yztob.AiSports.Postures.Sports.SportStandingLongJump.Pushing(Yztob.AiSports.Inferences.Things.Human)">
|
||||||
|
<inheritdoc />
|
||||||
|
</member>
|
||||||
<member name="M:Yztob.AiSports.Postures.Sports.SportStandingLongJump.Pushing(Yztob.AiSports.Inferences.Things.Human,System.Collections.Generic.IEnumerable{Yztob.AiSports.Inferences.Things.BoundingBox})">
|
<member name="M:Yztob.AiSports.Postures.Sports.SportStandingLongJump.Pushing(Yztob.AiSports.Inferences.Things.Human,System.Collections.Generic.IEnumerable{Yztob.AiSports.Inferences.Things.BoundingBox})">
|
||||||
<inheritdoc />
|
<inheritdoc />
|
||||||
</member>
|
</member>
|
||||||
@ -2335,63 +2420,6 @@
|
|||||||
<param name="trend">当前势</param>
|
<param name="trend">当前势</param>
|
||||||
<param name="isChanged">趋势是否变化</param>
|
<param name="isChanged">趋势是否变化</param>
|
||||||
</member>
|
</member>
|
||||||
<member name="T:Yztob.AiSports.Postures.Utility">
|
|
||||||
<summary>
|
|
||||||
姿态分析相关工具函数集
|
|
||||||
</summary>
|
|
||||||
</member>
|
|
||||||
<member name="M:Yztob.AiSports.Postures.Utility.GetBodyKeyNameMaps">
|
|
||||||
<summary>
|
|
||||||
获取身体关键点键-名映射字典
|
|
||||||
</summary>
|
|
||||||
<returns></returns>
|
|
||||||
</member>
|
|
||||||
<member name="M:Yztob.AiSports.Postures.Utility.GetCameraViewName(Yztob.AiSports.Postures.Things.CameraViews)">
|
|
||||||
<summary>
|
|
||||||
获取相机视角名称
|
|
||||||
</summary>
|
|
||||||
<param name="view">当前视角</param>
|
|
||||||
<returns></returns>
|
|
||||||
</member>
|
|
||||||
<member name="M:Yztob.AiSports.Postures.Utility.Angle(System.Nullable{System.Drawing.PointF},System.Nullable{System.Drawing.PointF},System.Nullable{System.Drawing.PointF})">
|
|
||||||
<summary>
|
|
||||||
计算平面三个点的角度
|
|
||||||
</summary>
|
|
||||||
<param name="center">角度点</param>
|
|
||||||
<param name="second">上角点</param>
|
|
||||||
<param name="third">下角点</param>
|
|
||||||
<returns>
|
|
||||||
-1至少一个有一个坐标点是空的;否则返回计算角度;
|
|
||||||
</returns>
|
|
||||||
</member>
|
|
||||||
<member name="M:Yztob.AiSports.Postures.Utility.Angle(Yztob.AiSports.Inferences.Things.Keypoint,Yztob.AiSports.Inferences.Things.Keypoint,Yztob.AiSports.Inferences.Things.Keypoint)">
|
|
||||||
<summary>
|
|
||||||
计算三个人体关键点角度
|
|
||||||
</summary>
|
|
||||||
<param name="center">角度人体关键点</param>
|
|
||||||
<param name="second">上角人体关键点</param>
|
|
||||||
<param name="third">下角人体关键点</param>
|
|
||||||
<returns>
|
|
||||||
计算后的角度
|
|
||||||
</returns>
|
|
||||||
</member>
|
|
||||||
<member name="M:Yztob.AiSports.Postures.Utility.AssertAngle(System.Single,System.Single,System.Single)">
|
|
||||||
<summary>
|
|
||||||
断言<paramref name="angle"/>是否有<paramref name="expect"/>匹配
|
|
||||||
</summary>
|
|
||||||
<param name="angle">实际测量的角度</param>
|
|
||||||
<param name="expect">期望的角度</param>
|
|
||||||
<param name="offset">允许的偏差</param>
|
|
||||||
<returns></returns>
|
|
||||||
</member>
|
|
||||||
<member name="M:Yztob.AiSports.Postures.Utility.IoU(Yztob.AiSports.Inferences.Things.BoundingBox,Yztob.AiSports.Inferences.Things.BoundingBox)">
|
|
||||||
<summary>
|
|
||||||
计算两个边界框的交并比
|
|
||||||
</summary>
|
|
||||||
<param name="box1">框1</param>
|
|
||||||
<param name="box2">框2</param>
|
|
||||||
<returns></returns>
|
|
||||||
</member>
|
|
||||||
<member name="T:Yztob.AiSports.Common.Licenses.FeatureCpuPartMap">
|
<member name="T:Yztob.AiSports.Common.Licenses.FeatureCpuPartMap">
|
||||||
<summary>
|
<summary>
|
||||||
表示受权机器CPU部件特性图
|
表示受权机器CPU部件特性图
|
||||||
|
|||||||
Binary file not shown.
@ -111,6 +111,12 @@
|
|||||||
<member name="M:Yztob.AiSports.Sensors.WinForm.RTSPPreview.Dispose">
|
<member name="M:Yztob.AiSports.Sensors.WinForm.RTSPPreview.Dispose">
|
||||||
<inheritdoc />
|
<inheritdoc />
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:Yztob.AiSports.Sensors.WinForm.RTSPPreview.Pushing(Yztob.AiSports.Sensors.Things.VideoFrameWithBuffer)">
|
||||||
|
<summary>
|
||||||
|
直接向预览器推送帧,进行预览回放
|
||||||
|
</summary>
|
||||||
|
<param name="frame">帧图像</param>
|
||||||
|
</member>
|
||||||
<member name="M:Yztob.AiSports.Sensors.WinForm.RTSPPreview.Play">
|
<member name="M:Yztob.AiSports.Sensors.WinForm.RTSPPreview.Play">
|
||||||
<summary>
|
<summary>
|
||||||
启动抽帧/预览
|
启动抽帧/预览
|
||||||
|
|||||||
Binary file not shown.
@ -218,12 +218,13 @@
|
|||||||
视频流解码器
|
视频流解码器
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
<member name="M:Yztob.AiSports.Sensors.Implement.VideoStreamDecoder.#ctor(System.String,FFmpeg.AutoGen.Abstractions.AVHWDeviceType)">
|
<member name="M:Yztob.AiSports.Sensors.Implement.VideoStreamDecoder.#ctor(System.String,FFmpeg.AutoGen.Abstractions.AVHWDeviceType,System.Int32)">
|
||||||
<summary>
|
<summary>
|
||||||
初始化解码器
|
初始化解码器
|
||||||
</summary>
|
</summary>
|
||||||
<param name="url">设备访问url</param>
|
<param name="url">设备访问url</param>
|
||||||
<param name="HWDeviceType">硬件设备类型</param>
|
<param name="HWDeviceType">硬件设备类型</param>
|
||||||
|
<param name="timeout">视频连接超时是间</param>
|
||||||
</member>
|
</member>
|
||||||
<member name="P:Yztob.AiSports.Sensors.Implement.VideoStreamDecoder.CodecName">
|
<member name="P:Yztob.AiSports.Sensors.Implement.VideoStreamDecoder.CodecName">
|
||||||
<summary>
|
<summary>
|
||||||
@ -307,9 +308,21 @@
|
|||||||
获取FFmpeg原始帧
|
获取FFmpeg原始帧
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="P:Yztob.AiSports.Sensors.Things.VideoFrame.PresentTimestamp">
|
||||||
|
<summary>
|
||||||
|
获取或设置帧相对流开始的展示时间戳,单位:秒
|
||||||
|
</summary>
|
||||||
|
<remarks>通俗的理解便是,此帧在视频的第几秒出现的</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="P:Yztob.AiSports.Sensors.Things.VideoFrame.PreserveDuration">
|
||||||
|
<summary>
|
||||||
|
获取或设置上一帧距离这帧维持的时长
|
||||||
|
</summary>
|
||||||
|
<remarks>即用当帧的<see cref="P:Yztob.AiSports.Sensors.Things.VideoFrame.PresentTimestamp"/>减去上一帧的<see cref="P:Yztob.AiSports.Sensors.Things.VideoFrame.PresentTimestamp"/></remarks>
|
||||||
|
</member>
|
||||||
<member name="P:Yztob.AiSports.Sensors.Things.VideoFrame.Timestamp">
|
<member name="P:Yztob.AiSports.Sensors.Things.VideoFrame.Timestamp">
|
||||||
<summary>
|
<summary>
|
||||||
获取或设置时间戳,从UTC:2000-01-01开始的耗秒数
|
获取或设置帧提取时的系统时间戳,从UTC:2000-01-01开始的耗秒数
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
<member name="M:Yztob.AiSports.Sensors.Things.VideoFrame.GetTimestamp">
|
<member name="M:Yztob.AiSports.Sensors.Things.VideoFrame.GetTimestamp">
|
||||||
@ -365,6 +378,18 @@
|
|||||||
获取FFmpeg原始帧
|
获取FFmpeg原始帧
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="P:Yztob.AiSports.Sensors.Things.VideoFrameWithBuffer.PresentTimestamp">
|
||||||
|
<summary>
|
||||||
|
获取或设置帧相对流开始的展示时间戳,单位:秒
|
||||||
|
</summary>
|
||||||
|
<remarks>通俗的理解便是,此帧在视频的第几秒出现的</remarks>
|
||||||
|
</member>
|
||||||
|
<member name="P:Yztob.AiSports.Sensors.Things.VideoFrameWithBuffer.PreserveDuration">
|
||||||
|
<summary>
|
||||||
|
获取或设置上一帧距离这帧维持的时长
|
||||||
|
</summary>
|
||||||
|
<remarks>即用当帧的<see cref="P:Yztob.AiSports.Sensors.Things.VideoFrameWithBuffer.PresentTimestamp"/>减去上一帧的<see cref="P:Yztob.AiSports.Sensors.Things.VideoFrameWithBuffer.PresentTimestamp"/></remarks>
|
||||||
|
</member>
|
||||||
<member name="P:Yztob.AiSports.Sensors.Things.VideoFrameWithBuffer.Timestamp">
|
<member name="P:Yztob.AiSports.Sensors.Things.VideoFrameWithBuffer.Timestamp">
|
||||||
<summary>
|
<summary>
|
||||||
获取或设置时间戳,从UTC:2000-01-01开始的耗秒数
|
获取或设置时间戳,从UTC:2000-01-01开始的耗秒数
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user