我们有一个应用程序,我们从外部系统获取消息,然后我们拍照,进行一些处理并将某些内容返回给外部系统。做一些性能测试,我发现了两个问题(它们有些相关)。我希望有人能够向我解释这一点。
1)_capture.QueryFrame()
缓冲帧吗?
我们看到的是,如果来自网络摄像头的两个帧的查询之间存在差距,则第二帧通常是旧图片而不是调用queryFrame时的图片。
我们能够在某种程度上通过丢弃一些帧来缓解这个问题,即调用_capture.QueryFrame()
2-3次并丢弃结果。
2)第二个问题是当我们计算应用程序的不同部分时,我们发现清除缓冲区(调用QueryFrame()
2-3次而不使用结果)需要大约65ms然后这一行:{ {1}}需要大约80毫秒。这两个部分占用了最大的处理时间,我们的实际处理时间仅为20-30ms。
是否有更快的方法(a)清除缓冲区(b)以捕获帧?
如果您有OpenCV的经验并且知道相关的事情,请告诉我。
答案 0 :(得分:2)
我回答了类似的问题System.TypeInitializationException using Emgu.CV in C#,并测试了获取最新帧的各种可能性,我发现了bes方法。
1)是的,当您从网络摄像头设置捕获时,会创建一个环形缓冲区来存储图像,这样可以有效地分配内存。
2)是的,有一种更快的方法,全局设置你的Capture设备并设置它的记录和调用ProcessFrame,以便尽可能从缓冲区获取图像。现在更改您的QueryFrame只是为了复制它刚刚获得的任何帧。这有望阻止您获取前一帧的问题,现在您将从缓冲区中获得最新的帧。
private Capture cap;
Image<Bgr, Byte> frame;
public CameraCapture()
{
InitializeComponent();
cap= new Capture();
cap.SetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_HEIGHT, height);
cap.SetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_WIDTH, width);
Application.Idle += ProcessFrame;
}
private void ProcessFrame(object sender, EventArgs arg)
{
frame = _capture.QueryFrame();
grayFrame = frame.Convert<Gray, Byte>();
}
public Image<Bgr,byte> QueryFrame()
{
return frame.Copy();
}
我希望如果不让我知道这会有所帮助,我会尝试为您的要求量身定制解决方案。不要忘记,您可以始终在不同的线程上运行您的获取,并调用新的QueryFrame方法。
干杯
克里斯
答案 1 :(得分:0)
这也可能是由于您正在使用的webcamera的刷新率。我的相机工作在60Hz,所以我有一个定时器,每15毫秒捕获一帧。