5. OpenCV шаг за шагом. Вывод видео

1. OpenCV шаг за шагом. Введение.
2. OpenCV шаг за шагом. Установка.
3. OpenCV шаг за шагом. Hello World.
4. OpenCV шаг за шагом. Загрузка картинки.
5. OpenCV шаг за шагом. Вывод видео

Вывод видео в OpenCV не сложнее, чем вывод одной картинки, только в данном случае потребуется использовать цикл для последовательного вывода кадров. Так же необходимо предусмотреть условия выхода из цикла, если кино нам надоест :)

Работа программы начинается с функции cvCreateFileCapture, которая предоставляет нам доступ к видео-файлу. Далее в бесконечном цикле мы последовательно получаем кадры видео один за другим с помощью функции cvQueryFrame, которая возвращает указатель на уже знакомую нам структуру картинки IplImage.
Показываем кадр в окошке, а затем при помощи функции cvWaitKey ждём 33 миллисекунды и затем цикл продолжается, если не нажата клавиша ESC.
33 выбрано не случайно — т.к. эта задержка даёт возможность просмотра 30 кадров в секунду.

#include <cv.h>
#include <highgui.h>
#include <stdlib.h>
#include <stdio.h>

IplImage* frame =0;

int main(int argc, char* argv[])
{
	// имя файла задаётся первым параметром
	char* filename = argc == 2 ? argv[1] : "test.avi";

	printf("[i] file: %s\n", filename);

	// окно для отображения картинки
	cvNamedWindow("original",CV_WINDOW_AUTOSIZE);

	// получаем информацию о видео-файле
	CvCapture* capture = cvCreateFileCapture( filename );

	while(1){
		// получаем следующий кадр
		frame = cvQueryFrame( capture ); 
		if( !frame ) {
			break;
		}

		// здесь можно вставить
		// процедуру обработки

		// показываем кадр
		cvShowImage( "original", frame );

		char c = cvWaitKey(33);
		if (c == 27) { // если нажата ESC - выходим
			break;
		}
	}

	// освобождаем ресурсы
	cvReleaseCapture( &capture );
	// удаляем окно
	cvDestroyWindow("original");
	return 0;
}


Вот пример работы программы(кадр из фильма «7 кабинок»)


CVAPI(CvCapture*) cvCreateFileCapture( const char* filename );
— функция принимает название файла для считывания и возвращает указатель на структуру CvCapture, которая содержит информацию о видео-файле.

CVAPI(IplImage*) cvQueryFrame( CvCapture* capture );
— получает и возвращает кадр с камеры или из файла. В качестве параметра получает указатель на структуру CvCapture.
! возвращаемое изображение не должно освобождаться или модифицироваться!

CVAPI(void) cvReleaseCapture( CvCapture** capture );
— освобождает память, связанную со структурой CvCapture



Ссылки:
Вывод видео на OpenCV

Читать далее: 6. OpenCV шаг за шагом. Ползунок

По теме:
OpenCV и работа с видео
  • 0
  • 12 июля 2010, 10:47
  • noonv

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

RSS свернуть / развернуть
+
0
Я столкнулся с проблемой при выводе видео. Во время работы программы количество используемой ей ОЗУ постоянно нарастает до тех пор, пока она не переполнится. Надо что-то где-то очищать на каждом проходе цикла. Только вот не пойму что. Хотя возможно проблема кроется и не в выводе видео((

#include <cv.h>
#include <highgui.h>
#include <stdlib.h>
#include <stdio.h>

#define RESIZE_COEF 1.2	//коефициент изменения размеров (>1 - уменьшить в RESIZE_COEF раз)
						//(<1 & >0 - увеличить в 1/RESIZE_COEF раз)
CvCapture* capture =0;
IplImage* frame =0;
IplImage* edge =0;
IplImage* convertedImage =0;
IplImage* dst=0;


// функция-обработчик ползунка - перемещение между кадрами
void myTrackbarCallback(int pos) {
        cvSetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES, pos);
}

int main(int argc, char* argv[])
{
        // имя файла задаётся первым параметром
        char* filename = argc == 2 ? argv[1] : "1.avi";

        printf("[i] file: %s\n", filename);

        // окно для отображения картинки
        cvNamedWindow("original",CV_WINDOW_AUTOSIZE);
		cvNamedWindow("LineDetector",CV_WINDOW_AUTOSIZE);//CV_WINDOW_AUTOSIZE);
		//cvNamedWindow("onece",

        // получаем информацию о видео-файле
        capture = cvCreateFileCapture( filename );

        // получаем число кадров
        double framesCount = cvGetCaptureProperty( capture, CV_CAP_PROP_FRAME_COUNT);
        printf("[i] count: %.0f\n", framesCount);
        int frames = (int)framesCount;

        int currentPosition=0;
        if( frames!= 0 ) {
                // показываем ползунок
                cvCreateTrackbar("Position", "original", ¤tPosition, frames, myTrackbarCallback);
        }

        while(1){
                // получаем следующий кадр
                frame = cvQueryFrame( capture ); 
                if( !frame ) {
                        break;
                }
				//изменяю размеры
				
				dst = cvCreateImage( cvSize(frame->width/RESIZE_COEF, frame->height/RESIZE_COEF), frame->depth, frame->nChannels );
				cvResize(frame, dst, frame->nChannels);
				
				edge = cvCreateImage( cvSize(dst->width,dst->height), IPL_DEPTH_8U, 1 );
				convertedImage = cvCreateImage( cvSize(dst->width,dst->height), IPL_DEPTH_8U, 1 );
				//конвертируем в градацию серого 8 бит
				cvConvertImage(dst, edge, CV_BGR2GRAY);
				//пременяем детектор линий
				cvCanny(edge, convertedImage, 100, 300, 3);
				//cvCanny(,,,,);
				

                // показываем кадр
                cvShowImage( "original", dst);
				cvShowImage("LineDetector", convertedImage);

                char c = cvWaitKey(25);
                if (c == 27) { // если нажата ESC - выходим
                        break;
                }

				//capture = 0;
        }

        // освобождаем ресурсы
        cvReleaseCapture( &capture );

        // удаляем окна
        cvDestroyWindow("original");
		cvDestroyWindow("LineDetector");
        return 0;
}


В чем тут может быть проблема?
avatar

DeVOLT

  • 17 декабря 2010, 17:44
+
0
странно, что сами не догадались — у вас в цикле каждый раз создаётся (выделяется память) сразу под две картинки dst и edge. Т.о. нужно просто в конце цикла их освобождать (или лучше — выделять память только один раз — при первом проходе цикла).
avatar

noonv

  • 17 декабря 2010, 18:13
+
0
Здравствуйте. Также столкнулся с некоторой проблемой. Ваш исходник прекрасно компилируется, но, при запуске исполняемого файла, вылазит ошибка и приложение падает. При запуске отладчика вылезает следующее:

Unhandled exception at 0x00905a4d in 03. Videofile.exe: 0xC0000005: Access violation.

Как с этим быть?

Использую Windows 7 / Visual studio 2010 / OpenCV 2.2.0
avatar

AdemRani

  • 9 марта 2011, 01:13
+
0
хм… под версией 2.2 не пробовал — возможно это глюки именно новой версии — попробуйте под 2.1
avatar

noonv

  • 16 марта 2011, 09:55
+
0
Было то же самое под дебагом, решилось подключением отладочных версий библиотек вместо релизных (opencv_core220d.lib вместо opencv_core220.lib и т.д.). Релизные библиотеки походу с ошибкой (которую вероятно уже пофиксили), попадались в интернете подобные треды.
avatar

jne100

  • 15 июня 2011, 21:11
+
0
Добрый день! Подскажите пожалуйста в чем может быть проблема… Собрал этот пример, а видео нет, только серый квадрат. Функция cvCreateFileCapture(filename) не возвращает указатель на capture… Заранее спасибо!
avatar

vlarry

  • 5 мая 2011, 09:45
+
0
вариантов масса. самое простое — не может найти указанный файл.
avatar

noonv

  • 5 мая 2011, 10:07
+
0
проверял, уже и через командную строку вбивал и напрямую… а как-то можно в opencv вывести ошибку, типа geterror или что-то такое, чтобы точно знать в чем проблема? А какие еще есть варианты? Использую OpenCv 1.0. Спасибо…
avatar

vlarry

  • 5 мая 2011, 10:11
+
0
я для этого собираю отладочную версию библиотеки и просто трассирую вызов метода отладчиком.
Так же, рекомендую перейти на более свежую версию OpenCV ;)
avatar

noonv

  • 5 мая 2011, 10:16
+
0
извини за может быть тупой вопрос, а как трассировать в visual studio(к сожалению никогда такого не делал)… и попробую обновить opencv до 2.0. Спасибо…
avatar

vlarry

  • 5 мая 2011, 10:29
+
0
поставил паузу после открытия видеофайла и увидел в консоли, что вывело ошибку:
warning: error opening file (C:\User\VP\ocv\opencv\src\highgui\cvcap_ffmpeg.cpp:452)
Непонятно что это за путь, где он ищет?
avatar

vlarry

  • 5 мая 2011, 12:09
+
0
Я так понимаю, что это ошибка в файле cvcap_ffmpeg.cpp в строке 452. Т.е. получается, что сама ошибка в либе, при сборке(по ходу в windows 7 собирали)?
avatar

vlarry

  • 5 мая 2011, 13:15
+
0
и теперь интересно, как ее обойти
avatar

vlarry

  • 5 мая 2011, 13:15
+
0
Добрый вечер! Нашел свой бок — это по поводу предыдущего поста. Но возникла другая проблема: при запуске — программа падает и выдает сообщение: «необработанное исключение и т.д. и т.п… Нарушение прав доступа при чтении 0хffffffffff»… Перед этим считывает 3 кадра… Помогите пожалуйста!!!
avatar

vlarry

  • 11 мая 2011, 15:25
+
0
Добрый! Специально для вопросов, напрямую не относящиеся к темам опубликованных статей, запущен форум.
avatar

admin

  • 11 мая 2011, 18:31
+
0
спасибо, я уже разобрался. В Debug наверное какой-то глюк, но под Realese все нормально.
avatar

vlarry

  • 12 мая 2011, 07:38
+
0
Вас не затруднит ответить на robocraft.ru/forum/viewtopic.php?f=7&t=102, почему при обращении к пикселям изображения, получаемого методом cvQueryFrame( capture ); возникает
Unhandled exception at 0x00411b05 in ImageAnalysis.exe: 0xC0000005: Access violation reading location 0x0000001c.
и
HIGHGUI ERROR: AVI: Could not seek to position 0.000?
avatar

Luminar

  • 28 октября 2011, 18:24
+
0
Здравствуйте! Столкнулся с такой проблемой, при воспроизведении видео с помощью кода из данной статьи, видео показывает, но без звука. Почему такое может быть? подскажите пожалуйста.
avatar

Dmitriy

  • 12 ноября 2011, 08:01
+
0
OpenCV — библиотека для работы с видео, а не со звуком :)
avatar

admin

  • 12 ноября 2011, 15:45
+
0
Т. е. видео со звуком у меня не получится запустить по этому примеру?
Как же мне тогда запустить видео со звуком в C++?
avatar

Dmitriy

  • 13 ноября 2011, 09:51
+
0
Здравствуйте. Есть такая проблема. Данный пример компилируется, запускается, но программа тут же закрывается не воспроизводя видео. Пишет такую ошибку: warning: Error openning file <.../.../modules/highgiu/src/cap_ffmpeg_impl.hpp:526> Что за ошибка 526? Поиск в инете ни чего не дал.
avatar

Scam

  • 20 февраля 2012, 16:59
+
0
Сори. Вопрос закрыт. Моя невнимательность. Видео файл не там лежал)
avatar

Scam

  • 20 февраля 2012, 17:04
+
0
Возвращаемое изображение (frame в примере выше) не должно освобождаться или модифицироваться так как является указателем? Верно?
avatar

nikitabugrov

  • 10 сентября 2012, 21:29
+
0
да
avatar

noonv

  • 11 сентября 2012, 08:57
+
0
Здравствуйте! Скомпилировал этот пример, но при запуске программа не показывает ничего, только выводит в консоль "[i] file: test.avi" и завершает работу. Повставлял в код printf'ов, чтобы понять, до куда до ходит программа, и выяснил, что выполняется условие:

if( !frame ) {
        break;
}

Проверял — нужный видеофайл в папке с программой, в плеере он запускается. Все кодеки вроде стоят. У меня Ubuntu 13.10 на виртуалке, версия библиотеки OpenCV — 2.4.8. На другом компьютере с настоящей, не виртуальной Убунтой 10.04 и OpenCV 2.3.1 — то же самое.
Подскажите, пожалуйста, в чем может быть проблема?
avatar

mgv

  • 7 апреля 2014, 13:09
+
0
Скорее всего — нет нужного кодека. Проверяется просто — см. OpenCV и работа с видео.
avatar

noonv

  • 7 апреля 2014, 13:15
+
0
Здравствуйте! выводит в консоль "[i] file: test.avi" и завершает работу. Как лечить?
вылетает в строке:
if( !frame )
avatar

JleHuH213

  • 10 ноября 2015, 20:14
+
0
Не удаётся считать кадр. Рекомендую пройтись отладчиком. Возможно, проблемы с кодеком.
см. OpenCV и работа с видео
avatar

admin

  • 11 ноября 2015, 09:58
+
0
Да спасибо! opencv_ffmpeg.dll в проект и всё заработало =)
avatar

JleHuH213

  • 11 ноября 2015, 12:19
+
0
Всем привет. А как можно захватить видео в opencv из стрима, который пишется в fifo?
avatar

nejtr0n

  • 14 января 2017, 19:39
+
0
Как можно решить эту проблему?
[i] file: drop.avi
[ INFO:0] VIDEOIO: Enabled backends(6, sorted by priority): FFMPEG(1000); MSMF(990); DSHOW(980); VFW(970); CV_IMAGES(960); CV_MJPEG(950)
[ WARN:0] cvCreateFileCaptureWithPreference: backend FFMPEG doesn't support legacy API anymore.
avatar

varabey

  • 11 августа 2018, 23:47

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