【问题标题】:Unable to use EMGU CV to grab images from RTSP stream continuously无法使用 EMGU CV 从 RTSP 流中连续抓取图像
【发布时间】:2019-12-01 11:51:02
【问题描述】:

我正在尝试使用 C# Windows 窗体应用程序从 IP 摄像机的 RTSP 流中获取图像。我正在使用 EMGU CV 连续捕获流,但 RTSP Steam 在几秒钟后停止,然后 imageGrabbedEvent 永远不会触发。

我的目的很简单:从相机中获取每一帧并进行分析。

我正在使用 IP 地址为 192.168.1.64 的 HIKVision IP 摄像机 (DS-2CD2683G1-IZ) 在端口 554 上流式传输 RTSP(这是许多 Hikvision IP 摄像机的默认 IP 地址和端口号)

DateTime LastTimeImageGrabReinitialised = new DateTime();


public void InitializeCameraEMGUStream()
        {
            //added a datetime to the URL as recommended by another answer but it didnt help.
            VideoCapture myVideoCapture = new VideoCapture("rtsp://admin:mysecretpassword@192.168.1.64:554/ch1/main/av_stream?"+DateTime.Now.ToString());
            myVideoCapture.ImageGrabbed += imageGrabbedEvent;
            myVideoCapture.Start();

            LastTimeImageGrabReinitialised = DateTime.Now;

        }

private void imageGrabbedEvent(object sender, EventArgs e)
        {
            lastTimeImageGrabbed = DateTime.Now;
            try
            {
                Mat m = new Mat();
                myVideoCapture.Retrieve(m);
                LatestAcquiredImage = m.ToImage<Bgr, byte>().Bitmap;
                pictureBox.Image = m.ToImage<Bgr, byte>().Bitmap;
                imgEntrada = m.ToImage<Bgr, byte>();
            }
            catch (Exception Ex)
            {



            }

            //I tried adding some logic to reinitialize the stream after a few hundred milliseconds, 
            //but it seems the reinitialization takes a while to obtain a clear image and many frames cannot be read.
            if((DateTime.Now- LastTimeImageGrabReinitialised).TotalMilliseconds>200)
            {

                myVideoCapture.Start();
                LastTimeImageGrabReinitialised = DateTime.Now;
            }

        }


我已经浏览了几个在线可用的答案,但找不到确定的方法来保持直播。在这方面我非常感谢任何帮助。

仅供参考:我已经尝试过:

  1. 我尝试每隔一段时间重新初始化 VideoCapture,但速度很慢,而且许多初始帧都是嘈杂/不清晰的图像。

  2. 我已经尝试使用 VLC.Dotnet 来运行 RTSP 流,流工作得非常好,但是抓取图像并将其转换为图像非常慢,主要是因为 VLCControl.TakeSnapshot() 保存文件在磁盘上。充其量,这会消耗超过 500 毫秒,并且在此期间丢失了许多帧。

  3. 我还尝试使用 RTSPClientSharp,在使用它时,imageGrabbed 事件会定期触发,但我无法显示解码的图像。

  4. 我尝试使用 HTTP 从摄像头获取图像,但是,每张图像的到达时间超过 600 毫秒,同时摄像头不会接受任何其他连接请求,因此再次丢失了许多帧。

【问题讨论】:

    标签: c# .net emgucv rtsp


    【解决方案1】:

    我在使用 RTSP 流时遇到了类似的问题,我通过使用 QueryFrame 以及超时而不是 ImageGrabbed 事件解决了这个问题,因此您的相机可能值得一试。这是抓取帧的主要处理循环,我没有观察到任何意外的丢帧我只看到了QueryFrame 超时,原因是相机断电:

    try
    {
        if (!cameraOpened)
        {
            LogMessage("Opening camera stream...");
            var openTask = Task.Run(() => capture = new Capture("rtsp://admin:redacted@10.0.0.22:554"));
            if (await Task.WhenAny(openTask, Task.Delay(20000)) != openTask)
            {
                LogMessage("Unable to open camera stream");
            }
            else
            {
                LogMessage("Camera stream opened");
                cameraOpened = true;
            }
        }
        if (cameraOpened)
        {
            var captureTask = Task.Run(() => inputFrame = capture.QueryFrame());
            if (await Task.WhenAny(captureTask, Task.Delay(5000)) != captureTask)
            {
                LogMessage("Camera connection lost");
                cameraOpened = false;
            } 
            else
            {
                if (inputFrame != null && !inputFrame.IsEmpty)
                {
                    frameQueue.Enqueue(inputFrame);
                }
            }
        }
    } catch (Exception ex)
    {
        LogMessage(ex.Message);
        Thread.Sleep(5000);
    }
    

    frameQueue 声明如下,并且处理发生在一个单独的线程中,这也可能有所帮助。我很久以前写了代码,而不是这个,我现在使用ConcurrentQueue 类。

    Queue myQ = new Queue();
    Queue frameQueue = Queue.Synchronized(myQ);
    

    【讨论】:

    • 嗨彼得,感谢您的回复。我尝试了上面的方法,QueryFrame 方法在运行大约 1 分钟后开始返回 null inputFrame。此外,图像似乎延迟到达,最终延迟堆积,在 QueryFrame 开始返回 null 之前,视频延迟了大约 30 秒(基于相机时钟)
    • 这听起来有点跟不上,一个快速的尝试是使用QuerySmallFrame 来获取半尺寸图像,如果可行,可以尝试将相机中的视频格式调整为某种东西更小或更压缩。您还可以尝试查看 Visual Studio Profiler,看看代码中是否存在您没有预料到的瓶颈。
    【解决方案2】:

    我终于找到了解决办法。

    虽然 Emgu 的 RTSP 流抓取器不稳定,但 RTSPClientSharp 是一个非常稳定的实现,用于从 RTSP 流中抓取单个帧并将它们转换为可用于 .NET 中的任何图像处理的位图。 GitWorks 中提供的开箱即用示例。

    https://github.com/BogdanovKirill/RtspClientSharp

    从GitHub下载项目后,您可以尝试使用以下流进行抓取(如果仍然在线,请使用VLC检查以确保流仍然可用)

    rtsp://rtsp.stream/pattern

    【讨论】:

      猜你喜欢
      • 2015-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-06
      • 2017-12-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多