using CSScripting;
using OpenCvSharp;
using OpenCvSharp.Extensions;
using OpenCvSharp.WpfExtensions;
using OxyPlot;
using OxyPlot.Axes;
using OxyPlot.Series;
using Prism.Commands;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
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 TeamAAS_VP.Core;
using TeamAAS_VP.Enums;
using TeamAAS_VP.Models;
namespace TeamAAS_VP.Controls
{
public partial class FocusAnalyzerControl : UserControl
{
private FocusAnalyzerViewModel ViewModel;
// 鼠标状态
private bool _isMouseDown = false;
private System.Windows.Point _mouseDownPoint;
public FocusAnalyzerControl()
{
InitializeComponent();
Loaded += OnLoaded;
}
private void OnLoaded(object sender, RoutedEventArgs e)
{
// 初始化ViewModel
if (DataContext == null)
DataContext = new FocusAnalyzerViewModel();
ViewModel=DataContext as FocusAnalyzerViewModel;
}
#region 鼠标事件处理
private void ImageDisplay_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (ViewModel == null) return;
_isMouseDown = true;
_mouseDownPoint = e.GetPosition(ImageDisplay);
// 处理ROI操作
if (ViewModel.CurrentRoi != null)
{
// 检查是否点击了ROI
if (ViewModel.StartRoiDrag(_mouseDownPoint))
{
CaptureMouse();
return;
}
}
// 开始绘制新ROI
if (ViewModel.RoiMode == RoiOperationMode.Draw)
{
ViewModel.StartRoiDrawing(_mouseDownPoint);
CaptureMouse();
}
}
private void ImageDisplay_MouseMove(object sender, MouseEventArgs e)
{
if (ViewModel == null || !_isMouseDown) return;
var currentPoint = e.GetPosition(ImageDisplay);
// 处理ROI拖动
if (ViewModel.RoiMode != RoiOperationMode.Draw && ViewModel.CurrentRoi != null)
{
ViewModel.UpdateRoiDrag(currentPoint);
UpdateRoiVisual();
}
// 处理ROI绘制
else if (ViewModel.RoiMode == RoiOperationMode.Draw)
{
ViewModel.UpdateRoiDrawing(currentPoint);
UpdateRoiVisual();
}
}
private void ImageDisplay_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (ViewModel == null || !_isMouseDown) return;
_isMouseDown = false;
ReleaseMouseCapture();
if (ViewModel.RoiMode == RoiOperationMode.Draw)
{
ViewModel.FinishRoiDrawing();
}
else
{
ViewModel.FinishRoiDrag();
}
}
#endregion
#region ROI可视化更新
private void UpdateRoiVisual()
{
if (ViewModel?.CurrentRoi == null) return;
// 更新ROI矩形位置和大小
Canvas.SetLeft(RoiRectangle, ViewModel.CurrentRoi.X);
Canvas.SetTop(RoiRectangle, ViewModel.CurrentRoi.Y);
RoiRectangle.Width = ViewModel.CurrentRoi.Width;
RoiRectangle.Height = ViewModel.CurrentRoi.Height;
// 更新控制点位置
UpdateRoiHandles();
}
private void UpdateRoiHandles()
{
if (ViewModel?.CurrentRoi == null) return;
var roi = ViewModel.CurrentRoi;
// 更新角点
UpdateHandlePosition(TopLeftHandle, roi.X, roi.Y);
UpdateHandlePosition(TopRightHandle, roi.X + roi.Width, roi.Y);
UpdateHandlePosition(BottomLeftHandle, roi.X, roi.Y + roi.Height);
UpdateHandlePosition(BottomRightHandle, roi.X + roi.Width, roi.Y + roi.Height);
// 更新边中点
UpdateHandlePosition(TopHandle, roi.X + roi.Width / 2, roi.Y);
UpdateHandlePosition(RightHandle, roi.X + roi.Width, roi.Y + roi.Height / 2);
UpdateHandlePosition(BottomHandle, roi.X + roi.Width / 2, roi.Y + roi.Height);
UpdateHandlePosition(LeftHandle, roi.X, roi.Y + roi.Height / 2);
// 更新旋转控制点
UpdateRotateHandlePosition(roi);
}
private void UpdateHandlePosition(FrameworkElement handle, double x, double y)
{
if (handle == null) return;
Canvas.SetLeft(handle, x - handle.Width / 2);
Canvas.SetTop(handle, y - handle.Height / 2);
}
private void UpdateRotateHandlePosition(RotatedRect roi)
{
if (RotateHandle == null) return;
// 旋转控制点在矩形顶部中心上方
double centerX = roi.X + roi.Width / 2;
double centerY = roi.Y + roi.Height / 2;
// 计算旋转后的位置
double angleRad = roi.Angle * Math.PI / 180;
double radius = Math.Max(roi.Width, roi.Height) / 2 + 20; // 距离中心20像素
double x = centerX + radius * Math.Sin(angleRad);
double y = centerY - radius * Math.Cos(angleRad);
// 设置位置
RotateHandle.RenderTransform = new RotateTransform(roi.Angle);
Canvas.SetLeft(RotateHandle, x - 5); // 5是三角形宽度的一半
Canvas.SetTop(RotateHandle, y - 5); // 5是三角形高度的一半
}
#endregion
#region 依赖属性
// CurrentImage依赖属性
public static readonly DependencyProperty CurrentImageProperty =
DependencyProperty.Register("CurrentImage", typeof(ImageSource), typeof(FocusAnalyzerControl),
new PropertyMetadata(null, OnCurrentImageChanged));
public ImageSource CurrentImage
{
get => (ImageSource)GetValue(CurrentImageProperty);
set => SetValue(CurrentImageProperty, value);
}
private static void OnCurrentImageChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = d as FocusAnalyzerControl;
if (control.ViewModel != null)
control.ViewModel.CurrentImage = e.NewValue as ImageSource;
}
// Parameters依赖属性
public static readonly DependencyProperty ParametersProperty =
DependencyProperty.Register("Parameters", typeof(AnalysisParameters), typeof(FocusAnalyzerControl),
new PropertyMetadata(new AnalysisParameters(), OnParametersChanged));
public AnalysisParameters Parameters
{
get => (AnalysisParameters)GetValue(ParametersProperty);
set => SetValue(ParametersProperty, value);
}
private static void OnParametersChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = d as FocusAnalyzerControl;
if (control.ViewModel != null)
control.ViewModel.Parameters = e.NewValue as AnalysisParameters;
}
// CurrentResult依赖属性
public static readonly DependencyProperty CurrentResultProperty =
DependencyProperty.Register("CurrentResult", typeof(AnalysisResult), typeof(FocusAnalyzerControl),
new PropertyMetadata(new AnalysisResult(), OnCurrentResultChanged));
public AnalysisResult CurrentResult
{
get => (AnalysisResult)GetValue(CurrentResultProperty);
set => SetValue(CurrentResultProperty, value);
}
private static void OnCurrentResultChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = d as FocusAnalyzerControl;
if (control.ViewModel != null)
control.ViewModel.CurrentResult = e.NewValue as AnalysisResult;
}
// StartAnalysisCommand依赖属性
public static readonly DependencyProperty StartAnalysisCommandProperty =
DependencyProperty.Register("StartAnalysisCommand", typeof(ICommand), typeof(FocusAnalyzerControl),
new PropertyMetadata(null, OnStartAnalysisCommandChanged));
public ICommand StartAnalysisCommand
{
get => (ICommand)GetValue(StartAnalysisCommandProperty);
set => SetValue(StartAnalysisCommandProperty, value);
}
private static void OnStartAnalysisCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = d as FocusAnalyzerControl;
if (control.ViewModel != null)
control.ViewModel.StartAnalysisCommand = e.NewValue as ICommand;
}
// 其他命令和属性的依赖属性...
#endregion
#region 公共方法
///
/// 处理图像帧
///
public async Task ProcessImageFrameAsync(OpenCvSharp.Mat frame)
{
if (ViewModel != null)
await ViewModel.ProcessImageFrameAsync(frame);
}
///
/// 执行单次分析
///
public void PerformAnalysis(OpenCvSharp.Mat frame)
{
ViewModel?.PerformAnalysis(frame);
}
///
/// 获取当前ROI区域
///
public OpenCvSharp.Rect? GetCurrentRoiRect()
{
if (ViewModel?.CurrentRoi == null)
return null;
return new OpenCvSharp.Rect(
(int)ViewModel.CurrentRoi.X,
(int)ViewModel.CurrentRoi.Y,
(int)ViewModel.CurrentRoi.Width,
(int)ViewModel.CurrentRoi.Height);
}
///
/// 获取旋转ROI
///
public OpenCvSharp.RotatedRect? GetCurrentRotatedRoi()
{
if (ViewModel?.CurrentRoi == null)
return null;
return ViewModel.CurrentRoi.ToCvRotatedRect();
}
#endregion
}
}