一段时间后,IP Camera停止流式传输

我正在开发一个应用程序,我想使用IP camera显示video流,以及对IP Camera捕获的图像进行一些其他主要操作。

摄像头捕获中使用的库用于摄像头捕获: Emgu.CV库

下面是我在C#中使用的代码。

变量声明

  private Capture capture; //takes images from camera as image frames private Emgu.CV.UI.ImageBox img; // Dynamic Picture Controls private int nCam; // no of cameras 

处理图像的代码

  private void ProcessFrame(object sender, EventArgs arg) { try { // Live Streaming Display Image ImageFrame = capture.QueryFrame(); // If Ip camera try to reinitialize the IP camera if(ImageFrame == null) { capture.Dispose(); capture = new Capture(URL); ImageFrame = capture.QueryFrame(); } ImageFrame = ImageFrame.Resize(img.Width, img.Height, Emgu.CV.CvEnum.INTER.CV_INTER_LINEAR); img.Image = ImageFrame; // Here I am doing some other operations like // 1. Save Image captured from the IP Camera // 2. Detect faces in Image // 3. Draw Face markers on Image // 4. Some database based on result of Face Detection // 4. Delete image File // continue Looping for other Ip Cameras } catch (NullReferenceException e) { } } 

现在,问题是在一段时间后, QueryFrame()提供null值和相机停止流。

任何人都可以告诉我为什么会这样吗? 我怎么解决这个问题? 如果需要更多信息,请告诉我。

提前致谢。

对于延迟感到抱歉,但我提供了一个适用于多个公共IP摄像机的示例。 它需要EMGU引用替换为您当前的版本,目标构建目录应设置为“EMGU Version \ bin”或者将其提取到examples文件夹。

http://sourceforge.net/projects/emguexample/files/Capture/CameraCapture%20Public%20IP.zip/download

它不使用旧的QueryFrame()方法,而是使用RetrieveBgrFrame()方法。 它工作得相当好,我没有空例外。 但是,如果你用这样的东西替换ProcessFrame()方法

如果返回的帧是Image是可以为空的字段,则不应该尝试执行任何操作,如果_capture.RetrieveBgrFrame();则不应该有问题。 如果有问题则返回null然后存在更大的问题。

 private void ProcessFrame(object sender, EventArgs arg) { //If you want to access the image data the use the following method call //Image frame = new Image(_capture.RetrieveBgrFrame().ToBitmap()); if (RetrieveBgrFrame.Checked) { Image frame = _capture.RetrieveBgrFrame(); //because we are using an autosize picturebox we need to do a thread safe update if(frame!=null) { DisplayImage(frame.ToBitmap()); Image ImageFrame = frame.Resize(img.Width, img.Height, Emgu.CV.CvEnum.INTER.CV_INTER_LINEAR); // Here I am doing some other operations like // 1. Save Image captured from the IP Camera // 2. Detect faces in Image // 3. Draw Face markers on Image // 4. Some database based on result of Face Detection // 4. Delete image File // continue Looping for other Ip Cameras } //else do nothing as we have no image } else if (RetrieveGrayFrame.Checked) { Image frame = _capture.RetrieveGrayFrame(); //because we are using an autosize picturebox we need to do a thread safe update if (frame != null) DisplayImage(frame.ToBitmap()); } } 

另请注意,您的评论“继续循环播放其他Ip相机”可能会导致一些问题。 你应该为你正在使用的每个摄像机摄像头配备一个新的Capture构造函数。 你用了多少台相机? 你正在使用什么公用IP摄像头,所以我可以尝试复制这个问题? 单独的构造函数的原因是ip camera需要一段时间来协商连接并且不断地处理原始构造并替换它将对垃圾收集器造成严重破坏并且如果时间问题则不会引入。

干杯

克里斯

[编辑]

如果您的相机在超时期限后返回空帧,那么我会检查设置是否存在问题,或者您的连接速度很慢,它会断开连接以减少其他人的延迟,但是这不是代码问题。 您可以单独使用c#将数据获取到位图,然后将其传递给Image类型变量。 这里有一篇很棒的文章:

http://www.codeproject.com/Articles/15537/Camera-Vision-video-surveillance-on-C

我已经对此进行了调整,因此您可以使用HttpWebRequest作为最终检查以查看流是否处于活动状态,尽管此处仍会生成空的exception:

 using System.Net; using System.IO; string url; private void ProcessFrame(object sender, EventArgs arg) { //***If you want to access the image data the use the following method call***/ //Image frame = new Image(_capture.RetrieveBgrFrame().ToBitmap()); if (RetrieveBgrFrame.Checked) { Image frame = _capture.RetrieveBgrFrame(); //because we are using an autosize picturebox we need to do a thread safe update if (frame != null) { DisplayImage(frame.ToBitmap()); } else { HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url); // get response WebResponse resp = req.GetResponse(); //get stream Stream stream = resp.GetResponseStream(); if (!stream.CanRead) { //try reconnecting the camera captureButtonClick(null, null); //pause _capture.Dispose();//get rid captureButtonClick(null, null); //reconnect } } } else if (RetrieveGrayFrame.Checked) { Image frame = _capture.RetrieveGrayFrame(); //because we are using an autosize picturebox we need to do a thread safe update if (frame != null) DisplayImage(frame.ToBitmap()); } } private void captureButtonClick(object sender, EventArgs e) { url = Camera_Selection.SelectedItem.ToString(); //add this ... the rest of the code } 

要显示多个网络摄像头,您需要创建一个类来处理Capture构造和processframe事件。 理想情况下,您将引发一个专用的事件调用,其中包含一个摄像机标识符,因为frameready事件调用不会调用它。 我必须更容易创建一个带有MDI父级的表单,并打开一个对象来管理捕获变量和帧就绪事件。 Alpha版本可在此处获得:

http://sourceforge.net/projects/emguexample/files/Capture/CameraCapture%20Public%20IP%20Multipl%20Display%20Alpha.zip/download