OpenCV и работа с видео


Небольшой ликбез по поводу OpenCV и работы с видео.

OpenCV поддерживает множество способов захвата и записи видео на всевозможных аппаратных и программных платформах. При этом не используются какие-то его внутренние технологии, а задействуются возможности платформы и установленных на ней библиотек.

На Windows используются родные Video for Windows (vfw) и DirectShow.

Причём vfw используется, начиная с самых ранних версий OpenCV, заканчивая самой последней. Что такое vfw? Это старая технология, корнями уходящяя в Windows 3.1, а то и позже. Декодеры для vfw сейчас почти не пишутся, вероятность проигрывания или записи файла с помощью vfw очень низка. В OpenCV для этого есть функция cvCreateFileCapture_VFW.

DirectShow использовалась в нескольких версиях OpenCV как библиотека VideoInput (см. #ifdef HAVE_VIDEOINPUT CV_CAP_DSHOW, #endif).
На сегодня, DirectShow является предпочтительным средством работы с видео в Windows. Декодеры и кодеры популярных видеокодеков, как правило, оформляют в виде DirectShow фильтров, плейеры используют их, всевозможные грабберы тоже. Что надо сделать, чтобы задействовать DirectShow в OpenCV? Очевидно, сконфигурировать CMake, установив HAVE_VIDEOINPUT в TRUE. Или самому в файле cvconfig.h найти и установить HAVE_VIDEOINPUT.

Теперь перейдём к ffmpeg. Это кроссплатформенная библиотека, которую можно использовать как в Windows, так и в Линуксе. Например, в версии OpenCV 2.3.2 ffmpeg задействуется через opencv_ffmpeg.dll. Её надо кидать в папку к своему exe. И, вроде, всё. Во всяком случае при проигрывании файла *.mp4 именно её функции использовались для декодирования видео, глубже в отладчике я не заглядывал. В предыдущих версиях OpenCV мне приходилось совершать серию шаманских действий для задействования ffmpeg.

Что ещё? А много чего!
XINE = HAVE_XINE + cvCreateFileCapture_XINE
GSTREAMER = HAVE_GSTREAMER + cvCreateCapture_GStreamer
QUICKTIME = HAVE_QUICKTIME + cvCreateFileCapture_QT
AVFOUNDATION = HAVE_AVFOUNDATION + cvCreateFileCapture_AVFoundation
И ещё можно найти, если порыскать по исходникам. То есть различные операционные системы, сторонние библиотеки, аппаратные платформы. Всё это можно найти в документации. Надо лишь установить библиотеки и сконфигурировать CMake. И проиграется практически ЛЮБОЙ файл и захватится видео практически с ЛЮБОЙ камеры.

Теперь посмотрим как оно работает в OpenCV (файл cap.cpp):
/**
 * Videoreader dispatching method: it tries to find the first
 * API that can access a given filename.
 */
CV_IMPL CvCapture * cvCreateFileCapture (const char * filename)
{
    CvCapture * result = 0;

    if (! result)
        result = cvCreateFileCapture_FFMPEG_proxy (filename);

#ifdef HAVE_VFW
    if (! result)
        result = cvCreateFileCapture_VFW (filename);
#endif

#ifdef HAVE_MSMF
    if (! result)
        result = cvCreateFileCapture_MSMF (filename);
#endif

#ifdef HAVE_XINE
    if (! result)
        result = cvCreateFileCapture_XINE (filename);
#endif

#ifdef HAVE_GSTREAMER
    if (! result)
        result = cvCreateCapture_GStreamer (CV_CAP_GSTREAMER_FILE, filename);
#endif

#if defined(HAVE_QUICKTIME) || defined(HAVE_QTKIT)
    if (! result)
        result = cvCreateFileCapture_QT (filename);
#endif

#ifdef HAVE_AVFOUNDATION
    if (! result)
        result = cvCreateFileCapture_AVFoundation (filename);
#endif

#ifdef HAVE_OPENNI
    if (! result)
        result = cvCreateFileCapture_OpenNI (filename);
#endif

    if (! result)
        result = cvCreateFileCapture_Images (filename);

    return result;
}


То есть, при проигрывании файла OpenCV пытается по очереди найти доступный декодер из тех, с которыми сконфигурирован CMake. Самая первая попытка — создание cvCreateFileCapture_FFMPEG_proxy. Если ffmpeg не находится, то на Windows вызывается функция cvCreateFileCapture_VFW (её на листинге нет, она находится внутри cvCreateFileCapture_FFMPEG_proxy). И дальше по очереди.

Что делать, если файл всё таки не проигрывается? Надо воспользоваться отладчиком. Зайти внутрь функции cvCreateFileCapture и посмотреть какие декодеры вообще задействованы и какие обламываются, хотя должны были бы работать. И, соответственно, посмотреть, почему они обламываются. Это не так сложно.
Например, я попытался проиграть, записанный на телефоне, файл *.mp4. ffmpeg не нашёл opencv_ffmpeg.dll, а vfw не захотел его открывать (что логично). Остальные библиотеки у меня не были задействованы. Поэтому я просто закинул opencv_ffmpeg.dll и всё заработало.
Если бы потребовалось проиграть QuickTime видео, то необходимо было бы найти в документации способ подключения QuickTime и выставить в cvconfig.h HAVE_QUICKTIME (либо сделать это в CMake — так правильней).

По материалам от Nuzhny

По теме
OpenCV шаг за шагом. Захват видео с камеры
Работа с камерой через библиотеку videoInput
  • 0
  • 27 ноября 2013, 12:49
  • noonv

Комментарии (0)

RSS свернуть / развернуть

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.