IP Camera stop streaming after some time

六眼飞鱼酱① 提交于 2019-11-27 08:52:42

问题


I am working on one application where I want to use IP camera for displaying video streaming and and some other major operations on image captured by the IP Camera.

Libraries used in Camera capture For Camera Capture : Emgu.CV Library

Below is the code which I am using in C#.

Variable Declaration

    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   

Code for Processing Image

  private void ProcessFrame(object sender, EventArgs arg)
  {
    try
          {                
      // Live Streaming Display
     Image<Bgr, Byte> 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)
       {
       }
    }

Now, The Problem is after some time the QueryFrame() provide null value and camera Stop streaming.

Can any one tell me why this is happening? How I can resolve this problem? If any more information is needed Please Let me know.

Thanks in Advance.


回答1:


Sorry about the delay but I have provide an example that works with several public IP cameras. It will need the EMGU reference replacing with your current version and the target build directory should be set to "EMGU Version\bin" alternatively extract it to the examples folder.

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

Rather than using the older QueryFrame() method it uses the RetrieveBgrFrame() method. It has worked reasonably well and I have had no null exceptions. However if you do replace the ProcessFrame() method with something like this

You should not be attempting to do any operations if the frame returned is Image is a nullable field and should not have a problem if _capture.RetrieveBgrFrame(); returns null if there is a problem then there is a bigger issue.

private void ProcessFrame(object sender, EventArgs arg)
{
    //If you want to access the image data the use the following method call
    //Image<Bgr, Byte> frame = new Image<Bgr,byte>(_capture.RetrieveBgrFrame().ToBitmap());

    if (RetrieveBgrFrame.Checked)
    {
        Image<Bgr, Byte> 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<Bgr, Byte> 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<Gray, Byte> frame = _capture.RetrieveGrayFrame();
        //because we are using an autosize picturebox we need to do a thread safe update
        if (frame != null) DisplayImage(frame.ToBitmap());
    }
}

On a separate note your comment 'continue Looping for other Ip Cameras' may cause several issues. You should have a new Capture constructor for each camera camera you are using. How many camera are you using? and what public ip camera are you using so I can attempt to replicate the issue? The reason for the separate constructor is that ip cameras take a while to negotiate connections with and constantly Disposing of the original construct and replacing it will play havoc with the garbage collector and introduce no end if timing issues.

Cheers

Chris

[EDIT]

If your camera is returning null frames after a timeout period then I would check to see if there is an issue with the setup or maybe your connection is so slow it disconnects you to reduce lag to others there are various causes but this is not a code problem. You can use c# alone to acquire the data to a bitmap and then pass this to an Image type variable. There is a great article here:

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

I've adapted this so you can use a HttpWebRequest as a final check to see if the stream is alive although there are still null exceptions that will be produced here:

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<Bgr, Byte> frame = new Image<Bgr,byte>(_capture.RetrieveBgrFrame().ToBitmap());

        if (RetrieveBgrFrame.Checked)
        {
            Image<Bgr, Byte> 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<Gray, Byte> 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
    }

To display multiple webcams you would create a class to handle the Capture construct and processframe event. Ideally you would raise an purpose built event call that would include a camera identifier as the frameready event call does not call this. I have to make things easier created a form with as a MDI parent and opened an object to manage the capture variables and frame ready event. The Alpha version is available here:

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



来源:https://stackoverflow.com/questions/21745309/ip-camera-stop-streaming-after-some-time

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!