EmguCV / OpenCV QueryFrame медленный / буферы - PullRequest
2 голосов
/ 29 марта 2010

У нас есть приложение, в котором мы получаем сообщение от внешней системы, а затем делаем снимок, выполняем некоторую обработку и возвращаем что-то обратно во внешнюю систему. Проведя некоторое тестирование производительности, я обнаружил две проблемы (они несколько связаны). Я надеялся, что кто-нибудь сможет мне это объяснить.

1) _capture.QueryFrame() буферизует кадры? Мы видим, что если между запросом к двум кадрам с веб-камеры существует разрыв, второй кадр часто является более старым, а не тем, когда вызывался queryFrame.

Нам удалось до некоторой степени смягчить эту проблему, отбросив некоторые кадры, т.е. позвонив _capture.QueryFrame() 2-3 раза и отбросив результаты.

2) Вторая проблема заключается в том, что, когда мы рассчитали различные части приложения, мы обнаружили, что очистка буфера (вызов QueryFrame() 2-3 раза и не использование результатов) занимает около 65 мс, а затем эта строка: Image<Bgr, Byte> source = _capture.QueryFrame() занимает около 80 мс. Эти две части занимают большую часть времени обработки, наша фактическая обработка занимает всего около 20-30 мс.

Есть ли более быстрый способ (а) очистить буфер (б) для захвата кадра?

Если у вас есть опыт работы с OpenCV и вы знаете что-то связанное, пожалуйста, дайте мне знать.

Ответы [ 2 ]

2 голосов
/ 27 сентября 2011

Я ответил на аналогичный вопрос System.TypeInitializationException, используя Emgu.CV в C # и, протестировав различные возможности получения обновленного фрейма, я нашел ниже метод bes.

1) да, когда вы устанавливаете Capture с веб-камеры, создается кольцевой буфер для хранения изображений, что позволяет эффективно распределять память.

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.

Cheers

Chris

0 голосов
/ 09 мая 2011

Это также может быть связано с частотой обновления веб-камеры, которую вы используете.Моя камера работает на частоте 60 Гц, поэтому у меня есть таймер, который снимает кадр каждые 15 миллисекунд.

...