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

C# 无法使用EMGU CV连续从RTSP流抓取图像,c#,.net,emgucv,rtsp,C#,.net,Emgucv,Rtsp,我正在尝试使用C#Windows窗体应用程序从IP摄像头的RTSP流中获取图像。我使用EMGU CV连续捕获流,但RTSP蒸汽在几秒钟后停止,然后imageGrabbedEvent从未触发 我的目的很简单:从相机中获取每一帧并对其进行分析 我正在使用端口554上的IP地址为192.168.1.64流式RTSP的海康威视IP摄像头(DS-2CD2683G1-IZ)(这是许多海康威视IP摄像头的默认IP地址和端口号) DateTime LastTimeImageGrabReinitialised=n

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

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

我正在使用端口554上的IP地址为192.168.1.64流式RTSP的海康威视IP摄像头(DS-2CD2683G1-IZ)(这是许多海康威视IP摄像头的默认IP地址和端口号)

DateTime LastTimeImageGrabReinitialised=new DateTime();
public void InitializeCameraEMGUStream()
{
//根据另一个答案的建议,在URL中添加了datetime,但没有帮助。
VideoCapture myVideoCapture=新视频捕获(“rtsp://admin:mysecretpassword@192.168.1.64:554/ch1/main/av_stream?+DateTime.Now.ToString();
myVideoCapture.ImageGrabbed+=imageGrabbedEvent;
myVideoCapture.Start();
LastTimeImageGrabReinitialised=DateTime.Now;
}
私有void imageGrabbedEvent(对象发送方,EventArgs e)
{
LastTimeImageGrapped=DateTime.Now;
尝试
{
Mat m=新Mat();
myVideoCapture.Retrieve(m);
LateStaQuiredImage=m.ToImage().Bitmap;
pictureBox.Image=m.ToImage().Bitmap;
imgEntrada=m.ToImage();
}
捕获(例外情况除外)
{
}
//我尝试添加一些逻辑来在几百毫秒后重新初始化流,
//但重新初始化似乎需要一段时间才能获得清晰的图像,许多帧无法读取。
如果((DateTime.Now-LastTimeImageGrabReinitialized).TotalMillimes>200)
{
myVideoCapture.Start();
LastTimeImageGrabReinitialised=DateTime.Now;
}
}
我已经在网上找到了一些答案,但找不到一个确定的方法来保持流的活力。我真的很感激在这方面的任何帮助

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

  • 我试着每隔一段时间重新初始化视频捕获,但速度很慢,许多初始帧都是嘈杂/不清晰的图像

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

  • 此外,我还尝试使用RTSPClientSharp,在使用时,ImageAcrapped事件会定期触发,但我无法显示解码图像

  • 我尝试使用HTTP从相机获取图像,但是,每个图像需要600多毫秒才能到达,同时相机不会接受任何其他连接请求,因此许多帧再次丢失


  • 我在一个RTSP流中遇到了类似的问题,我通过使用
    QueryFrame
    以及超时来解决它,而不是使用
    imagegrapped
    事件,因此您的相机可能值得一试。这是抓取帧的主要处理循环,我没有观察到任何意外丢失的帧。我只看到
    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秒(基于摄像头时钟),这听起来像是有什么东西没有跟上,一个快速尝试的方法是使用
    QuerySallFrame
    获得半幅图像,如果可行,可以尝试将相机中的视频格式调整为更小或更压缩的格式。您还可以尝试查看VisualStudio探查器,看看代码中是否存在您不期望的瓶颈。
    Queue myQ = new Queue();
    Queue frameQueue = Queue.Synchronized(myQ);