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

时间:2019-12-01 11:51:02

标签: c# .net emgucv rtsp

我正在尝试使用C#Windows Forms应用程序从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毫秒以上的时间才能到达,并且在此期间摄像机将不接受任何其他连接请求,因此许多帧再次丢失。

    < / li>

1 个答案:

答案 0 :(得分:0)

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