如何从 IP 摄像机以更高的 FPS 抓取 JPEG 格式的图像
大家好!
我在从 Panasonic IP 摄像机中抓取 JPEG 格式的图像时遇到问题,事实上问题出在 fps 上,因为 fps 始终保持 1 或 2 不超过它,但事实上摄像机最多支持 30 个,摄像机型号为 Panasonic 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
Hy Everyone!
I am having a problem in grabbing images from a Panasonic IP Camera in JPEG format infact the problem is with the fps because the fps is always remains 1 or 2 not more than it but infact camera supports upto 30 the cam model is Panasonic WV-SP302E i am using the following C# code to grab the image and display it in my winforms app
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();
}
}
I am even using the backgrounworker component to grab images in another thread but still 2 fps. Any idea how to increase the fps
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
距离提问已经有一段时间了,但从那时起仍然是一样的。
该相机在流模式下提供高达每秒 30 帧的速度,但这不一定适用于 JPEG 快照帧速率。与全速流媒体相比,有效 JPEG 速率可能或多或少慢,具体取决于相机型号。
实际上对此您无能为力(MPEG-4/H.264 摄像机通常以较低速率发送 JPEG),您的选择是:
It has been quite some time since the question, but it is still all the same since then.
The camera offers up to 30 frames per second in streaming mode, however this does not necessarily apply to JPEG snapshot frame rate. Depending on camera model effective JPEG rate might be more or less slower as compared to full speed streaming.
There is little you can actually do about this (it is typical for MPEG-4/H.264 camera to send JPEGs at lower rate), your options are:
通常,您每秒不能从 IP 摄像机查询超过几个 jpeg 图像。如果您想要 30fps 的视频流,则需要查询“视频”流(例如 Motion jpeg),而不是快照流。
Usually you can't query more than few jpeg images / second from an IP camera. If you want a video stream with 30fps, you need to query a "video" stream like motion jpeg, not a snapshot stream.
看起来您已经做了很多设置来让该流继续运行。将分配从那里取出,这样您就不会不断地分配和释放,这会有所帮助。
一旦流开始运行,读取多个帧可能会有所帮助(即从数据采集循环内生成位图)。仅供参考,您不应该从非 GUI 线程调用 GUI 操作。使用 ReportProgress 发回数据。
您确定是捕获花费了时间而不是显示它吗?您是否尝试删除绘图代码进行测试?
Looks like you have quite a bit of set up to get that stream going. Taking the allocation out of there so you're not constantly allocating and freeing will help.
Reading multiple frames once you've got the stream going will probably help (i.e. yielding bitmaps from within your data acquisition loop). FYI, you shouldn't be calling GUI operations from a non-gui thread. Use ReportProgress to send the data back.
Are you certain it's the capture that's taking the time as opposed to displaynig it? Have you tried removing the drawing code to test?
确保场景的照明充足。简单但有些不准确的解释是,处于自动曝光模式的数码相机将等待捕获足够的光线,而在传感器效率低下的黑暗场景(如夜间的暗室)中,这将需要一段时间。在光线较亮的房间或室外日光下尝试使用相机,看看帧速率是否有所提高。
Make sure you're lighting the scene adequately. The simple and somewhat inaccurate explanation is that digital cameras in auto exposure mode will wait until they have captured enough light, which in a dark scene (like a dark room at night) with an inefficient sensor will take a while. Try the camera in a lighter room, or outside in the daylight, and see if your frame rate improves.