update:setting
This commit is contained in:
parent
9f56229c59
commit
45a365e695
19
Wpf_AiSportsMicrospace/Views/Setting/JumpSetting.xaml
Normal file
19
Wpf_AiSportsMicrospace/Views/Setting/JumpSetting.xaml
Normal file
@ -0,0 +1,19 @@
|
||||
<UserControl x:Class="Wpf_AiSportsMicrospace.Views.JumpSttting"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:Wpf_AiSportsMicrospace.MyUserControl"
|
||||
Loaded="Window_Loaded"
|
||||
mc:Ignorable="d" Width="1920" Height="1080">
|
||||
<Grid>
|
||||
<!-- 右侧视频预览 -->
|
||||
<Grid Background="Black">
|
||||
<Button Width="200" Height="30" TextBlock.FontSize="16" MouseLeftButtonDown="Ellipse_MouseLeftButtonDown" MouseLeftButtonUp="Ellipse_MouseLeftButtonUp">
|
||||
<TextBox Text="按钮"></TextBox>
|
||||
</Button>
|
||||
<Image x:Name="videoImage" Stretch="Uniform" />
|
||||
<Canvas x:Name="overlayCanvas" IsHitTestVisible="False" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
348
Wpf_AiSportsMicrospace/Views/Setting/JumpSetting.xaml.cs
Normal file
348
Wpf_AiSportsMicrospace/Views/Setting/JumpSetting.xaml.cs
Normal file
@ -0,0 +1,348 @@
|
||||
using AiSportsMicrospaceDB.DBContext;
|
||||
using Emgu.CV.Reg;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using SharpDX.Direct3D9;
|
||||
using SkiaSharp;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
using System.Windows.Threading;
|
||||
using Wpf_AiSportsMicrospace.Common;
|
||||
using Wpf_AiSportsMicrospace.Dto;
|
||||
using Yztob.AiSports.Inferences.Abstractions;
|
||||
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 Wpf_AiSportsMicrospace.Views
|
||||
{
|
||||
public partial class JumpSttting : UserControl
|
||||
{
|
||||
#region 私有成员
|
||||
private IHumanPredictor _humanPredictor;
|
||||
private IObjectDetector _objectDetector;
|
||||
private HumanGraphicsRenderer _humanGraphicsRenderer;
|
||||
private readonly List<SportDescriptor> _sports;
|
||||
private SportBase _sport;
|
||||
private readonly SportDetectionQueue _detectQueue;
|
||||
|
||||
private WriteableBitmap _videoBitmap;
|
||||
private int _lastFrameNumber = -1;
|
||||
|
||||
// 拖拽相关成员变量
|
||||
private bool _isDragging = false;
|
||||
private Ellipse? _draggingEllipse;
|
||||
private TextBlock? _draggingTextBlock;
|
||||
private Point _dragStartMousePos;
|
||||
private double _dragStartLeft;
|
||||
private double _dragStartTop;
|
||||
#endregion
|
||||
|
||||
public JumpSttting()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
_humanPredictor = HumanPredictorFactory.Create(HumanPredictorType.SingleHigh);
|
||||
_objectDetector = ObjectDetectorFactory.CreateSportGoodsDetector();
|
||||
_humanGraphicsRenderer = new HumanGraphicsRenderer();
|
||||
_humanGraphicsRenderer.DrawLabel = false;
|
||||
|
||||
_sports = SportBase.GetSports();
|
||||
|
||||
_detectQueue = new SportDetectionQueue();
|
||||
|
||||
// 确保在加载完成后绘制圆圈
|
||||
this.Loaded += (s, e) => DrawCirclesWithText();
|
||||
}
|
||||
|
||||
private void Window_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Application.Current.Dispatcher.InvokeAsync(() =>
|
||||
{
|
||||
DrawCirclesWithText();
|
||||
}, DispatcherPriority.Loaded);
|
||||
|
||||
videoImage.SizeChanged += (s, ev) =>
|
||||
{
|
||||
DrawCirclesWithText();
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 绘制可拖动的圆圈和位置文本
|
||||
/// </summary>
|
||||
private void DrawCirclesWithText()
|
||||
{
|
||||
if (overlayCanvas == null)
|
||||
{
|
||||
Debug.WriteLine("overlayCanvas 为空,无法绘制");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
overlayCanvas.Children.Clear();
|
||||
Debug.WriteLine($"Canvas 尺寸: {overlayCanvas.ActualWidth} x {overlayCanvas.ActualHeight}");
|
||||
|
||||
double imgWidth = overlayCanvas.ActualWidth;
|
||||
double imgHeight = overlayCanvas.ActualHeight;
|
||||
|
||||
// 如果实际尺寸为0,使用控件大小
|
||||
if (imgWidth <= 0 || imgHeight <= 0)
|
||||
{
|
||||
imgWidth = this.videoImage?.ActualWidth ?? 800;
|
||||
imgHeight = this.videoImage?.ActualHeight ?? 600;
|
||||
Debug.WriteLine($"使用备用尺寸: {imgWidth} x {imgHeight}");
|
||||
}
|
||||
|
||||
if (imgWidth <= 0 || imgHeight <= 0)
|
||||
{
|
||||
Debug.WriteLine("尺寸无效,跳过绘制");
|
||||
return;
|
||||
}
|
||||
|
||||
double radius = 50;
|
||||
int circleIndex = 1;
|
||||
|
||||
// 每个圆的位置:X 和 Y 都归一化 0~1
|
||||
var circlePositions = new List<(double XNorm, double YNorm)>
|
||||
{
|
||||
(0.1, 0.6),
|
||||
(0.3, 0.8),
|
||||
(0.5, 0.6),
|
||||
(0.7, 0.8),
|
||||
(0.9, 0.6)
|
||||
};
|
||||
|
||||
foreach (var pos in circlePositions)
|
||||
{
|
||||
double x = pos.XNorm * imgWidth;
|
||||
double y = pos.YNorm * imgHeight;
|
||||
|
||||
Debug.WriteLine($"创建第{circleIndex}个圆: 原始坐标 ({x:F0}, {y:F0})");
|
||||
|
||||
// 创建圆圈
|
||||
var ellipse = CreateDraggableEllipse(x, y, radius);
|
||||
|
||||
// 创建文本控件
|
||||
var textBlock = CreatePositionText(x, y, radius, circleIndex);
|
||||
|
||||
overlayCanvas.Children.Add(ellipse);
|
||||
overlayCanvas.Children.Add(textBlock);
|
||||
|
||||
circleIndex++;
|
||||
}
|
||||
|
||||
Debug.WriteLine($"成功绘制 {circleIndex - 1} 个可拖动圆圈");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine($"绘制圆圈时出错: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建可拖动的圆圈
|
||||
/// </summary>
|
||||
private Ellipse CreateDraggableEllipse(double centerX, double centerY, double radius)
|
||||
{
|
||||
var ellipse = new Ellipse
|
||||
{
|
||||
Width = radius * 2,
|
||||
Height = radius * 2,
|
||||
Opacity = 0.7,
|
||||
Fill = new SolidColorBrush(Colors.Blue),
|
||||
Stroke = new SolidColorBrush(Colors.Yellow),
|
||||
StrokeThickness = 3,
|
||||
Cursor = Cursors.Hand,
|
||||
Tag = "draggable_circle" // 添加标记便于识别
|
||||
};
|
||||
|
||||
Canvas.SetLeft(ellipse, centerX - radius);
|
||||
Canvas.SetTop(ellipse, centerY - radius);
|
||||
|
||||
// 添加鼠标事件处理程序
|
||||
ellipse.MouseLeftButtonDown += Ellipse_MouseLeftButtonDown;
|
||||
ellipse.MouseMove += Ellipse_MouseMove;
|
||||
ellipse.MouseLeftButtonUp += Ellipse_MouseLeftButtonUp;
|
||||
ellipse.MouseEnter += (s, e) => ellipse.Opacity = 0.9;
|
||||
ellipse.MouseLeave += (s, e) => ellipse.Opacity = _isDragging ? 1.0 : 0.7;
|
||||
|
||||
return ellipse;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建位置显示文本
|
||||
/// </summary>
|
||||
private TextBlock CreatePositionText(double centerX, double centerY, double radius, int circleIndex)
|
||||
{
|
||||
var textBlock = new TextBlock
|
||||
{
|
||||
Text = $"圆{circleIndex}: ({centerX:F0}, {centerY:F0})",
|
||||
Foreground = Brushes.Red,
|
||||
FontWeight = FontWeights.Bold,
|
||||
FontSize = 14,
|
||||
TextAlignment = TextAlignment.Center,
|
||||
Width = 150,
|
||||
Height = 25,
|
||||
Background = new SolidColorBrush(Color.FromArgb(180, 255, 255, 255)),
|
||||
Tag = $"text_for_circle_{circleIndex}"
|
||||
};
|
||||
|
||||
Canvas.SetLeft(textBlock, centerX - 75);
|
||||
Canvas.SetTop(textBlock, centerY - radius - 30);
|
||||
|
||||
return textBlock;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 鼠标按下事件:开始拖动
|
||||
/// </summary>
|
||||
private void Ellipse_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (sender is not Ellipse ellipse || overlayCanvas == null) return;
|
||||
|
||||
Debug.WriteLine("开始拖动圆圈");
|
||||
|
||||
_draggingEllipse = ellipse;
|
||||
_isDragging = true;
|
||||
_dragStartMousePos = e.GetPosition(overlayCanvas);
|
||||
_dragStartLeft = Canvas.GetLeft(ellipse);
|
||||
_dragStartTop = Canvas.GetTop(ellipse);
|
||||
|
||||
// 查找对应的文本控件
|
||||
_draggingTextBlock = FindCorrespondingTextBlock(ellipse);
|
||||
|
||||
ellipse.CaptureMouse();
|
||||
ellipse.Opacity = 1.0;
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找圆圈对应的文本控件
|
||||
/// </summary>
|
||||
private TextBlock? FindCorrespondingTextBlock(Ellipse ellipse)
|
||||
{
|
||||
double centerX = Canvas.GetLeft(ellipse) + ellipse.Width / 2;
|
||||
double centerY = Canvas.GetTop(ellipse) + ellipse.Height / 2;
|
||||
|
||||
// 查找距离圆圈中心最近的文本控件
|
||||
TextBlock? closestTextBlock = null;
|
||||
double minDistance = double.MaxValue;
|
||||
|
||||
foreach (var child in overlayCanvas.Children)
|
||||
{
|
||||
if (child is TextBlock textBlock)
|
||||
{
|
||||
double textX = Canvas.GetLeft(textBlock) + textBlock.Width / 2;
|
||||
double textY = Canvas.GetTop(textBlock) + textBlock.Height / 2;
|
||||
|
||||
double distance = Math.Sqrt(Math.Pow(textX - centerX, 2) + Math.Pow(textY - centerY, 2));
|
||||
|
||||
if (distance < minDistance)
|
||||
{
|
||||
minDistance = distance;
|
||||
closestTextBlock = textBlock;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return closestTextBlock;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 鼠标移动事件:拖动过程中更新位置
|
||||
/// </summary>
|
||||
private void Ellipse_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (!_isDragging || _draggingEllipse == null || overlayCanvas == null) return;
|
||||
|
||||
var currentPos = e.GetPosition(overlayCanvas);
|
||||
double dx = currentPos.X - _dragStartMousePos.X;
|
||||
double dy = currentPos.Y - _dragStartMousePos.Y;
|
||||
|
||||
double newLeft = _dragStartLeft + dx;
|
||||
double newTop = _dragStartTop + dy;
|
||||
|
||||
// 限制边界
|
||||
double maxLeft = overlayCanvas.ActualWidth - _draggingEllipse.Width;
|
||||
double maxTop = overlayCanvas.ActualHeight - _draggingEllipse.Height;
|
||||
newLeft = Math.Max(0, Math.Min(newLeft, maxLeft));
|
||||
newTop = Math.Max(0, Math.Min(newTop, maxTop));
|
||||
|
||||
// 更新圆圈位置
|
||||
Canvas.SetLeft(_draggingEllipse, newLeft);
|
||||
Canvas.SetTop(_draggingEllipse, newTop);
|
||||
|
||||
// 更新对应文本
|
||||
if (_draggingTextBlock != null)
|
||||
{
|
||||
double centerX = newLeft + _draggingEllipse.Width / 2;
|
||||
double centerY = newTop + _draggingEllipse.Height / 2;
|
||||
double radius = _draggingEllipse.Width / 2;
|
||||
|
||||
Canvas.SetLeft(_draggingTextBlock, centerX - 75);
|
||||
Canvas.SetTop(_draggingTextBlock, centerY - radius - 30);
|
||||
|
||||
// 更新文本内容
|
||||
_draggingTextBlock.Text = $"({centerX:F0}, {centerY:F0})";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 鼠标释放事件:结束拖动
|
||||
/// </summary>
|
||||
private void Ellipse_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (_draggingEllipse == null || overlayCanvas == null) return;
|
||||
|
||||
if (_isDragging)
|
||||
{
|
||||
_isDragging = false;
|
||||
_draggingEllipse.ReleaseMouseCapture();
|
||||
|
||||
double left = Canvas.GetLeft(_draggingEllipse);
|
||||
double top = Canvas.GetTop(_draggingEllipse);
|
||||
double centerX = left + _draggingEllipse.Width / 2;
|
||||
double centerY = top + _draggingEllipse.Height / 2;
|
||||
|
||||
Debug.WriteLine($"圆圈移动到坐标: X={centerX:F0}, Y={centerY:F0}");
|
||||
|
||||
// 显示完成标记
|
||||
if (_draggingTextBlock != null)
|
||||
{
|
||||
_draggingTextBlock.Text = $"({centerX:F0}, {centerY:F0}) ✓";
|
||||
|
||||
Task.Delay(2000).ContinueWith(t =>
|
||||
{
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
if (_draggingTextBlock != null)
|
||||
{
|
||||
_draggingTextBlock.Text = $"({centerX:F0}, {centerY:F0})";
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Debug.WriteLine("结束拖动圆圈");
|
||||
}
|
||||
|
||||
_draggingEllipse.Opacity = 0.7;
|
||||
_draggingEllipse = null;
|
||||
_draggingTextBlock = null;
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user