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

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

我们可以通过丢弃一些帧(即,调用_capture.QueryFrame() 2-3次并丢弃结果)在某种程度上减轻此问题。

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

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

如果您有使用OpenCV的经验并且了解相关知识,请告诉我。

最佳答案

我回答了一个类似的问题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方法。

干杯

克里斯

关于c# - EmguCV/OpenCV QueryFrame慢/缓冲区,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2534543/

10-12 20:35