6. OpenCV шаг за шагом. Ползунок

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

При просмотре видео из прошлого шага сразу чувствуется нехватка такого полезного контрола, как линейка прокрутки :)
Поэтому рассмотрим, такую полезную функцию пользовательского интерфейса от 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

value — устанавливаемая величина

CVAPI(int) cvCreateTrackbar( const char* trackbar_name, const char* window_name, int* value, int count, CvTrackbarCallback on_change);
— создаёт ползунок и отображает его в заданном окне

trackbar_name — название ползунка
window_name — название окна, в котором будет отображаться ползунок
value — указатель на целочисленную переменную, которая хранит текущую позицию ползунка.
count — максимальная позиция ползунка (минимальная всегда 0).
on_change — указатель на функцию, которая будет вызываться каждый раз при изменении положения ползунка.

функция-обработчик должна иметь вид:
void (CV_CDECL *CvTrackbarCallback2)(int pos, void* userdata);

, где pos — текущее положение ползунка.

Дополнительные функции:
CVAPI(int) cvGetTrackbarPos( const char* trackbar_name, const char* window_name );
CVAPI(void) cvSetTrackbarPos( const char* trackbar_name, const char* window_name, int pos );
— получить/установить положение ползунка
trackbar_name — название ползунка
window_name — название окна
pos — положение

Используя эти функции можно заставить нашу программу отображать ползунком текущее положение в файле :)



Читать далее: 7. OpenCV шаг за шагом. Захват видео с камеры
  • 0
  • 14 июля 2010, 12:21
  • noonv

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

RSS свернуть / развернуть
+
0
В этом примере есть опечатка в строке:
cvCreateTrackbar(«Position», «original», ¤tPosition, frames, myTrackbarCallback);
надо заменить на:
cvCreateTrackbar(«Position», «original», ¤tPosition, frames, myTrackbarCallback);

Также хочу сказать, что при загрузки фильмов количество фреймов может быть велико, из-за этого может не работать ползунок (в CallBack-функцию всегда приходить значение 0). Поэтому мне пришлось работать не с количеством фреймов, а с количеством секунд.

А так, большое спасибо за Ваш труд.
avatar

Mur

  • 5 ноября 2010, 14:44
+
0
Спасибо за отзыв!
смотрю приведённый код и опечатки не вижу — он там именно такой, как вы и указали :)
Про количество фреймов — вы абсолютно правы.
avatar

noonv

  • 5 ноября 2010, 14:48
+
0
А не подскажите какое максимальное допустимое количество для TrackBar?

Про опечатку могу сказать следующее, попробуйте зайти на эту страницу через Chrome, я через него смотрю, и вижу неизменную картину :)
avatar

Mur

  • 5 ноября 2010, 20:38
+
0
Опечатка есть — framework не понимает, что такое ¤tPosition. Поэтому вместо строчки:

int currentPosition=0;

надо написать две строчки:

int currentPosition=0;
int* ¤tPosition = ¤tPosition;
avatar

orcchg

  • 30 ноября 2010, 00:00
+
0
int* ¤tPosition = ¤tPosition;
avatar

orcchg

  • 30 ноября 2010, 00:01
+
0
тут глюки с браузером:

int* ¤tPosition = <знак получения адреса указателя>currentPosition;
avatar

orcchg

  • 30 ноября 2010, 00:03
+
0
спасибо, полезная статейка, только сейчас уже не все актуально cvCaptureFromFile…
Появился вопрос, как сделать без извращений
отображать ползунком текущее положение в файле :)
если изменять через cvSetTrackbarPos, срабатывает callback и работает неправильно… я сделал в callback проверку как изменено, но это странно…
while(1){
                frame = cvQueryFrame( capture ); 
                if( !frame ) {
                        break;
                }
                cvShowImage( name, frame );
				manualChanged = 1;
				cvSetTrackbarPos(track, name, ++value);
                char c = cvWaitKey(33);
                if (c == 27) { // если нажата ESC - выходим
                        break;
                }
        }
avatar

vans239

  • 11 февраля 2011, 17:26
+
0
Можете поделиться кодом? У вас ползунок меняется в ходе воспроизведения видео?
avatar

JleHuH213

  • 11 ноября 2015, 13:59
+
0
Спасибо за статью! Есть вопрос: кто-нибудь работал с параметром void* userdata? хотелось бы поподробнее узнать как его правильно использовать.
Стоит задача избавиться от глобальных переменных с помощью этого параметра.
Заранее благодарен.
avatar

sergev

  • 29 февраля 2012, 14:34
+
0
cvReleaseImage(&frame); — нужно?!
avatar

ns5d

  • 18 августа 2012, 16:25
+
0
Нет. На прошлом уроке специально отмечается, что картинка возвращаемая функцией cvQueryFrame() не должна освобождаться или модифицироваться.
avatar

noonv

  • 18 августа 2012, 19:30
+
0
OpenCV шаг за шагом. Загрузка картинки:

// освобождаем ресурсы
cvReleaseImage(&image);
cvReleaseImage(&src);


по аналогии (по работе с видео) я делал:

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


зы: косяком назвать сложно, просто заметил эту деталь и стало интересно нужно ли писать или не обязательно.
avatar

ns5d

  • 18 августа 2012, 21:17
+
+1
Добрый день! почему выдает ошибку error C2065: '¤tPosition': undeclared identifier? Что не так?
avatar

avideo

  • 10 июля 2015, 09:55
+
0
парсер чудит. там должно быть (без пробела):
& currentPosition
avatar

admin

  • 10 июля 2015, 10:45
+
0
Всем неравнодушным привет! По мере возможности начал ковырять opencv. В отдельных примерах opencv и в этом тоже, требуется библиотека tbb_debug.dll. Скачал ее x86 версию — ошибка 0xc0150002, ставлю версию x64 -ошибка 0xc0000007b. Стоит win7 64, opencv 234 и VC++ 10v. Куда ковырять подскажите?
avatar

r2d2

  • 31 июля 2016, 12:10

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