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 шаг за шагом. Захват видео с камеры


15 комментариев на «“6. OpenCV шаг за шагом. Ползунок”»

  1. В этом примере есть опечатка в строке:
    cvCreateTrackbar(«Position», «original», ¤tPosition, frames, myTrackbarCallback);
    надо заменить на:
    cvCreateTrackbar(«Position», «original», &currentPosition, frames, myTrackbarCallback);

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

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

    • Спасибо за отзыв!
      смотрю приведённый код и опечатки не вижу — он там именно такой, как вы и указали 🙂
      Про количество фреймов — вы абсолютно правы.

    • А не подскажите какое максимальное допустимое количество для TrackBar?

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

  2. Опечатка есть — framework не понимает, что такое ¤tPosition. Поэтому вместо строчки:

    int currentPosition=0;

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

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

    • тут глюки с браузером:

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

  3. Спасибо за статью! Есть вопрос: кто-нибудь работал с параметром void* userdata? хотелось бы поподробнее узнать как его правильно использовать.
    Стоит задача избавиться от глобальных переменных с помощью этого параметра.
    Заранее благодарен.

    • OpenCV шаг за шагом. Загрузка картинки:

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

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

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

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

    • парсер чудит. там должно быть (без пробела):

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

  5. спасибо, полезная статейка, только сейчас уже не все актуально 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;
                    }
            }
    • Можете поделиться кодом? У вас ползунок меняется в ходе воспроизведения видео?

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

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