Перейти к содержимому
Compvision.ru
Виталий

Проблема открытия видеофайла в opencv

Recommended Posts

Необходимо открыть видеофайл для обработки в формате mp4

Использую opencv 2,3 и python 2.6. Windows 7 32bit

import cv

cam=cv.CaptureFromFile("1.mp4")

Capture не создается. Пробовал другими функциями создавть - то же самое.

Не открывается файл именно формата "MP4", другие форматы(avi) открываются. медиаплеером файл проигрвается.

Смотреть в сторону кодеков?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Может сменить расширение на mpeg?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Может сменить расширение на mpeg?

Попробовал - не помогло. Использовал mpeg, mpg, avi. При этих разрешениях плеер открывал файл.

Видеофайл - ролик записанный телефоном в разрешении 1920*1080. Может в этом дело?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Может там кодек какой то нестандартный? Обычные mp4 (не с телефона) открываются?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Другие файлы в разрешении mp4 тоже не открываются в программе.(avi открывается)

Все файлы о которых идет речь проигрываются медиаплеером.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Думаю, что надо провести небольшой ликбез по поводу 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 2.3.2 (файл cap.cpp):

CV_IMPL CvCapture * cvCreateFileCapture (const char * filename)

{

    CvCapture * result = 0;


    if (! result)

        result = cvCreateFileCapture_FFMPEG_proxy (filename);


    #ifdef HAVE_XINE

    if (! result)

        result = cvCreateFileCapture_XINE (filename);

    #endif


    #ifdef HAVE_GSTREAMER

    if (! result)

        result = cvCreateCapture_GStreamer (CV_CAP_GSTREAMER_FILE, filename);

    #endif


    #ifdef HAVE_QUICKTIME

    if (! result)

        result = cvCreateFileCapture_QT (filename);

    #endif


    #ifdef HAVE_AVFOUNDATION

    if (! result)

        result = cvCreateFileCapture_AVFoundation (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 - так правильней).

  • Like 2

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

2Nuzhny

отличный ликбез! если не возражаете потом утащу в курс про OpenCV (со ссылкой, разумеется) :rolleyes:

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Не возражаю, конечно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

А не подскажете как все выглядит в связке Python 2.7 + OpenCV 2.4.10  проблема та-же не захватываются mp4, flv и некоторые avi, как и у топикстартера переименование файлов не помогает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Скорее всего кодеки не установлены.

Поставьте K-Lite codec pack, думаю должно быть достаточно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Скорее всего кодеки не установлены.

Поставьте K-Lite codec pack, думаю должно быть достаточно.

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

вот код - примитивный- 

import numpy as np
import cv2
 
cap = cv2.VideoCapture('video2.avi')
#cap = cv2.VideoCapture(0)
ret, frame = cap.read()
print 'ret=',ret
while(ret):
    # Capture frame-by-frame
    ret, frame = cap.read()
    cv2.imshow('frame',frame)
    if cv2.waitKey(1) & 0xFF == 27:
        break
 
cap.release()
cv2.destroyAllWindows()
 
с web- камеры все захватывается хорошо

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Гм. А файл-то открывается? Что будет, если абсолютный путь к нему указать?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Гм. А файл-то открывается? Что будет, если абсолютный путь к нему указать?

открывается. абсолютный путь проблему не решил. 

Заметил одну штуку... ставил ffshow. после этого стали захватываться некоторые avi. а mp4 - нет.

потом поставил ffmpeg. те авишники что раньше захватывались, захватываться перестали. сейчас поставил K-lite codec pack.

Теперь ничего больше не захватывается, кроме встроенной в ноутбук web-камеры.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

ffmpeg штука хитрая. У меня есть файлы, сжатые кодеком lagarith (сжатие без потери качества). Если рядом лежит opencv_ffmpeg.dll, то они не проигрываются. Если убрать эту dll из папки, то проигрываются. Почему? Потому что ffmpeg не умеет этот кодек, а avi контейнеры понимает. А сам кодек, если не ошибаюсь, вообще как vfw фильтр в систему ставится вместе с K-lite codec pack.

Думаю, что проблема где-то у тебя в системе, с твоим набором кодеков. Такое очень трудно будет решить нам со стороны. попробу запустить на другом компе, на нескольких разных компах. А потом сравнить их, если где-то проиграется.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

ffmpeg штука хитрая. У меня есть файлы, сжатые кодеком lagarith (сжатие без потери качества). Если рядом лежит opencv_ffmpeg.dll, то они не проигрываются. Если убрать эту dll из папки, то проигрываются. Почему? Потому что ffmpeg не умеет этот кодек, а avi контейнеры понимает. А сам кодек, если не ошибаюсь, вообще как vfw фильтр в систему ставится вместе с K-lite codec pack.

Думаю, что проблема где-то у тебя в системе, с твоим набором кодеков. Такое очень трудно будет решить нам со стороны. попробу запустить на другом компе, на нескольких разных компах. А потом сравнить их, если где-то проиграется.

мда.. а можно как-то это отдебажить? посмотреть версию кодека который питон пытается использовать, например в процессе захвата...

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Можно, но только не средствами Питона. Надо собрать OpenCV из исходников с дебажной инфой и посмотреть что выбирается в cap.cpp

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Можно, но только не средствами Питона. Надо собрать OpenCV из исходников с дебажной инфой и посмотреть что выбирается в cap.cpp

Решил. Помог совет отсюда: http://stackoverflow.com/questions/11699298/opencv-2-4-videocapture-not-working-on-windows

последовательность действий такова:

копируем все файлы из \opencv\sources\3rdparty\ffmpeg в site-packages и\или прописываем путь до них в PATH.

затем переименовываем opencv_ffmpeg.dll в opencv_ffmpegXYZ.dll где X.Y.Z - версия openCV. в моем случае 2.4.10 и файл назывался opencv_ffmpeg2410.dll. 

После этого по прежнему ничего не работает.

Далее идем в opencv\build\x64\vc10\bin и копируем  opencv_ffmpegXYZ_64.dll, заменяем им ранее скопированный opencv_ffmpeg_64.dll. Именно так, иначе не работает, т.к. файлы opencv_ffmpeg_64.dll из папок \sources\3rdparty\ffmpeg и build\x64\vc10\bin различаются.

После этого все заводится. 

Моя конфигурация: Win 8.1x64 Python 2.7x32 openCV 2.4.10x32

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте учётную запись или войдите для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать учётную запись

Зарегистрируйтесь для создания учётной записи. Это просто!

Зарегистрировать учётную запись

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу

×