2014-12-04 3 views
1

Для проекта компьютерного зрения, над которым я работаю, мне нужно захватить изображения с помощью веб-камеры Logitech C920. Я использую VideoCapture от OpenCV, но проблема, с которой я столкнулась, заключается в том, что изображение, которое я принимаю в определенный момент, не показывает последнюю вещь, которую видит камера. То есть, если я беру изображение в timestamp t, он показывает, что камера увидела в timestamp (t - delta), так сказать.Задержка OpenCV VideoCapture/V4L2 при захвате нового изображения веб-камеры

Я сделал это, написав программу, которая увеличивает счетчик и показывает его на экране. Я указал на камеру на экране и дал ей запись. Когда счетчик достиг определенного значения, скажем, 10000, он захватит изображение и сохранит его с именем файла «counter_value.png» (например, 10000.png). Таким образом, мне удалось сравнить текущее значение счетчика с текущим значением, наблюдаемым камерой. Я заметил, что большую часть времени задержка составляет около 4-5 кадров, но это не фиксированное значение.

Я видел похожие сообщения по этому вопросу, но ни один из них не помог. Некоторым людям рекомендуется поместить подпрограмму захвата кадров в отдельный поток и обновить переменную Mat_ current_frame. Я попробовал это, но по какой-то причине проблема все еще присутствует. Кто-то еще сказал, что камера хорошо работает в Windows (но мне нужно использовать Linux, хотя). Я попробовал запустить тот же код в Windows, и действительно, задержка составляла всего около 1 кадра (что также может быть, что камера не увидела счетчик, потому что экран не обновлялся достаточно быстро).

Тогда я решил запустить простой просмотрщик веб-камер, основанный только на коде V4L2, считая, что проблема может возникать из OpenCV. Я снова испытал такую ​​же задержку, что заставляет меня поверить, что драйвер использует какой-то буфер для кэширования изображений.

Я новичок в V4L2 и мне действительно нужно, чтобы решить эту проблему как можно скорее, так что мои вопросы к вам, ребята являются:

  1. Кто-нибудь нашел решение для получения последнего изображения с помощью v4l2 (и возможно, OpenCV)?
  2. Если нет способа решить проблему с помощью V4L2, может ли кто-нибудь узнать другую альтернативу исправлению этой проблемы в Linux?

С уважением,

Михай

ответ

0

Похоже, что всегда будет задержка между VideoCapture::grab() вызова и, когда кадр фактически берется. Это происходит из-за буферизации кадров, которая выполняется на уровне аппаратного обеспечения/SO, и вы не можете этого избежать.

OpenCV предоставляет метод VideoCapture::get(CV_CAP_PROP_POS_MEC)), чтобы дать вам точное время, когда был захвачен кадр, но это возможно только в том случае, если камера поддерживает его.

Недавно была обнаружена проблема в V4L реализации OpenCV: http://answers.opencv.org/question/61099/is-it-possible-to-get-frame-timestamps-for-live-streaming-video-frames-on-linux/

И несколько дней назад исправление было тянули: https://github.com/Itseez/opencv/pull/3998

В конце концов, если вы имеете право установки, вы может знать, каково время, в которое был сделан кадр (и, следовательно, компенсировать).

0

Возможно, проблема связана с драйвером Linux UVC, но я использовал Microsoft LifeCam Cinemas для машинного зрения на машинах Ubuntu 12.04 и 14.04 и не видел задержки в 4-5 кадров. Я управляю ими в условиях низкой освещенности, но в этом случае они уменьшают частоту кадров до 7,5 кадров в секунду.

Другим возможным виновником является задержка в веб-камере в зависимости от формата. C920, похоже, поддерживает H.264 (что делает несколько веб-камер), поэтому Logitech, возможно, приложил максимум усилий, чтобы сделать эту работу хорошо, но OpenCV, похоже, не поддерживает H.264 в Linux; см. это answer, для каких форматов он поддерживает. Тот же вопрос также имеет answer с ядром (!) Для исправления проблемы с драйвером UVC.

PS: чтобы проверить формат фактически используется в моем случае, я добавил

fprintf(stderr, ">>> palette: %d\n", capture->palette); 

в this line в коде OpenCV.

Смежные вопросы