none
在WPF中用Emgu.CV.VideoCapture 实时预览海康的RTSP流问题 RRS feed

  • 问题

  • 软件环境:Emgu.CV.World, Version=3.3.0.2824 、.net4.0 、Win7 64位系统

    代码:

    Loaded事件调用如下代码

     Thread threadCamera = new Thread((ThreadStart)delegate
               {
                   _capture1 = new VideoCapture("rtsp://admin:abc12345@192.168.112.21:554/mpeg4/ch1/sub/av_stream");
                   _capture1.ImageGrabbed -= ProcessFrame1;
                   _capture1.ImageGrabbed += ProcessFrame1;
                   _frame1 = new Mat();
                   if (_capture1 != null) _capture1.Start();//摄像头开启  

               });
                threadCamera.IsBackground = true;
                threadCamera.Start();

     private void ProcessFrame1(object sender, EventArgs e)
            {
                try
                {
                    if (_capture1 != null && _capture1.Ptr != IntPtr.Zero)
                    {
                        if (_capture1.Retrieve(_frame1, 0))
                        {
                            this.Dispatcher.Invoke(new Action(() =>
                            {
                                try
                                {
                                    if (_frame1 != null && _frame1.Bitmap != null && _frame1.Cols > 0)
                                    {
                                        pic1.Source = null;
                                        pic1.Source = ToBitmapSource(_frame1.Bitmap);
                                    }
                                }
                                catch (Exception ex)
                                {
                                }

                            }), null);
                        }
                        else
                        {
                        }
                        Thread.Sleep(50);
                    }

                }
                catch (Exception ex)
                {
                }

            }

    以上方法可以正常预览摄像头。

    有一个奇怪的问题是,调试阶段代码打断点,会预览卡主,ProcessFrame1图像捕获事件不返回视频帧,或者程序一直正常运行着偶尔也会发生预览停止(原因不清楚)

    调试阶段查看预览停止的原因,VideoCapture的 _grabState 字段为Stopped,但是此字段是非公共成员,只能通过反射获取。

    想请教大佬们,为何会出现图像捕获事件不返回视频帧了?如果发生了此情况,我是否可以通过反射判断_grabState 的状态 再次new VideoCapture.

    2020年8月21日 9:15

全部回复

  • 你好,

    你是在项目中的Nuget中安装你的Emgu.CV 包吗?你的visual Studio 的版本是多少?在预览停止时有错误信息显示么?感觉你的问题不是WPF原生的问题,更趋向于Emgu.CV。如果我理解错误,请指出。

    谢谢

    Daisy Tian


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2020年8月24日 8:46
  • 你好,

    你是在项目中的Nuget中安装你的Emgu.CV 包吗?你的visual Studio 的版本是多少?在预览停止时有错误信息显示么?感觉你的问题不是WPF原生的问题,更趋向于Emgu.CV。如果我理解错误,请指出。

    谢谢

    Daisy Tian


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    您好,我的vs版本是2013,没有从Nuget中安装;直接拷贝的动态库。

    在预览停止时没有异常错误信息,我是通过断点跟踪进去,看到VideoCapture的 _grabState 字段为Stopped状态了。软件并没有报错。


    2020年8月24日 9:36
  • 通过反编译代码,看到VideoCapture类中,只有一个地方会GrabState.Stopped,就是在Run方法中,Run方法的调用就是我调用Start方法时启用的,一直循环。

    public void Start(ExceptionHandler eh = null)
            {
                if (_grabState == GrabState.Pause)
                {
                    _grabState = GrabState.Running;
                    _pauseEvent.Set();
                }
                else if (_grabState == GrabState.Stopped || _grabState == GrabState.Stopping)
                {
                    _grabState = GrabState.Running;
                    ThreadPool.QueueUserWorkItem(delegate
                    {
                        Run(eh);
                    });
                }
            }

      private void Run(ExceptionHandler eh = null)
            {
                try
                {
                    while (_grabState == GrabState.Running || _grabState == GrabState.Pause)
                    {
                        if (_grabState == GrabState.Pause)
                        {
                            _pauseEvent.WaitOne();
                        }
                        else if (IntPtr.Zero.Equals(_ptr) || !Grab())
                        {
                            _grabState = GrabState.Stopping;
                        }
                    }
                }
                catch (Exception ex)
                {
                    if (eh == null || !eh.HandleException(ex))
                    {
                        throw new Exception("Capture error", ex);
                    }
                }
                finally
                {
                    _grabState = GrabState.Stopped;
                }
            }

    从上面代码得知,肯定是报了异常才会导致GrabState.Stopped,但是这个异常信息我代码加了trycatch也捕获不到

    2020年8月24日 9:52