繁体   English   中英

无法使用 EMGU CV 连续从 RTSP 流中抓取图像

[英]Unable to use EMGU CV to grab images from RTSP stream continuously

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

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

我正在使用 IP 地址为 192.168.1.64 的 HIKVision IP 摄像机 (DS-2CD2683G1-IZ) 在端口 554 上流式传输 RTSP(这是许多海康威视 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 多毫秒才能到达,同时相机不会接受任何其他连接请求,因此再次丢失了许多帧。

我在 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);

我终于能够找到解决方案。

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

https://github.com/BogdanovKirill/RtspClientSharp

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

rtsp://rtsp.stream/pattern

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM