如何以更高的Fps从网络摄像机中抓取JPEG格式的图像

本文关键字:摄像机 抓取 JPEG 图像 格式 网络 Fps | 更新日期: 2023-09-27 17:49:44

大家好!

我在以JPEG格式从松下IP相机抓取图像时遇到问题,实际上问题是fps,因为fps总是保持1或2不超过它,但实际上相机支持高达30,相机型号是松下WV-SP302E,我使用以下c#代码抓取图像并将其显示在我的winforms应用程序

public partial class Form1 : Form
{
    // indicates wether to prevent caching in case of a proxy server or not
    private bool preventCaching = false;                
    public Form1()
    {
        InitializeComponent();
    }
    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        while (true)
        {
            this.pictureBox1.Image = this.GetSingleFrame(@"http://ipaddress/SnapshotJPEG?Resolution=320x240&Quality=Standard");                
        }
    }
    /// <summary>
    /// Get a single JPEG frame from the camera
    /// </summary>
    /// <param name="source">JPEG Stream source</param>
    /// <exception cref="WebException">If the IP camera is not receable or an error is occured</exception>
    /// <exception cref="Exception">If an unknown error occured</exception>
    public Bitmap GetSingleFrame(string source)
    {
        byte[] buffer = new byte[512 * 1024];   // buffer to read stream
        HttpWebRequest req = null;
        WebResponse resp = null;
        Stream stream = null;
        Random rnd = new Random((int)DateTime.Now.Ticks);
        try
        {
            int read, total = 0;
            // create request
            if (!preventCaching)
            {
                req = (HttpWebRequest)WebRequest.Create(source);
            }
            else
            {
                req = (HttpWebRequest)WebRequest.Create(source + ((source.IndexOf('?') == -1) ? '?' : '&') + "fake=" + rnd.Next().ToString());
            }
            // set login and password                
            req.Credentials = new NetworkCredential("root", "a");                
            req.Timeout = -1;
            resp = req.GetResponse();
            // get response stream
            stream = resp.GetResponseStream();
            // loop
            do
            {
                read = stream.Read(buffer, total, 1024);
                total += read;
            }
            while (read != 0);
            Bitmap bmp = (Bitmap)Bitmap.FromStream(new MemoryStream(buffer, 0, total));
            return bmp;
        }
        catch (WebException ex)
        {
            string s = ex.ToString();
            return null;
        }
        catch (Exception ex)
        {
            string s = ex.ToString();
            return null;
        }
        finally
        {
            // abort request
            if (req != null)
            {
                req.Abort();
                req = null;
            }
            // close response stream
            if (stream != null)
            {
                stream.Close();
                stream = null;
            }
            // close response
            if (resp != null)
            {
                resp.Close();
                resp = null;
            }
        }
    }
    private void Form1_Load(object sender, EventArgs e)
    {
        this.backgroundWorker1.RunWorkerAsync();
    }
}

我甚至使用backgrounworker组件在另一个线程中抓取图像,但仍然是2 fps。有没有办法增加fps

如何以更高的Fps从网络摄像机中抓取JPEG格式的图像

这个问题已经过去一段时间了,但从那以后一切都是一样的。

相机提供高达每秒30帧的流模式,但这并不一定适用于JPEG快照帧率。与全速流媒体相比,根据相机型号的不同,有效的JPEG速率可能会更慢。

实际上你对此几乎无能为力(这是典型的MPEG-4/H)。264相机以较低的速率发送jpeg),您的选项是:

  • 通过接收视频馈送(可能是像RTSP这样的标准协议,或通过SDK或相机供应商的ActiveX控件的专有协议)从相机获取图像
  • 用更合适的型号替换相机,这样每秒可以获得更多的JPEG快照

通常你不能从一个IP摄像机查询超过几个jpeg图像/秒。如果你想要一个30fps的视频流,你需要查询像motion jpeg这样的"视频"流,而不是快照流。

看起来您已经进行了相当多的设置以使该流运行。从那里取出分配,这样你就不用不断地分配和释放了。

读取多个帧,一旦你有了流可能会有所帮助(即产生位图从你的数据采集循环)。仅供参考,您不应该从非GUI线程调用GUI操作。使用ReportProgress将数据发回。

你确定是捕获占用了时间而不是显示时间吗?你有没有试过移除图纸代码进行测试?

确保你的场景光线充足。简单但有些不准确的解释是,自动曝光模式下的数码相机会等待,直到它们捕捉到足够的光线,而在一个黑暗的场景中(比如夜晚的暗室),传感器效率低下,这需要一段时间。在光线较亮的房间或室外日光下试试,看看你的帧率是否会提高。