我有两台IP摄像机,它们是不同的型号,都来自同一制造商。我们称它们为Cam1和Cam2。我想通过网络地址从这些摄像机中检索帧,但是有一些问题。
Cam1:
当使用frame = capture.RetrieveBgrFrame();
时,frame总是null。
frame = capture.QueryFrame();
框架是好。
Cam2 (在相同的网络和我的个人电脑):
当使用frame = capture.RetrieveBgrFrame();
时,frame总是null。
当使用frame = capture.QueryFrame();
时,WinForm被冻结,计算机(i73,3ghz, 6GB RAM)冻结。
两个流地址都可以。我试着用VLC和OpenCV c++平台打开它们。
这里可能有什么问题?
代码如下:
using Emgu.CV;
using Emgu.Util;
using Emgu.CV.Structure;
using Emgu.CV.UI;
namespace IPcamera
{
public partial class Form1 : Form
{
private Capture capture;
private Image<Bgr, Byte> frame;
public Form1()
{
InitializeComponent();
try
{
capture = new Capture(camera_address);
}
catch (NullReferenceException exception)
{
MessageBox.Show(exception.Message);
}
if (capture != null)
{
Application.Idle += ProcessFrame;
}
}
void ProcessFrame(object sender, EventArgs e)
{
frame = capture.RetrieveBgrFrame();
if (frame != null)
{
pictureBox1.Image = frame.ToBitmap();
}
}
}
}
我通常不使用IP摄像机,但我怀疑它们在初始化时不会开始拍摄图像。RetrieveBgrFrame()返回相机拍摄的最后一张图像,所以如果我是对的,RetrieveBgrFrame()将返回null,因为相机本身没有拍摄图像。尝试将ProcessFrame处理程序添加到相机事件捕获中。imagegrab而不是Application。空闲并检查是否正在被调用
关于冻结,如果是"低fps"冻结,可能是由于相机速度慢,或者试图通过慢总线发送大图像。如果它永远冻结,检查是否有任何其他应用程序可以使用该相机,并释放资源(您是在cam2之前尝试cam1还是在新的运行中尝试cam2 ?)
能否替换
Application.Idle += ProcessFrame;
capture.ImageGrabbed += ProcessFrame;
然后RetrieveBgrFrame()方法可以返回帧。这就是我通常的做法,我没有遇到任何问题。您可能需要将image分配给pictureBox1。
pictureBox1.Invoke((MethodInvoker) (() => pictureBox1.Image = frame.ToBitmap()));