| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311 |
- 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 公共方法
- /// <summary>
- /// 处理图像帧
- /// </summary>
- public async Task ProcessImageFrameAsync(OpenCvSharp.Mat frame)
- {
- if (ViewModel != null)
- await ViewModel.ProcessImageFrameAsync(frame);
- }
- /// <summary>
- /// 执行单次分析
- /// </summary>
- public void PerformAnalysis(OpenCvSharp.Mat frame)
- {
- ViewModel?.PerformAnalysis(frame);
- }
- /// <summary>
- /// 获取当前ROI区域
- /// </summary>
- 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);
- }
- /// <summary>
- /// 获取旋转ROI
- /// </summary>
- public OpenCvSharp.RotatedRect? GetCurrentRotatedRoi()
- {
- if (ViewModel?.CurrentRoi == null)
- return null;
- return ViewModel.CurrentRoi.ToCvRotatedRect();
- }
- #endregion
- }
- }
|