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 и работа с видео


31 комментарий на «“5. OpenCV шаг за шагом. Вывод видео”»

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

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

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

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

    • хм… под версией 2.2 не пробовал — возможно это глюки именно новой версии — попробуйте под 2.1

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

  2. Добрый день! Подскажите пожалуйста в чем может быть проблема… Собрал этот пример, а видео нет, только серый квадрат. Функция cvCreateFileCapture(filename) не возвращает указатель на capture… Заранее спасибо!

    • вариантов масса. самое простое — не может найти указанный файл.

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

    • я для этого собираю отладочную версию библиотеки и просто трассирую вызов метода отладчиком.
      Так же, рекомендую перейти на более свежую версию OpenCV 😉

    • извини за может быть тупой вопрос, а как трассировать в visual studio(к сожалению никогда такого не делал)… и попробую обновить opencv до 2.0. Спасибо…

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

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

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

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

    • спасибо, я уже разобрался. В Debug наверное какой-то глюк, но под Realese все нормально.

  4. Вас не затруднит ответить на 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?

  5. Здравствуйте! Столкнулся с такой проблемой, при воспроизведении видео с помощью кода из данной статьи, видео показывает, но без звука. Почему такое может быть? подскажите пожалуйста.

    • OpenCV — библиотека для работы с видео, а не со звуком 🙂

    • Т. е. видео со звуком у меня не получится запустить по этому примеру?
      Как же мне тогда запустить видео со звуком в C++?

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

    • Сори. Вопрос закрыт. Моя невнимательность. Видео файл не там лежал)

  7. Возвращаемое изображение (frame в примере выше) не должно освобождаться или модифицироваться так как является указателем? Верно?

  8. Как можно решить эту проблему?
    [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.

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

    #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", &currentPosition, 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;
    }
    

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

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

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

    if( !frame ) {
            break;
    }
    

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

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

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
Робототехника
Будущее за бионическими роботами?
Нейронная сеть - введение