При просмотре видео из прошлого шага сразу чувствуется нехватка такого полезного контрола, как линейка прокрутки :)
Поэтому рассмотрим, такую полезную функцию пользовательского интерфейса от HighGUI, как ползунок.
Ползунок привязывается к конкретному окну функцией cvCreateTrackbar(). У неё, в качестве последнего параметра, передаётся указатель на функцию-обработчик, которая вызывается при изменении положения ползунка. Далее для установки положения на интересующем кадре используется функция cvSetCaptureProperty(), которая устанавливает параметры видеозахвата.
#include <cv.h>
#include <highgui.h>
#include <stdlib.h>
#include <stdio.h>
CvCapture* capture =0;
IplImage* frame =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] : "test.avi";
printf("[i] file: %s\n", filename);
// окно для отображения картинки
cvNamedWindow("original",CV_WINDOW_AUTOSIZE);
// получаем информацию о видео-файле
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;
}
// здесь можно вставить
// процедуру обработки
// показываем кадр
cvShowImage( "original", frame );
char c = cvWaitKey(33);
if (c == 27) { // если нажата ESC - выходим
break;
}
}
// освобождаем ресурсы
cvReleaseCapture( &capture );
// удаляем окно
cvDestroyWindow("original");
return 0;
}
Пример работы программы(кадр из фильма «7 кабинок»)
CVAPI(double) cvGetCaptureProperty( CvCapture* capture, int property_id );
CVAPI(int) cvSetCaptureProperty( CvCapture* capture, int property_id, double value );
— получаем/устанавливаем свойства видеозахвата.
capture — указатель на видео-структуру
property_id — идентфикатор свойств:
#define CV_CAP_PROP_POS_MSEC 0 // текущее положение в миллисекундах
#define CV_CAP_PROP_POS_FRAMES 1 // начинающийся от 0 индекс кадра, который должен быть захвачен следующим
#define CV_CAP_PROP_POS_AVI_RATIO 2 // относительное положение видео-файла 0 - начало, 1 - конец
#define CV_CAP_PROP_FRAME_WIDTH 3 // ширина изображения
#define CV_CAP_PROP_FRAME_HEIGHT 4 // высота изображения
#define CV_CAP_PROP_FPS 5 // частота кадров
#define CV_CAP_PROP_FOURCC 6 // 4-буквенный код кодека
#define CV_CAP_PROP_FRAME_COUNT 7
#define CV_CAP_PROP_FORMAT 8
#define CV_CAP_PROP_MODE 9
#define CV_CAP_PROP_BRIGHTNESS 10 // яркость изображения (только для камеры)
#define CV_CAP_PROP_CONTRAST 11 // контрастность изображения (только для камеры)
#define CV_CAP_PROP_SATURATION 12 // насыщенность изображения (только для камеры)
#define CV_CAP_PROP_HUE 13 // тон изображения (только для камеры)
#define CV_CAP_PROP_GAIN 14
#define CV_CAP_PROP_EXPOSURE 15
#define CV_CAP_PROP_CONVERT_RGB 16
#define CV_CAP_PROP_WHITE_BALANCE 17
#define CV_CAP_PROP_RECTIFICATION 18
— создаёт ползунок и отображает его в заданном окне
trackbar_name — название ползунка
window_name — название окна, в котором будет отображаться ползунок
value — указатель на целочисленную переменную, которая хранит текущую позицию ползунка.
count — максимальная позиция ползунка (минимальная всегда 0).
on_change — указатель на функцию, которая будет вызываться каждый раз при изменении положения ползунка.
В этом примере есть опечатка в строке:
cvCreateTrackbar(«Position», «original», ¤tPosition, frames, myTrackbarCallback);
надо заменить на:
cvCreateTrackbar(«Position», «original», ¤tPosition, frames, myTrackbarCallback);
Также хочу сказать, что при загрузки фильмов количество фреймов может быть велико, из-за этого может не работать ползунок (в CallBack-функцию всегда приходить значение 0). Поэтому мне пришлось работать не с количеством фреймов, а с количеством секунд.
Спасибо за статью! Есть вопрос: кто-нибудь работал с параметром void* userdata? хотелось бы поподробнее узнать как его правильно использовать.
Стоит задача избавиться от глобальных переменных с помощью этого параметра.
Заранее благодарен.
Всем неравнодушным привет! По мере возможности начал ковырять opencv. В отдельных примерах opencv и в этом тоже, требуется библиотека tbb_debug.dll. Скачал ее x86 версию — ошибка 0xc0150002, ставлю версию x64 -ошибка 0xc0000007b. Стоит win7 64, opencv 234 и VC++ 10v. Куда ковырять подскажите?
Комментарии (15)
RSS свернуть / развернутьcvCreateTrackbar(«Position», «original», ¤tPosition, frames, myTrackbarCallback);
надо заменить на:
cvCreateTrackbar(«Position», «original», ¤tPosition, frames, myTrackbarCallback);
Также хочу сказать, что при загрузки фильмов количество фреймов может быть велико, из-за этого может не работать ползунок (в CallBack-функцию всегда приходить значение 0). Поэтому мне пришлось работать не с количеством фреймов, а с количеством секунд.
А так, большое спасибо за Ваш труд.
Mur
смотрю приведённый код и опечатки не вижу — он там именно такой, как вы и указали :)
Про количество фреймов — вы абсолютно правы.
noonv
Про опечатку могу сказать следующее, попробуйте зайти на эту страницу через Chrome, я через него смотрю, и вижу неизменную картину :)
Mur
int currentPosition=0;
надо написать две строчки:
int currentPosition=0;
int* ¤tPosition = ¤tPosition;
orcchg
orcchg
int* ¤tPosition = <знак получения адреса указателя>currentPosition;
orcchg
Появился вопрос, как сделать без извращений если изменять через cvSetTrackbarPos, срабатывает callback и работает неправильно… я сделал в callback проверку как изменено, но это странно…
vans239
JleHuH213
Стоит задача избавиться от глобальных переменных с помощью этого параметра.
Заранее благодарен.
sergev
ns5d
noonv
…
// освобождаем ресурсы
cvReleaseImage(&image);
cvReleaseImage(&src);
…
по аналогии (по работе с видео) я делал:
…
// освобождаем ресурсы
cvReleaseImage(&frame);
cvReleaseCapture(&capture);
…
зы: косяком назвать сложно, просто заметил эту деталь и стало интересно нужно ли писать или не обязательно.
ns5d
avideo
admin
r2d2
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.