8. OpenCV шаг за шагом. Запись видео


1. OpenCV шаг за шагом. Введение.
2. OpenCV шаг за шагом. Установка.
3. OpenCV шаг за шагом. Hello World.
4. OpenCV шаг за шагом. Загрузка картинки.
5. OpenCV шаг за шагом. Вывод видео
6. OpenCV шаг за шагом. Ползунок
7. OpenCV шаг за шагом. Захват видео с камеры
8. OpenCV шаг за шагом. Запись видео

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

Для этого необходимо сначала инициализировать структуру редактора с помощью функции cvCreateVideoWriter(), в качестве параметров которой передаются название файла для сохранения видео, четырёх-буквенный код видео-кодека, размер кадра и частоту кадров.
Далее при получении кадра с камеры или очередной картинки из набора изображений — он записывается в файл с помощью функции cvWriteFrame(). И в конце — нужно не забыть освободить редактор функцией cvReleaseVideoWriter().

//
// Программа получает видео с камеры и записывает в avi файл
//

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

int main(int argc, char* argv[])
{
	cvNamedWindow("capture");

	// получаем любую подключённую камеру
	CvCapture *capture = cvCreateCameraCapture(CV_CAP_ANY);
	assert(capture!=0);

	const char *filename = "capture.avi";

	// частота кадров
	//double fps = cvGetCaptureProperty (capture, CV_CAP_PROP_FPS);
	double fps = 15;

	// размер картинки
	//CvSize size = cvSize( (int)cvGetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH), (int)cvGetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT));
	CvSize size = cvSize(640, 480);

	CvVideoWriter *writer = cvCreateVideoWriter(filename, CV_FOURCC('X','V','I','D'), fps, size, 0);
	assert(writer!=0);

	IplImage *frame=0;

	while(true){
		// получаем кадр
		frame = cvQueryFrame( capture );

		// сохраняем в файл
		cvWriteFrame(writer, frame);

		// показываем
		cvShowImage("capture", frame);  
		char c = cvWaitKey(1);
		if (c == 27) { // если нажата ESC - выходим
			break;
		}
	}

	// освобождаем ресурсы
	cvReleaseCapture( &capture );
	cvReleaseVideoWriter(&writer);
	cvDestroyWindow("capture");
	return 0;
}

Обратите внимание, что заданный кодек установлен в системе.

CVAPI(CvVideoWriter*) cvCreateVideoWriter( const char* filename, int fourcc, double fps, CvSize frame_size, int is_color CV_DEFAULT(1));

— инициализация записи видео в файл
возвращает указатель на структуру редактора видео-файла:

struct CvVideoWriter
{
    virtual ~CvVideoWriter() {}
    virtual bool writeFrame(const IplImage*) { return false; }
};

filename — имя файл для записи
fourcc — 4-буквенный код кодека для обработки видео, формируется макросом CV_FOURCC:

CV_FOURCC('X','V','I','D') - кодек XviD
CV_FOURCC('P','I','M','1')    = MPEG-1
CV_FOURCC('M','J','P','G')    = motion-jpeg  (does not work well)
CV_FOURCC('M', 'P', '4', '2') = MPEG-4.2 
CV_FOURCC('D', 'I', 'V', '3') = MPEG-4.3 
CV_FOURCC('D', 'I', 'V', 'X') = MPEG-4 
CV_FOURCC('U', '2', '6', '3') = H263 
CV_FOURCC('I', '2', '6', '3') = H263I 
CV_FOURCC('F', 'L', 'V', '1') = FLV1 

fps — астота кадров созданного видео потока
frame_size — размер кадра
is_color — определяет сохранять цветное изображение (1) или в градациях серого(0) (пока только под Windows)

CVAPI(int) cvWriteFrame( CvVideoWriter* writer, const IplImage* image );

— записывает/добавляет кадр в видео-файл

writer — указатель на структуру редактора видео-файла.
image — изображение для сохранения

CVAPI(void) cvReleaseVideoWriter( CvVideoWriter** writer );

— закрывает видео-файл
writer — указатель на структуру редактора видео-файла.


Далее: 9. OpenCV шаг за шагом. События от мышки


17 комментариев на «“8. OpenCV шаг за шагом. Запись видео”»

  1. Господа, как решить проблему — видеофайл создается, имеет адекватный размер, но не проигрывается никакими плеерами (выдается ошибка — типа недопустимая операция). Пробовал указывать разные кодеки.

    Во время записи видео пишется что-то типа такого: «compiler did not align stack variables…» и т.д. что компилятор не может скомпилить libavcodec и это проблема компилятора, а не кодека.

    Подскажите, как решить проблему?
    компилятор: VS2008, OpenCV 1.1 (так же пробовал с 1.0), OS Win7x64.

    • думаю, стоит попробовать более свежую версию библиотеки 😉
      на данный момент — это 2.2 (в сборе она идёт под 2010-ю студию и чтобы заставить работать её под 2008-й её нужно пересобрать), но можете попробовать и 2.1

    • сам столкнулся с этой проблемой 🙁
      OpenCV 2.1 при попытке записи видео выпадает ошибка:

      Compiler did not align stack variables. Libavcodec has been miscompiled
      and may be very slow or crash. This is not a bug in libavcodec,
      but in the compiler. You may try recompiling using gcc >= 4.2

      примечательно, что в OpenCV 2.0 запись отрабатывает на ура 🙂

  2. Господа, я может чего-то не понимаю?..

    Если делать, как написал Nefka 1 июня 2011, всё работает… НО!!!

    В этом примере: CvCapture *var =…
    А во всех предыдущих: CvCapture* var =…

    Разница лишь в том, где * стоит после CvCapture, IplImage, char* и т д. Но если в этом примере
    все CvCapture *, IplImage * и пр. изменить на CvCapture*, IplImage* и пр., уже ничего не работает, и вылазит ошибка

    Compiler did not align stack variables. Libavcodec has been miscompiled
    and may be very slow or crash. This is not a bug in libavcodec,
    but in the compiler…,

    уже упомянутая выше.

    Win7 64
    OpenCV 2.1

    Я просто места себе не могу найти — никак не понимаю, ПОЧЕМУ оно так ((((((

    Заранее спасибо

  3. Работаю в Xcode 5.0
    Система Macintosh Маверик (OS X 10.9.2)

    Вылетает ошибка

    OpenCV Error: Assertion failed (dst.data == dst0.data) in cvCvtColor, file /Users/maksim/Downloads/opencv/modules/imgproc/src/color.cpp, line 4422
    libc++abi.dylib: terminating with uncaught exception of type cv::Exception: /Users/maksim/Downloads/opencv/modules/imgproc/src/color.cpp:4422: error: (-215) dst.data == dst0.data in function cvCvtColor

    На строчке

    cvWriteFrame(writer, frame);

    Менял writer как сказал Mur — не помогло

  4. подскажите, какими средствами можно выдать поток сделанный в opencv в виде стрима наружу. любой вариант подойдет.
    смысл. на raspberry обработал opencv изображение, а как выдать на веб сервер понять не могу. хотя бы направление подскажите.
    например на вход GStreamer как можно из opencv подать. или как проще можно

    • Вероятно, самым простым способом будет передавать картинку в формате MJPEG (Motion JPEG) — это когда, каждый кадр представляет собой изображение в формате JPEG.
      Для сжатия можно использовать cvEncodeImage(), а далее просто
      открываем серверный сокет и подключившимся клиентам отдаём заголовок и картинку.
      За основу можно взять тот же MJPG-streamer, написанный на C.

      PS вопросы, напрямую не относящиеся к теме топиков лучше задавать на форуме.

    • Спасибо за ответ. удалось получить результат. Создал ветку на форуме

  5. Все работает хорошо(debian 8 qt). Пишет 640х480 (avi). А что надо сделать, чтобы писало в 1280х720? просто поставить cvSize(1280, 720) не записывает(создает файл, но не пишет).

  6. В примере видно, что частота кадров и размер задаются конкретными числами.
    Попробовал раскомментировать строку

    double fps = cvGetCaptureProperty (capture, CV_CAP_PROP_FPS);

    Как я понял, она должна определять действительную частоту кадров (с fps=15 записанное видео у меня получается ускоренным).
    Но после этого стало появляться исключение при инициализации редактора.
    Вот такой printf:

    printf(" fps: %f\n", fps);

    сообщает

    fps: 0.000000

    Значит я неправильно вызываю cvGetCaptureProperty?
    Не подскажете, как ей пользоваться правильно?

    • посмотрите исходники OpenCV — скорее всего эта функция просто не отрабатывает

  7. Не получается сохранить видео.
    Вчера скопипастил пример, запускаю

    OpenCV Error: Unsupported format or combination of formats (cvWriteFrame() needs images with depth = IPL_DEPTH_8U and nChannels = 1.) in CvVideoWriter_FFMPEG::writerFrame, file /home/nefka/Загрузки/opencv/OpenCV-2.2.0/modules/highgui/src/cap_ffmpeg.cpp, line 1076
    terminate called after throwing an instance of ‘cv::Exception’
    what(): /home/nefka/Загрузки/opencv/OpenCV-2.2.0/modules/highgui/src/cap_ffmpeg.cpp:1076: error: (-210) cvWriteFrame() needs images with depth = IPL_DEPTH_8U and nChannels = 1. in function CvVideoWriter_FFMPEG::writerFrame

    Аварийный останов

    менял

    IplImage* frame=0;

    на

    IplImage* frame=cvCreateImage(size,IPL_DEPTH_8U,1);

    не помогает.
    Пересобрал ffmpeg и opencv, не помогло. ОС Ubuntu 10.04.
    если закомментировать строку

    cvWriteFrame(writer, frame);

    и увеличить cvWaitKey() с 1 до 33, как впредыдущем прмимере, то видео показывает.

    • Все проблема решена, 18 часов, штук пять кружек кофе, 2 Mur спасибо. Заменил

      CvVideoWriter *writer = cvCreateVideoWriter(filename, CV_FOURCC('X','V','I','D'), fps, size, 0);

      на

      CvVideoWriter *writer = cvCreateVideoWriter(filename, CV_FOURCC('X','V','I','D'), fps, size, 1);

      и все заработало

  8. при запуске ругается на

    assert(writer!=0);

    assertion failed!
    program:…
    file:
    line:62
    expension: writer!=0

    и три варианта ответа: прервать, повтор, пропустить
    если пропустить то картинка с камеры есть но не идет запись

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

Arduino

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

Разделы

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

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

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

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