Commit 8d12af08 by liulongfei

1. 视频控件添加手动校准插件

parent b6d7ca1a
...@@ -186,6 +186,10 @@ ...@@ -186,6 +186,10 @@
<Compile Include="SharpDx\WIC\WicBitmapHelper.cs" /> <Compile Include="SharpDx\WIC\WicBitmapHelper.cs" />
<Compile Include="SharpDx\WPF\D2dControl.cs" /> <Compile Include="SharpDx\WPF\D2dControl.cs" />
<Compile Include="SharpDx\WPF\Dx11ImageSource.cs" /> <Compile Include="SharpDx\WPF\Dx11ImageSource.cs" />
<Compile Include="VideoControl\Control\Plugin\ManualCorrection\EventArgs\ManualCorrectionClickEventArgs.cs" />
<Compile Include="VideoControl\Control\Plugin\ManualCorrection\ManualCorrectionExpand.cs" />
<Compile Include="VideoControl\Control\Plugin\ManualCorrection\Info\ManualCorrectionInfo.cs" />
<Compile Include="VideoControl\Control\Plugin\ManualCorrection\ManualCorrectionPlugin.cs" />
<Compile Include="VideoControl\Recording\VideoControlRecordingFrame.cs" /> <Compile Include="VideoControl\Recording\VideoControlRecordingFrame.cs" />
<Compile Include="VideoControl\Recording\VideoControlRecording.cs" /> <Compile Include="VideoControl\Recording\VideoControlRecording.cs" />
<Compile Include="VideoControl\Sync\IVideoControlSync.cs" /> <Compile Include="VideoControl\Sync\IVideoControlSync.cs" />
......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace VIZ.Framework.Common
{
/// <summary>
/// 手动校准点击事件参数
/// </summary>
public class ManualCorrectionClickEventArgs : EventArgs
{
/// <summary>
/// 鼠标点击位置
/// </summary>
public Point MousePoint { get; set; }
/// <summary>
/// 源坐标位置
/// </summary>
public Point SrcPoint { get; set; }
}
}
using SharpDX.Mathematics.Interop;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace VIZ.Framework.Common
{
/// <summary>
/// 手动校准信息
/// </summary>
public class ManualCorrectionInfo
{
/// <summary>
/// 填充颜色
/// </summary>
public RawColor4 FillColor { get; set; }
/// <summary>
/// 源半径
/// </summary>
public float SrcRadius { get; set; }
/// <summary>
/// 源中心点
/// </summary>
public RawVector2 SrcCenter { get; set; }
}
}
using SharpDX.Mathematics.Interop;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace VIZ.Framework.Common
{
/// <summary>
/// 手动校准扩展
/// </summary>
public static class ManualCorrectionExpand
{
/// <summary>
/// 更新手动校准区域
/// </summary>
/// <param name="videoControl">视频控件</param>
/// <param name="manualCorrectionInfo">手动校准区域</param>
public static void UpdateManualCorrection(this VideoControl videoControl, ManualCorrectionInfo manualCorrectionInfo)
{
if (videoControl.videoRender == null)
return;
ManualCorrectionPlugin plugin = videoControl.GetPlugin<ManualCorrectionPlugin>(VideoControlPluginNames.ManualCorrection);
if (plugin == null)
return;
plugin.Update(manualCorrectionInfo);
}
/// <summary>
/// 清理手动校准区域
/// </summary>
/// <param name="videoControl">视频控件</param>
public static void ClearManualCorrection(this VideoControl videoControl)
{
if (videoControl.videoRender == null)
return;
ManualCorrectionPlugin plugin = videoControl.GetPlugin<ManualCorrectionPlugin>(VideoControlPluginNames.ManualCorrection);
if (plugin == null)
return;
plugin.Update(null);
}
}
}
using log4net;
using SharpDX.Direct2D1;
using SharpDX.Mathematics.Interop;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VIZ.Framework.Core;
namespace VIZ.Framework.Common
{
/// <summary>
/// 手动校准插件
/// </summary>
public class ManualCorrectionPlugin : VideoPluginBase
{
/// <summary>
/// 日志
/// </summary>
private static readonly ILog log = LogManager.GetLogger(typeof(ManualCorrectionPlugin));
/// <summary>
/// 手动校准插件
/// </summary>
/// <param name="videoControl">视频控件</param>
public ManualCorrectionPlugin(VideoControl videoControl) : base(videoControl)
{
}
/// <summary>
/// 名称
/// </summary>
public override string Name => VideoControlPluginNames.ManualCorrection;
/// <summary>
/// 点击事件
/// </summary>
public event EventHandler<ManualCorrectionClickEventArgs> Click;
/// <summary>
/// 手动校准信息
/// </summary>
private volatile ManualCorrectionInfo manualCorrectionInfo;
/// <summary>
/// 更新数据
/// </summary>
/// <param name="manualCorrectionInfo">跟踪框信息</param>
public void Update(ManualCorrectionInfo manualCorrectionInfo)
{
this.manualCorrectionInfo = manualCorrectionInfo;
}
/// <summary>
/// 渲染
/// </summary>
/// <param name="context">渲染上下文</param>
public override void Render(VideoRenderContext context)
{
// 画面渲染区域
ManualCorrectionInfo info = this.manualCorrectionInfo;
if (info == null)
return;
SolidColorBrush brush = new SolidColorBrush(context.Target, info.FillColor);
RawVector2 center = ImageHelper.ConvertImagePointToUiPoint(context.VideoRenderInfo.Frame.Width, context.VideoRenderInfo.Frame.Height, context.VideoRenderInfo.DrawingRect, info.SrcCenter);
float radius = (float)ImageHelper.ConvertImageDistanceToUiDistanceUseX(context.VideoRenderInfo.Frame.Width, context.VideoRenderInfo.DrawingRect, info.SrcRadius);
Ellipse ellipse = new Ellipse(center, radius, radius);
context.Target.FillEllipse(ellipse, brush);
}
/// <summary>
/// 附加
/// </summary>
public override void Attach()
{
this.VideoRender.PreviewMouseLeftButtonDown -= VideoRender_PreviewMouseLeftButtonDown;
this.VideoRender.PreviewMouseLeftButtonDown += VideoRender_PreviewMouseLeftButtonDown;
}
/// <summary>
/// 卸载
/// </summary>
public override void Detach()
{
this.VideoRender.PreviewMouseLeftButtonDown -= VideoRender_PreviewMouseLeftButtonDown;
}
/// <summary>
/// 鼠标左键点击
/// </summary>
private void VideoRender_PreviewMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
if (!this.IsEnabled || this.Click == null)
return;
VideoRenderInfo renderInfo = this.VideoRender.RenderInfo;
if (renderInfo == null)
return;
ManualCorrectionClickEventArgs args = new ManualCorrectionClickEventArgs();
args.MousePoint = e.GetPosition(this.VideoRender);
args.SrcPoint = ImageHelper.ConvertUiPointToImagePoint(renderInfo.Frame.Width, renderInfo.Frame.Height, renderInfo.DrawingRect, args.MousePoint);
this.Click.Invoke(this, args);
}
}
}
\ No newline at end of file
...@@ -30,5 +30,10 @@ namespace VIZ.Framework.Common ...@@ -30,5 +30,10 @@ namespace VIZ.Framework.Common
/// 边线检测多边形 /// 边线检测多边形
/// </summary> /// </summary>
public const string SideCheckPolygon = "SideCheckPolygon"; public const string SideCheckPolygon = "SideCheckPolygon";
/// <summary>
/// 手动校准
/// </summary>
public const string ManualCorrection = "ManualCorrection";
} }
} }
...@@ -31,7 +31,7 @@ namespace VIZ.Framework.Common ...@@ -31,7 +31,7 @@ namespace VIZ.Framework.Common
/// <summary> /// <summary>
/// 是否正在保存 /// 是否正在保存
/// </summary> /// </summary>
public bool IsSaving { get; protected set; } public bool IsSaving { get; protected set; } = false;
/// <summary> /// <summary>
/// 录制帧队列 /// 录制帧队列
......
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
namespace VIZ.Framework.Core
{
/// <summary>
/// 字符串拼接转化器
/// </summary>
public class StringAppendConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
string v1 = value == null ? string.Empty : value.ToString();
string v2 = parameter == null ? string.Empty : parameter.ToString();
return v1 + v2;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
...@@ -147,6 +147,38 @@ namespace VIZ.Framework.Core ...@@ -147,6 +147,38 @@ namespace VIZ.Framework.Core
} }
/// <summary> /// <summary>
/// 将UI距离转化为图片距离,使用X轴比例
/// </summary>
/// <param name="imgWidth">图片宽度</param>
/// <param name="uiDrawRect">图片在UI的绘制区域</param>
/// <param name="distance">UI距离</param>
/// <returns>图片距离</returns>
public static double ConvertUiDistanceToImageDistanceUseX(int imgWidth, Rect uiDrawRect, double distance)
{
double xp = uiDrawRect.Width / imgWidth;
double destX = (distance - uiDrawRect.X) / xp;
return destX;
}
/// <summary>
/// 将UI距离转化为图片距离,使用Y轴比例
/// </summary>
/// <param name="imgHeight">图片高度</param>
/// <param name="uiDrawRect">图片在UI的绘制区域</param>
/// <param name="distance">UI距离</param>
/// <returns>图片距离</returns>
public static double ConvertUiDistanceToImageDistanceUseY(int imgHeight, Rect uiDrawRect, double distance)
{
double yp = uiDrawRect.Height / imgHeight;
double destY = (distance - uiDrawRect.Y) / yp;
return destY;
}
/// <summary>
/// 将图片坐标点转化为UI坐标点 /// 将图片坐标点转化为UI坐标点
/// </summary> /// </summary>
/// <param name="imgWidth">图片宽度</param> /// <param name="imgWidth">图片宽度</param>
...@@ -187,6 +219,38 @@ namespace VIZ.Framework.Core ...@@ -187,6 +219,38 @@ namespace VIZ.Framework.Core
} }
/// <summary> /// <summary>
/// 将图片距离转化为UI距离,使用X轴比例
/// </summary>
/// <param name="imgWidth">图片宽度</param>
/// <param name="uiDrawRect">图片在UI的绘制区域</param>
/// <param name="distance">图片距离</param>
/// <returns>UI距离</returns>
public static double ConvertImageDistanceToUiDistanceUseX(int imgWidth, Rect uiDrawRect, double distance)
{
double xp = uiDrawRect.Width / imgWidth;
double destX = distance * xp;
return destX;
}
/// <summary>
/// 将图片距离转化为UI距离,使用Y轴比例
/// </summary>
/// <param name="imgHeight">图片高度</param>
/// <param name="uiDrawRect">图片在UI的绘制区域</param>
/// <param name="distance">图片距离</param>
/// <returns>UI距离</returns>
public static double ConvertImageDistanceToUiDistanceUseY(int imgHeight, Rect uiDrawRect, double distance)
{
double yp = uiDrawRect.Height / imgHeight;
double destY = distance * yp;
return destY;
}
/// <summary>
/// 使用bottom矩形区域裁剪top矩形区域,使top矩形区域包括在bottom矩形区域内 /// 使用bottom矩形区域裁剪top矩形区域,使top矩形区域包括在bottom矩形区域内
/// </summary> /// </summary>
/// <param name="topRect">top矩形区域</param> /// <param name="topRect">top矩形区域</param>
......
...@@ -90,6 +90,7 @@ ...@@ -90,6 +90,7 @@
<Compile Include="Core\Converter\Bool2BoolConverter.cs" /> <Compile Include="Core\Converter\Bool2BoolConverter.cs" />
<Compile Include="Core\Converter\ByteSizeConverter.cs" /> <Compile Include="Core\Converter\ByteSizeConverter.cs" />
<Compile Include="Core\Converter\Bool2SolidColorBrushConverter.cs" /> <Compile Include="Core\Converter\Bool2SolidColorBrushConverter.cs" />
<Compile Include="Core\Converter\StringAppendConverter.cs" />
<Compile Include="Core\Enum\EnumHelper.cs" /> <Compile Include="Core\Enum\EnumHelper.cs" />
<Compile Include="Core\Helper\ByteHelper.cs" /> <Compile Include="Core\Helper\ByteHelper.cs" />
<Compile Include="Core\Helper\ProcessHelper.cs" /> <Compile Include="Core\Helper\ProcessHelper.cs" />
......
...@@ -81,7 +81,13 @@ namespace VIZ.Framework.Storage ...@@ -81,7 +81,13 @@ namespace VIZ.Framework.Storage
/// <summary> /// <summary>
/// 视频边线检测多边形区域透明度 /// 视频边线检测多边形区域透明度
/// </summary> /// </summary>
[Ini(Section = "Video", DefaultValue = "0.2", Type = typeof(double))] [Ini(Section = "Video", DefaultValue = "0.15", Type = typeof(double))]
public string VIDEO_SIDE_CHECK_POLYGON_OPACITY { get; set; } public string VIDEO_SIDE_CHECK_POLYGON_OPACITY { get; set; }
/// <summary>
/// 手动校准区域透明度
/// </summary>
[Ini(Section = "Video", DefaultValue = "0.2", Type = typeof(double))]
public string VIDEO_MANUAL_CORRECTION_OPACITY { get; set; }
} }
} }
...@@ -8,6 +8,6 @@ ...@@ -8,6 +8,6 @@
mc:Ignorable="d" WindowStartupLocation="CenterScreen" WindowState="Maximized" WindowStyle="None" mc:Ignorable="d" WindowStartupLocation="CenterScreen" WindowState="Maximized" WindowStyle="None"
Title="MainWindow" Height="800" Width="1200"> Title="MainWindow" Height="800" Width="1200">
<Grid> <Grid>
<local:Mouse3DTest></local:Mouse3DTest> <local:OpenCVVideoTest></local:OpenCVVideoTest>
</Grid> </Grid>
</Window> </Window>
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
<StackPanel Orientation="Horizontal" Grid.Row="1"> <StackPanel Orientation="Horizontal" Grid.Row="1">
<Button Margin="10,0,10,0" Width="120" Height="40" Content="图片测试" Click="Button_Click"></Button> <Button Margin="10,0,10,0" Width="120" Height="40" Content="图片测试" Click="Button_Click"></Button>
<Button Margin="10,0,10,0" Width="120" Height="40" Content="清理裁剪框" Click="Button_Click2"></Button> <Button Margin="10,0,10,0" Width="120" Height="40" Content="清理裁剪框" Click="Button_Click2"></Button>
<Button Margin="10,0,10,0" Width="120" Height="40" Content="手动校准测试" Click="Button_Click3"></Button>
</StackPanel> </StackPanel>
</Grid> </Grid>
</UserControl> </UserControl>
...@@ -42,10 +42,14 @@ namespace VIZ.Framework.WpfTest ...@@ -42,10 +42,14 @@ namespace VIZ.Framework.WpfTest
SideCheckPolygonPlugin sideCheckPolygonPlugin = new SideCheckPolygonPlugin(this.video); SideCheckPolygonPlugin sideCheckPolygonPlugin = new SideCheckPolygonPlugin(this.video);
sideCheckPolygonPlugin.Click += SideCheckPolygonPlugin_Click; sideCheckPolygonPlugin.Click += SideCheckPolygonPlugin_Click;
ManualCorrectionPlugin manualCorrectionPlugin = new ManualCorrectionPlugin(this.video);
manualCorrectionPlugin.Click += ManualCorrectionPlugin_Click;
this.video.AttachPlugin(trackingBoxPlugin); this.video.AttachPlugin(trackingBoxPlugin);
this.video.AttachPlugin(selectionBoxPlugin); this.video.AttachPlugin(selectionBoxPlugin);
this.video.AttachPlugin(clipBoxPlugin); this.video.AttachPlugin(clipBoxPlugin);
this.video.AttachPlugin(sideCheckPolygonPlugin); this.video.AttachPlugin(sideCheckPolygonPlugin);
this.video.AttachPlugin(manualCorrectionPlugin);
// 接入OpenCV插件 // 接入OpenCV插件
OpenCVStreamOption option = new OpenCVStreamOption(); OpenCVStreamOption option = new OpenCVStreamOption();
...@@ -99,6 +103,16 @@ namespace VIZ.Framework.WpfTest ...@@ -99,6 +103,16 @@ namespace VIZ.Framework.WpfTest
this.video.UpdateSideCheckPolygon(sideCheckPolygonInfos); this.video.UpdateSideCheckPolygon(sideCheckPolygonInfos);
} }
private void ManualCorrectionPlugin_Click(object sender, ManualCorrectionClickEventArgs e)
{
ManualCorrectionInfo info = new ManualCorrectionInfo();
info.FillColor = SharpDxColorHelper.FromString("#2200FF00");
info.SrcRadius = 200;
info.SrcCenter = new SharpDX.Mathematics.Interop.RawVector2(100, 100);
this.video.UpdateManualCorrection(info);
}
private void SideCheckPolygonPlugin_Click(object sender, SideCheckPolygonClickEventArgs e) private void SideCheckPolygonPlugin_Click(object sender, SideCheckPolygonClickEventArgs e)
{ {
Debug.WriteLine($"SideCheckPolygonPlugin_Click: [{e.MousePoint.X}, {e.MousePoint.Y}] [{e.SrcPoint.X}, {e.SrcPoint.Y}]"); Debug.WriteLine($"SideCheckPolygonPlugin_Click: [{e.MousePoint.X}, {e.MousePoint.Y}] [{e.SrcPoint.X}, {e.SrcPoint.Y}]");
...@@ -142,5 +156,13 @@ namespace VIZ.Framework.WpfTest ...@@ -142,5 +156,13 @@ namespace VIZ.Framework.WpfTest
{ {
this.video.ClearClipBox(); this.video.ClearClipBox();
} }
/// <summary>
/// 手动校准测试
/// </summary>
private void Button_Click3(object sender, RoutedEventArgs e)
{
}
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment