2

我们有一个应用程序,我们从外部系统获取消息,然后我们拍照,进行一些处理并将某些内容返回给外部系统。做一些性能测试,我发现了两个问题(它们有些相关)。我希望有人能够向我解释这一点。

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

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

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

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

如果您有使用 OpenCV 的经验并知道相关内容,请告诉我。

4

2 回答 2

2

我在 C# 中使用 Emgu.CV回答了一个类似的问题System.TypeInitializationException ,并测试了获取最新框架的各种可能性,我发现了下面的 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 方法。

干杯

克里斯

于 2011-09-27T18:58:39.637 回答
0

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

于 2011-05-09T14:19:14.317 回答