首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >EmguCV/OpenCV QueryFrame慢速/缓冲区

EmguCV/OpenCV QueryFrame慢速/缓冲区
EN

Stack Overflow用户
提问于 2010-03-29 05:01:57
回答 2查看 7.3K关注 0票数 2

我们有一个应用程序,在其中我们从外部系统获取消息,然后我们拍摄照片,进行一些处理,并将某些内容返回到外部系统。在做一些性能测试时,我发现了两个问题(它们在某种程度上是相关的)。我希望有人能给我解释一下。

1) _capture.QueryFrame()是否缓冲帧?我们看到的是,如果从网络摄像头查询两个帧之间存在间隙,则第二个帧通常是较旧的图片,而不是调用queryFrame时的图片。

我们能够通过丢弃一些帧在一定程度上缓解这个问题,即调用_capture.QueryFrame() 2-3次并丢弃结果。

2)第二个问题是,当我们对应用程序的不同部分进行计时时,我们发现清除缓冲区(调用QueryFrame() 2-3次,不使用结果)大约需要65ms,然后这一行:Image<Bgr, Byte> source = _capture.QueryFrame()大约需要80ms。这两个部分占用了最大的处理时间,我们的实际处理只多花了大约20-30ms。

是否有更快的方法(a)清除缓冲区(b)来捕获帧?

如果你有使用OpenCV的经验并知道一些相关的事情,请一定要让我知道。

EN

回答 2

Stack Overflow用户

发布于 2011-09-28 02:58:40

我回答了一个类似的问题System.TypeInitializationException using Emgu.CV in C#,在测试了获取最新帧的各种可能性后,我发现了下面的bes方法。

1)是的,当您设置从网络摄像头捕获时,会创建一个环形缓冲区来存储图像,这样可以有效地分配内存。

2)是的,有一种更快的方法,全局设置您的捕获设备,并将其设置为记录,并随时调用ProcessFrame从缓冲区获取图像。现在,简单地更改您的QueryFrame,以复制它刚刚获得的任何帧。这将有望解决您获取前一帧的问题,现在您将从缓冲区中获得最新的帧。

代码语言:javascript
复制
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方法。

干杯

克里斯

票数 2
EN

Stack Overflow用户

发布于 2011-05-09 22:19:14

这也可能是由于您正在使用的网络摄像头的刷新率。我的相机工作在60赫兹,所以我有一个计时器,每15毫秒捕捉一帧。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2534543

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档