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


Добавить комментарий

Arduino

Что такое Arduino?
Зачем мне Arduino?
Начало работы с Arduino
Для начинающих ардуинщиков
Радиодетали (точка входа для начинающих ардуинщиков)
Первые шаги с Arduino

Разделы

  1. Преимуществ нет, за исключением читабельности: тип bool обычно имеет размер 1 байт, как и uint8_t. Думаю, компилятор в обоих случаях…

  2. Добрый день! Я недавно начал изучать программирование под STM32 и ваши уроки просто бесценны! Хотел узнать зачем использовать переменную типа…

3D-печать AI Android Arduino Bluetooth CraftDuino DIY IDE iRobot Kinect LEGO OpenCV Open Source Python Raspberry Pi RoboCraft ROS swarm ИК автоматизация андроид балансировать бионика версия видео военный датчик дрон интерфейс камера кибервесна манипулятор машинное обучение наше нейронная сеть подводный пылесос работа распознавание робот робототехника светодиод сервомашинка собака управление ходить шаг за шагом шаговый двигатель шилд юмор

OpenCV
Робототехника
Будущее за бионическими роботами?
Нейронная сеть - введение