我正在尝试使用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;
}
}
我已经通过网上找到了一些答案,但是找不到一种确定的方法来保持视频流的生命。在这方面的任何帮助,我将非常感谢。
仅供参考:我已经尝试过的:
我尝试每隔一段时间重新初始化VideoCapture,但是它很慢,而且很多初始帧都是嘈杂/不清楚的图像。
我已经尝试使用VLC.Dotnet运行RTSP蒸汽,流工作正常,但是要抓取图像并将其转换为图像,图像非常慢,这主要是因为VLCControl.TakeSnapshot()将文件保存在磁盘。最好情况下,这会耗费超过500毫秒的时间,并且在此期间会丢失许多帧。
我还尝试使用RTSPClientSharp,在使用该代码时,imageGrabbed事件会定期触发,但我无法显示解码后的图像。
我尝试使用HTTP从摄像机获取图像,但是每个图像需要花费600毫秒以上的时间才能到达,并且在此期间摄像机将不接受任何其他连接请求,因此许多帧再次丢失。
< / li>答案 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);