C# 调用 Emgu.CV 显示RTSP流 + 设置程序运行超时时间
来源:互联网 发布:淘宝上什么祛痘产品好 编辑:程序博客网 时间:2024/05/20 07:15
1.后台代码
using Caliburn.Micro;using Emgu.CV;using System;using System.Collections.Generic;using System.Collections.ObjectModel;using System.Linq;using System.Text;using System.Threading;using System.Threading.Tasks;using System.Windows;using System.Windows.Media;using System.Windows.Media.Imaging;namespace WpfMyCapture{ public class MainViewModel:PropertyChangedBase { object lockObj = new object(); private int ImgNum = 6; string url1 = "rtsp://admin:admin123@192.168.1.93:554/Streaming/Channels/102?transportmode=unicast&profile=Profile_1"; public MainViewModel() { CvInvoke.UseOpenCL = false; } public void MainLoad() { InitSource(); } public void Start_Button_Click(object sender, RoutedEventArgs e) { foreach (var img in ImageD3DList) { if (img.Capt != null) { img.Capt.Start(); } } } public void capture_ImageGrabbed(object sender, EventArgs e) { try { ImgInfo img = ImageD3DList.ToList().Find(p => p.Ptr == (sender as Capture).Ptr); if (img == null) return; Mat frame = new Mat(); lock (lockObj) { if (img.Capt != null) { if (!img.Capt.Retrieve(frame)) { frame.Dispose(); return; } if (frame.IsEmpty) return; //Emgu.CV.UI.ImageBox //显示图片 可以使用Emgu CV 提供的 ImageBox显示视频, 也可以转成 BitmapSource显示。 System.Windows.Application.Current.Dispatcher.Invoke(new System.Action(() => { BitmapSource source = BitmapSourceConvert.ToBitmapSource(frame); frame.Dispose(); img.ImgSource = source; })); GC.Collect(); } } } catch (Exception ex) { } } public void Stop_Btn_Click(object sender, System.Windows.RoutedEventArgs e) { foreach (var img in ImageD3DList) { if (img.Capt != null) { img.Capt.Dispose(); } } } public void Pause_Btn_Click(object sender, System.Windows.RoutedEventArgs e) { Task.Factory.StartNew(() => { foreach (var img in ImageD3DList) { img.Capt.Stop(); } }); } private void InitSource() { ImageD3DList = new ObservableCollection<ImgInfo>(); for (int i = 0; i < ImgNum; i++) { ImgInfo img = new ImgInfo(); FuncTimeout time = new FuncTimeout(CreatCapture, 500); var result = time.doAction(new object[] { img, i }); ImageD3DList.Add(img); } } private object CreatCapture(object[] data) { ImgInfo img = data[0] as ImgInfo; int i = int.Parse(data[1].ToString()); img.Index = i; img.Width = 0; img.Height = 0; img.RtspUri = url1;// UriChannelReplace(url1); img.Capt = new Capture(img.RtspUri); img.Ptr = img.Capt.Ptr; img.Capt.ImageGrabbed += capture_ImageGrabbed; return 1; } private ObservableCollection<ImgInfo> imageD3DList = new ObservableCollection<ImgInfo>(); public ObservableCollection<ImgInfo> ImageD3DList { get { return imageD3DList; } set { imageD3DList = value; NotifyOfPropertyChange(() => ImageD3DList); } } } public static class BitmapSourceConvert { /// <summary> /// Delete a GDI object /// </summary> /// <param name="o">The poniter to the GDI object to be deleted</param> /// <returns></returns> [System.Runtime.InteropServices.DllImport("gdi32.dll")] public static extern bool DeleteObject(IntPtr hObject); /// <summary> /// Convert an IImage to a WPF BitmapSource. The result can be used in the Set Property of Image.Source /// </summary> /// <param name="image">The Emgu CV Image</param> /// <returns>The equivalent BitmapSource</returns> public static BitmapSource ToBitmapSource(IImage image) { using (System.Drawing.Bitmap source = image.Bitmap) { IntPtr ptr = source.GetHbitmap(); //obtain the Hbitmap BitmapSource bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap( ptr, IntPtr.Zero, Int32Rect.Empty, System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions()); if (!DeleteObject(ptr)) { throw new System.ComponentModel.Win32Exception(); } return bs; } } } /// <summary> /// 控制函数执行时间,超时返回null不继续执行 /// 调用方法 /// FuncTimeout.EventNeedRun action = delegate(object[] param) /// { /// //调用自定义函数 /// return Test(param[0].ToString(), param[1].ToString(), (DateTime)param[2]); /// }; /// FuncTimeout ft = new FuncTimeout(action, 2000); /// var result = ft.doAction("1", "2", DateTime.Now); /// </summary> public class FuncTimeout { /// <summary> /// 信号量 /// </summary> public ManualResetEvent manu = new ManualResetEvent(false); /// <summary> /// 是否接受到信号 /// </summary> public bool isGetSignal; /// <summary> /// 设置超时时间 /// </summary> public int timeout; /// <summary> /// 定义一个委托 ,输入参数可选,输出object /// </summary> public delegate object EventNeedRun(params object[] param); /// <summary> /// 要调用的方法的一个委托 /// </summary> private EventNeedRun FunctionNeedRun; /// <summary> /// 构造函数,传入超时的时间以及运行的方法 /// </summary> /// <param name="_action">运行的方法 </param> /// <param name="_timeout">超时的时间</param> public FuncTimeout(EventNeedRun _action, int _timeout) { FunctionNeedRun = _action; timeout = _timeout; } /// <summary> /// 回调函数 /// </summary> /// <param name="ar"></param> public void MyAsyncCallback(IAsyncResult ar) { //isGetSignal为false,表示异步方法其实已经超出设置的时间,此时不再需要执行回调方法。 if (isGetSignal == false) { //放弃执行回调函数; Thread.CurrentThread.Abort(); } } /// <summary> /// 调用函数 /// </summary> /// <param name="input">可选个数的输入参数</param> /// <returns></returns> public object doAction(params object[] input) { EventNeedRun WhatTodo = CombineActionAndManuset; //通过BeginInvoke方法,在线程池上异步的执行方法。 var r = WhatTodo.BeginInvoke(input, MyAsyncCallback, null); //设置阻塞,如果上述的BeginInvoke方法在timeout之前运行完毕,则manu会收到信号。此时isGetSignal为true。 //如果timeout时间内,还未收到信号,即异步方法还未运行完毕,则isGetSignal为false。 isGetSignal = manu.WaitOne(timeout); if (isGetSignal == true) { return WhatTodo.EndInvoke(r); } else { return null; } } /// <summary> /// 把要传进来的方法,和 manu.Set()的方法合并到一个方法体。 /// action方法运行完毕后,设置信号量,以取消阻塞。 /// </summary> /// <param name="input">输入参数</param> /// <returns></returns> public object CombineActionAndManuset(params object[] input) { var output = FunctionNeedRun(input); manu.Set(); return output; } } public class ImgInfo : PropertyChangedBase { private string rtspUri; public string RtspUri { get { return rtspUri; } set { rtspUri = value; NotifyOfPropertyChange(() => RtspUri); } } private int index; public int Index { get { return index; } set { index = value; NotifyOfPropertyChange(() => Index); } } private IntPtr ptr; public IntPtr Ptr { get { return ptr; } set { ptr = value; NotifyOfPropertyChange(() => Ptr); } } private int width; public int Width { get { return width; } set { width = value; NotifyOfPropertyChange(() => Width); } } private int height; public int Height { get { return height; } set { height = value; NotifyOfPropertyChange(() => Height); } } private Capture capt; public Capture Capt { get { return capt; } set { capt = value; NotifyOfPropertyChange(() => Capt); } } private ImageSource imgSource; public ImageSource ImgSource { get { return imgSource; } set { imgSource = value; NotifyOfPropertyChange(() => ImgSource); } } }}
2.xaml界面
<Window x:Class="WpfMyCapture.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:cal="http://www.caliburnproject.org" xmlns:enu="clr-namespace:Emgu.CV.UI;assembly=Emgu.CV.UI" xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms" xmlns:wfi="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration" Title="MainWindow" cal:Message.Attach="[Event Loaded]=[Action MainLoad()]" Width="525" Height="350"> <Grid x:Name="myGrid"> <Grid.RowDefinitions> <RowDefinition Height="auto" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <StackPanel Grid.Row="0" Orientation="Horizontal"> <Button cal:Message.Attach="[Event Click]=[Action Start_Button_Click($view,$eventArgs)]" Content="播放" /> <Button cal:Message.Attach="[Event Click]=[Action Pause_Btn_Click($view,$eventArgs)]" Content="暂停" /> <Button cal:Message.Attach="[Event Click]=[Action Stop_Btn_Click($view,$eventArgs)]" Content="停止" /> </StackPanel> <ItemsControl ItemsSource="{Binding ImageD3DList}" Grid.Row="1"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <UniformGrid Columns="3" /> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemTemplate> <DataTemplate> <DockPanel LastChildFill="True"> <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" DockPanel.Dock="Top" Text="{Binding ImgTest}" /> <Border BorderBrush="Gray" BorderThickness="1" ClipToBounds="True"> <!--<wfi:WindowsFormsHost> <enu:ImageBox FunctionalMode="Minimum" SizeMode="StretchImage" /> </wfi:WindowsFormsHost>--> <Image Source="{Binding ImgSource}" Stretch="Fill"/> </Border> </DockPanel> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> </Grid></Window>
阅读全文
0 0
- C# 调用 Emgu.CV 显示RTSP流 + 设置程序运行超时时间
- [RTSP]WPF用Emgu显示RTSP视频
- C#记录程序运行时间记录显示
- C#记录程序运行时间记录显示
- 调用webservice 设置超时时间
- 调用webservice 设置超时时间
- emgu cv 在WPF上显示图像
- Emgu CV添加UI控件不显示
- C#下的openCV(Emgu CV)
- C#下的openCV(Emgu CV)
- 【C# -- OpenCV】Emgu CV 第一个实例
- C#下使用openCV(Emgu CV)
- C#下的openCV(Emgu CV)
- Emgu.CV C# WinFrom 鼠标画图
- Emgu CV程序异常的首选解决方案
- 显示程序运行时间
- 显示程序运行时间
- axis 2 调用响应超时时间设置
- HTTP 状态码
- Java设计模式、abstract、重写、上造型
- Java Socket应用
- 赋值,浅克隆和深度克隆
- Mysql 事务隔离级别、InnoDB实现隔离机制
- C# 调用 Emgu.CV 显示RTSP流 + 设置程序运行超时时间
- “全选”复选框js编写
- 2017/8/15训练日记
- HTTP 报文头 初解
- 分治法求最大连续和的问题
- spring boot useServerPrepStmts=true可能引起的异常
- 考试总结
- HTTP 延时
- 正向代理和反向代理