Visual Vibration Tracking 0.2
Загрузка...
Поиск...
Не найдено
Открытые члены | Закрытые типы | Закрытые члены | Закрытые статические члены | Закрытые данные | Полный список членов класса
Класс VibrationDetector

Класс для создания объектов-детекторов вибрации Подробнее...

#include <vibration_detector.h>

Граф связей класса VibrationDetector:
Collaboration graph
[см. легенду]

Открытые члены

 VibrationDetector (std::string input_file_name, std::string output_file_name, std::string window_name)
 Конструктор класса Подробнее...
 
void ExecuteVibrationDetection ()
 Выполняет детекцию вибрации Подробнее...
 

Закрытые типы

enum  main_mode { DEFAULT , SELECTINGROI , PAUSE }
 
enum  colored_point_mode { COLORING_DEFAULT , COLORING_BASED_ON_FREQUENCY , COLORING_BASED_ON_AMPLITUDE }
 

Закрытые члены

void ServeTheQueues ()
 Обслуживает очереди на удаление и создание. Необходимо для того, чтобы не нарушить нумерацию точек во время выполнения основного цикла Подробнее...
 
void CreateNewPoint (Point2f mouse_coordinates)
 Создаем "обычную" точку Подробнее...
 
void LeftClickHandler (Point2f mouse_coordinates)
 Обработчик левых кликов Подробнее...
 
void CreateNewColoredPoint (Point2f mouse_coordinates)
 Обработчик "цветных" точек Подробнее...
 
void DeletePoints (Point2i mouse_coordinates)
 Удаляем объект "обычную" точку Подробнее...
 
void DeleteColoredPoints ()
 Удаляем объекты "цветная" точка Подробнее...
 
void FindAndDeleteUncofidentPoints ()
 Удаляет "цветные" и "обычные" точки, если уровень доверия к нми слишком низкий Подробнее...
 
void DetectEvent (int event, int x, int y, int flags)
 callback functions for detecting the click Подробнее...
 
void DefaultModeHandler (int event, int x, int y)
 Обычный режим Подробнее...
 
void RoiSelectionModeHandler (int event, int x, int y)
 Режим выделения региона интереса Подробнее...
 
Mat MakeWarpedFrame (Mat frame, std::vector< Point2i > warping_figure)
 Удаляет перспективные искажения Подробнее...
 
void TrackAndCalc ()
 Трекает точки алгоритмом Лукаса-Канаде и вызывает БПФ Подробнее...
 
std::vector< Point2f > FindGoodFeatures (Mat frame, Rect roi)
 Находит подходящие для трекинга точки на изображении Подробнее...
 
void DrawDebugLkWinRectangle (Mat &frame)
 Рисует точки и выводит данные Подробнее...
 
void DrawAndOutput (Mat &frame)
 Масштабирует, рисует и выводит на экран обработанный кадр с точками Подробнее...
 

Закрытые статические члены

static void OnMouse (int event, int x, int y, int flags, void *userdata)
 callback functions for detecting the click Подробнее...
 

Закрытые данные

FrameHandlerframe_handler
 Фреймпроцессор Подробнее...
 
bool running_
 Флаг запущенного основного алгоритма Подробнее...
 
float res_mp_
 Коэффициент автоскейла размеров окна в зависимости от разрешения исходного видео Подробнее...
 
int point_id_
 Псевдо-id (порядковывй номер точки) Подробнее...
 
Point last_mouse_position_
 Последняя позиция курсора в главном окне Подробнее...
 
int current_mode_
 Основной режим работы (enum main_mode) Подробнее...
 
bool fullscreen_
 Флаг для полноэкранного режима Подробнее...
 
std::vector< Point2i > l_click_queue_
 Очередь на создание "обычных" точек Подробнее...
 
std::vector< Point2f > c_point_queue_
 Очередь на создание "цветных" точек Подробнее...
 
std::vector< Point2i > delete_queue_
 Очередь на удаление точек Подробнее...
 
std::vector< Point2i > histograms_queue_
 Очередь на отрисовку гистограм Подробнее...
 
std::vector< LonelyPointHandler * > vec_lonely_point_handlers_
 Вектор обработчиков "одиноких" точек Подробнее...
 
std::vector< ColoredPointHandler * > vec_colored_point_handlers_
 Вектор обработчиков "цветных" точек Подробнее...
 
int sensivity_in_percents_
 Чувствительность при трекинге вибрации Подробнее...
 
Mat current_tracking_frame_
 Текущий Mat-instance только что найденного кадра из видео Подробнее...
 
Mat frame_to_be_shown_
 Mat-instance, который будет показан в окне Подробнее...
 
Mat grad_scale_
 Изображение цветной шкалы внизу экрана Подробнее...
 
int colored_point_mode_
 Текущий режим подсветки точек при выбранном регионе интереса (по амплитуде/по частоте) Подробнее...
 
bool roi_selecting_
 Флаг, показывающий происходит ли в данный момент выделение ROI. Подробнее...
 
bool roi_selected_
 Флаг, показывающий был ли выделен ROI или нет Подробнее...
 
Point2i tl_click_coords_
 Координаты первой точки прямоугольник (top left, bottom left, top right, bottom right - смотря "в какую сторону" выделять ROI с помощью мыши (курсора)) Подробнее...
 
std::string input_file_name_
 Имя (путь) входного видео Подробнее...
 
std::string output_file_name_
 Имя (путь) видео, в котором будет результат детектинга Подробнее...
 
std::string output_csv_file_name_
 Имя (путь) файла для хранения метаданных Подробнее...
 
std::string window_name_
 Имя главного окна Подробнее...
 
bool warping_figure_selecting_
 Флаг, показывающий, происходит ли в данный момент выделение фигуры (эта возможность отключена временно) Подробнее...
 
std::vector< Point > warping_figure_
 Координаты фигуры для исправления перспективы Подробнее...
 
Mat prev_img_gray_
 Предыдущий кадр видео в грейскейл и с небольшим блюром (FrameHandler::MakeGrayFrame()) Подробнее...
 
Mat next_img_gray_
 Следующий (или текущий после "предыдущего" - смотря как удобнее для понимания) кадр видео в грейскейл и с небольшим блюром (FrameHandler::MakeGrayFrame()) Подробнее...
 
int lk_win_size_
 Размер окна для алгоритма Лукаса-Канаде Подробнее...
 
int level_amount_
 Количество слоев пирамиды изображений в алгоритме Л-К Подробнее...
 
int fps_
 ФПС входного видео (две ширины полосы частот вибрации, которые можно отследить) Подробнее...
 
double frame_time_
 Текущее время кадра в мс (таймкод) Подробнее...
 

Подробное описание

Класс для создания объектов-детекторов вибрации

Объект класса является основной единицей в программе. Внутри себя создает объекты различных классов, описанных в заголовочных файлах проекта. См.

См. определение в файле vibration_detector.h строка 27

Перечисления

◆ colored_point_mode

енум, описывающий режимы подсветки цветных точек

См. определение в файле vibration_detector.h строка 41

42 {
43 COLORING_DEFAULT,
44 COLORING_BASED_ON_FREQUENCY,
45 COLORING_BASED_ON_AMPLITUDE
46 };

◆ main_mode

перечисление, описывающее глобальные режимы (дефолтный, режим выбирания региона интереса и пауза)

См. определение в файле vibration_detector.h строка 32

33 {
34 DEFAULT,
35 SELECTINGROI,
36 PAUSE
37 };

Конструктор(ы)

◆ VibrationDetector()

VibrationDetector::VibrationDetector ( std::string  input_file_name,
std::string  output_file_name,
std::string  window_name 
)

Конструктор класса

См. определение в файле vibration_detector.cpp строка 3

3 :
4 input_file_name_{ input_file_name },
5 output_file_name_{ output_file_name },
6 window_name_{ window_name },
8 colored_point_mode_{ COLORING_BASED_ON_FREQUENCY },
10 roi_selecting_{ false },
11 point_id_{ 0 },
12 current_mode_{ DEFAULT },
13 fullscreen_{ false }
14{
15 roi_selected_ = false;
16 lk_win_size_ = 40;
17 level_amount_ = 1;
18
20
22
24}
Класс для чтения и сохранения кадров видео, а также различной их обработки
Definition: frame_handler.h:29
float GetTextResizeFactor()
Возвращает коэффициент масштабирования
std::string window_name_
Имя главного окна
int level_amount_
Количество слоев пирамиды изображений в алгоритме Л-К
bool warping_figure_selecting_
Флаг, показывающий, происходит ли в данный момент выделение фигуры (эта возможность отключена временн...
int sensivity_in_percents_
Чувствительность при трекинге вибрации
bool fullscreen_
Флаг для полноэкранного режима
FrameHandler * frame_handler
Фреймпроцессор
float res_mp_
Коэффициент автоскейла размеров окна в зависимости от разрешения исходного видео
std::string input_file_name_
Имя (путь) входного видео
std::string output_file_name_
Имя (путь) видео, в котором будет результат детектинга
bool roi_selecting_
Флаг, показывающий происходит ли в данный момент выделение ROI.
int lk_win_size_
Размер окна для алгоритма Лукаса-Канаде
int current_mode_
Основной режим работы (enum main_mode)
std::string output_csv_file_name_
Имя (путь) файла для хранения метаданных
int point_id_
Псевдо-id (порядковывй номер точки)
int colored_point_mode_
Текущий режим подсветки точек при выбранном регионе интереса (по амплитуде/по частоте)
bool roi_selected_
Флаг, показывающий был ли выделен ROI или нет
std::string GenerateCsvFilename(std::string additional_text="")
Генерирует имя CSV файла для сохранения метаданных
Definition: helper.cpp:3

◆ ~VibrationDetector()

VibrationDetector::~VibrationDetector ( )

См. определение в файле vibration_detector.cpp строка 26

27{
28 delete frame_handler;
30 while (!vec_lonely_point_handlers_.empty())
31 {
32 delete(*(std::begin(vec_lonely_point_handlers_)));
33 // удаляем первую точку (первую в векторе и по сути первую по номеру)
35 }
36}
std::vector< LonelyPointHandler * > vec_lonely_point_handlers_
Вектор обработчиков "одиноких" точек
void DeleteColoredPoints()
Удаляем объекты "цветная" точка

Методы

◆ CreateNewColoredPoint()

void VibrationDetector::CreateNewColoredPoint ( Point2f  mouse_coordinates)
private

Обработчик "цветных" точек

См. определение в файле vibration_detector.cpp строка 108

109{
110 ColoredPointHandler* point_handler_ = new ColoredPointHandler(mouse_coordinates, fps_, point_id_++, res_mp_, output_csv_file_name_);
111 vec_colored_point_handlers_.push_back(point_handler_);
112}
Дочерний (от VibratingPoint) класс. Предназначен для помещения множества цветных точек на кадр и отсл...
int fps_
ФПС входного видео (две ширины полосы частот вибрации, которые можно отследить)
std::vector< ColoredPointHandler * > vec_colored_point_handlers_
Вектор обработчиков "цветных" точек

◆ CreateNewPoint()

void VibrationDetector::CreateNewPoint ( Point2f  mouse_coordinates)
private

Создаем "обычную" точку

См. определение в файле vibration_detector.cpp строка 57

58{
59 LonelyPointHandler* point_handler_ = new LonelyPointHandler(mouse_coordinates, fps_, point_id_++, res_mp_, output_csv_file_name_);
60 vec_lonely_point_handlers_.push_back(point_handler_);
61}
Дочерний (от VibratingPoint) класс. Предназначен для помещения точки на кадр и отслеживания её вибрац...

◆ DefaultModeHandler()

void VibrationDetector::DefaultModeHandler ( int  event,
int  x,
int  y 
)
private

Обычный режим

См. определение в файле vibration_detector.cpp строка 245

246{
247 switch (event)
248 {
249 case EVENT_LBUTTONDOWN:
250 {
251 // Проверяем флаги выделения ROI и фигуры для варпа
252 if (!roi_selecting_)
253 {
254 l_click_queue_.push_back(Point2i(x, y));
255 }
256 break;
257 }
258 case EVENT_RBUTTONDOWN:
259 {
261 delete_queue_.push_back(Point2i(x, y));
262 break;
263 }
264 case EVENT_MOUSEMOVE:
265 {
266 // Координаты последнего перемещения мыши
269 }
270 }
271}
std::vector< Point2i > delete_queue_
Очередь на удаление точек
std::vector< Point2i > l_click_queue_
Очередь на создание "обычных" точек
Point last_mouse_position_
Последняя позиция курсора в главном окне

◆ DeleteColoredPoints()

void VibrationDetector::DeleteColoredPoints ( )
private

Удаляем объекты "цветная" точка

См. определение в файле vibration_detector.cpp строка 177

178{
179 // Проходимся по вектору хэндлеров
180 while (!vec_colored_point_handlers_.empty())
181 {
182 delete(*(std::begin(vec_colored_point_handlers_)));
183 // удаляем первую точку (первую в векторе и по сути первую по номеру)
185 }
186
187 if (vec_lonely_point_handlers_.empty())
188 {
191 }
192}
static std::pair< double, double > extremum_amplitude_
Максимум и минимум амплитуды среди всех VibratingPoint объектов-наследников

◆ DeletePoints()

void VibrationDetector::DeletePoints ( Point2i  mouse_coordinates)
private

Удаляем объект "обычную" точку

См. определение в файле vibration_detector.cpp строка 114

115{
116 // создаем вектор ID (номеров) для точек, которые удалим
117 std::vector<int> lon_point_ids_to_be_deleted_;
118 std::vector<int> col_point_ids_to_be_deleted_;
119
120 // проходим по всему вектору точек
121 for (int i = 0; i < vec_lonely_point_handlers_.size(); i++)
122 {
123 // если произошло пересечение с мышкой, вносим ID (номер) точки в "вектор точек на удаление" или уровень доверия" точки стал слишком маленький, так же удаляем точку
125 {
126 lon_point_ids_to_be_deleted_.push_back(i);
127 }
128 }
129 for (int i = 0; i < vec_colored_point_handlers_.size(); i++)
130 {
131 // если произошло пересечение с мышкой, вносим ID (номер) точки в "вектор точек на удаление" или уровень доверия" точки стал слишком маленький, так же удаляем точку
133 {
134 col_point_ids_to_be_deleted_.push_back(i);
135 }
136 }
137 std::cout << "DEBUG: deleting " << lon_point_ids_to_be_deleted_.size() + col_point_ids_to_be_deleted_.size() << " point" << std::endl;
138
139 // проходимся по вектору точек на удаление
140 while (!lon_point_ids_to_be_deleted_.empty())
141 {
142 delete(*(std::begin(vec_lonely_point_handlers_) + lon_point_ids_to_be_deleted_[0]));
143 // удаляем первую точку (первую в векторе и по сути первую по номеру)
144 vec_lonely_point_handlers_.erase(std::begin(vec_lonely_point_handlers_) + lon_point_ids_to_be_deleted_[0]);
145 // удаляем номер только что удалённой точки из вектора
146 lon_point_ids_to_be_deleted_.erase(std::begin(lon_point_ids_to_be_deleted_));
147 // меняем номера других точек в списке, если там ещё что-то есть
148 for (int i = 0; i < lon_point_ids_to_be_deleted_.size(); i++)
149 {
150 // уменьшаем номер оставшихся в очереди на удаление точек на один, тк номера в vec_point_handlers сместились на один вниз (влево и тп, как удобнее для понимания :))
151 lon_point_ids_to_be_deleted_[i] = lon_point_ids_to_be_deleted_[i] - 1;
152 }
153 }
154
155 while (!col_point_ids_to_be_deleted_.empty())
156 {
157 delete(*(std::begin(vec_colored_point_handlers_) + col_point_ids_to_be_deleted_[0]));
158 // удаляем первую точку (первую в векторе и по сути первую по номеру)
159 vec_colored_point_handlers_.erase(std::begin(vec_colored_point_handlers_) + col_point_ids_to_be_deleted_[0]);
160 // удаляем номер только что удалённой точки из вектора
161 col_point_ids_to_be_deleted_.erase(std::begin(col_point_ids_to_be_deleted_));
162 // меняем номера других точек в списке, если там ещё что-то есть
163 for (int i = 0; i < col_point_ids_to_be_deleted_.size(); i++)
164 {
165 // уменьшаем номер оставшихся в очереди на удаление точек на один, тк номера в vec_point_handlers сместились на один вниз (влево и тп, как удобнее для понимания :))
166 col_point_ids_to_be_deleted_[i] = col_point_ids_to_be_deleted_[i] - 1;
167 }
168 }
169
170 if (vec_lonely_point_handlers_.empty())
171 {
174 }
175}
bool IsInteracted(Point2i coordinates)
Проверяет точку на наличие взаимодействия с ней (если курсор попал в область взаимодействия точки Vib...

◆ DetectEvent()

void VibrationDetector::DetectEvent ( int  event,
int  x,
int  y,
int  flags 
)
private

callback functions for detecting the click

См. определение в файле vibration_detector.cpp строка 224

225{
226 switch (current_mode_)
227 {
228 case DEFAULT:
229 {
230 DefaultModeHandler(event, x, y);
231 break;
232 }
233 case SELECTINGROI:
234 {
235 RoiSelectionModeHandler(event, x, y);
236 break;
237 }
238 case PAUSE:
239 {
240 break;
241 }
242 }
243}
void DefaultModeHandler(int event, int x, int y)
Обычный режим
void RoiSelectionModeHandler(int event, int x, int y)
Режим выделения региона интереса

◆ DrawAndOutput()

void VibrationDetector::DrawAndOutput ( Mat &  frame)
private

Масштабирует, рисует и выводит на экран обработанный кадр с точками

См. определение в файле vibration_detector.cpp строка 465

466{
467 // Рассматриваем вариант, при котором выбран ROI для цветных (colored) точек
468 if (roi_selected_)
469 {
470 // Перемещение изображение на переднем плане на X единиц (px)
471 int x_translation = frame.cols - grad_scale_.cols;
472 // Перемещение изображение на переднем плане на Y единиц (px)
473 int y_translation = frame.rows - grad_scale_.rows;
474 // Вектор этого перемещения
475 Point2i translation_vector = Point2i(x_translation, y_translation);
476 // Вставляем градиент на кадр
477 frame = frame_handler->PutFrameOverFrame(grad_scale_, frame, translation_vector);
478 }
479 // Масштабируем кадр для вывода на экран и добавляем на него подсказки для пользователя
480 frame.copyTo(frame_to_be_shown_);
482 // Выводим кадр на экран
484}
Mat AddTips(Mat frame, int mode)
Добавляет (отрисовывает) подсказки для пользователя на кадр
void ShowFrame(Mat frame, bool fullscreen)
Выводит в главное окно принимаемое изображение
Mat PutFrameOverFrame(Mat foreground_frame, Mat background_frame, Point2i translation_vector)
Накладывает изображение (переднний план) на другое изображение (задний план)
Mat grad_scale_
Изображение цветной шкалы внизу экрана
Mat frame_to_be_shown_
Mat-instance, который будет показан в окне

◆ DrawDebugLkWinRectangle()

void VibrationDetector::DrawDebugLkWinRectangle ( Mat &  frame)
private

Рисует точки и выводит данные

См. определение в файле vibration_detector.cpp строка 487

488{
489
490 for (int i = 0; i < vec_lonely_point_handlers_.size(); i++)
491 {
492 // DEBUG
493 Rect debug_lk_win_size = Rect(
494 Point2i(vec_lonely_point_handlers_[i]->GetLastFoundCoordinates().x - lk_win_size_, vec_lonely_point_handlers_[i]->GetLastFoundCoordinates().y - lk_win_size_),
495 Point2i(vec_lonely_point_handlers_[i]->GetLastFoundCoordinates().x + lk_win_size_, vec_lonely_point_handlers_[i]->GetLastFoundCoordinates().y + lk_win_size_)
496 );
497 rectangle(frame, debug_lk_win_size, Scalar(0, 0, 255), 1);
498 }
499}

◆ ExecuteVibrationDetection()

void VibrationDetector::ExecuteVibrationDetection ( )

Выполняет детекцию вибрации

См. определение в файле vibration_detector.cpp строка 501

502{
507
508 // reading the first frame of sequence so we can convert it to gray color space
511
514
515 // Генерируем шкалу
517
518 // conditions of exit
519 running_ = true;
520 int current_num_of_frame = 0;
521 int amount_of_frames = frame_handler->GetAmountOfFrames();
522
523 // устанавливаем callback handler на основное окно
524 setMouseCallback(frame_handler->GetMainWindowName(), OnMouse, (void*)this);
525
526 while ((current_num_of_frame < amount_of_frames - 1) && running_ == true)
527 {
528 current_num_of_frame = frame_handler->GetCurrentPosOfFrame();
529
530 // reading next frame and converting it to gray color space
532
534 if (!warping_figure_.empty())
535 {
537 }
538
540
541 // Трекинг и вычисление частоты вибрации
543
544 TrackAndCalc();
545
546 // Рисование точек, треков и данных (вибрации, амплитуды и т.п.)
547 for (int i = 0; i < vec_lonely_point_handlers_.size(); i++)
548 {
549 vec_lonely_point_handlers_[i]->VibratingPoint::IsInteracted(last_mouse_position_);
551 }
552 for (int i = 0; i < vec_colored_point_handlers_.size(); i++)
553 {
554 // Обновляем максимальную амплитуду
555 vec_colored_point_handlers_[i]->VibratingPoint::IsInteracted(last_mouse_position_);
558 }
559
560 // обслуживаем и очищаем очереди на создание и удаление точек
562
564
565 // Записываем изначальный кадр
567
568 // Обновляем предыдущий кадр
570
571 // 20 - задержка в мс
572 int code = waitKey(20);
573 switch (code)
574 {
575 // Пауза
576 // Клавиши - пробел (ASCII code)
577 case 32:
578 {
579 current_mode_ = PAUSE;
580
582
583 waitKey(0);
584 current_mode_ = DEFAULT;
585 break;
586 }
587 case 'c':
588 {
589 Mat unchanged_frame = current_tracking_frame_;
591
592 warping_figure_.clear();
594
596 {
597 for (int i = 0; i < warping_figure_.size(); i++)
598 {
599 circle(unchanged_frame, warping_figure_[i], 10, Scalar(255, 207, 64), 2);
600 }
601
602 if (warping_figure_.size() == 4)
604
605 frame_handler->ShowFrame(unchanged_frame, fullscreen_);
606 waitKey(20);
607 }
608 break;
609 }
610 // Изменение чувствительности (VibratingPoint::sensivity_ -> влияет на VibratingPoint::confidence_level_)
611 // Клавиши - "A" или "a" (ASCII code)
612 // A - for adjust
613 case 65:
614 case 97:
615 {
616 current_mode_ = PAUSE;
617
619
620 namedWindow("Sensivity Window", WINDOW_FULLSCREEN);
621 createTrackbar("Sensivity", "Sensivity Window", &sensivity_in_percents_, 100, NULL);
622
623 waitKey(0);
624
625 destroyWindow("Sensivity Window");
626
627 for (int i = 0; i < vec_lonely_point_handlers_.size(); i++)
628 {
629 vec_lonely_point_handlers_[i]->SetSensivity(2.0 / static_cast<double>(10 * sensivity_in_percents_));\
630 }
631 for (int i = 0; i < vec_colored_point_handlers_.size(); i++)
632 {
633 vec_colored_point_handlers_[i]->SetSensivity(2.0 / static_cast<double>(10 * sensivity_in_percents_));
634 }
635
636 current_mode_ = DEFAULT;
637 break;
638 }
639 // Фуллскрин.
640 // Клавиши - "F" или "f" (ASCII code)
641 case 102:
642 case 70:
643 {
644 // Проверка на флаг полноэкранного режима. Если он изначально был false, меняем на true, и наоборот в противном случае
645 if (!fullscreen_)
646 {
647 fullscreen_ = true;
648 }
649 else
650 {
651 fullscreen_ = false;
652 }
653 break;
654 }
655 // Изменение режима подсветки точек при активном регионе интереса (ROI)
656 // Клавиши - "M" или "m" (ASCII code)
657 case 77:
658 case 109:
659 {
660 // Перебираем режимы по порядку
661 if (colored_point_mode_ == 2)
663 else
665
667 break;
668 }
669 // Выделение региона интереса (ROI)
670 // Клавиши - "R" или "r" (ASCII code)
671 case 82:
672 case 114:
673 {
674 // Обновляем текущий режим
675 current_mode_ = SELECTINGROI;
676 // Регион интереса
677 Rect roi;
678 // Сбрасываеи флаг выделенного региона интереса
679 roi_selected_ = false;
680 // Флаг выхода из режима
681 bool wanna_quit = false;
682
683 while (!roi_selected_ && !wanna_quit)
684 {
685 // создаю копию current_tracking_frame_
686 Mat frame = current_tracking_frame_.clone();
687
688 // Пока происходит выделение региона интереса (в нашем случае пока не была отпущена ЛКМ), отрисовываем прямоугольник
689 if (roi_selecting_)
690 {
692 rectangle(frame, roi, Scalar(0, 255, 0), 1 * (1 / res_mp_));
693 }
694
695 DrawAndOutput(frame);
696
697 switch (waitKey(20))
698 {
699 // R for reset
700 case 'r':
701 {
702 wanna_quit = true;
703 // Удаляем старые "цветные" точки
705 break;
706 }
707 // Esc
708 case 27:
709 {
710 wanna_quit = true;
711 break;
712 }
713 }
714 }
715 // ROI может быть пустым после выхода из цикла выше кейсом в свитче
716 if (!roi.empty())
718
719 current_mode_ = DEFAULT;
720 break;
721 }
722 case 'q':
723 {
724 running_ = false;
725 std::cout << frame_handler->GetInputCapStatus() << std::endl;
726 break;
727 }
728 }
729 }
730}
int GetAmountOfFrames()
Возвращает общее количество кадров
String GetMainWindowName()
Возвращает название главного окна, в которое выводятся кадры
bool GetInputCapStatus()
Возвращает текущий статус input_cap.
Mat GetCurrentFrame()
Возвращает последний прочитанный на данный момент кадр
void ReadNextFrame()
Считывает следующий кадр видео
void WriteFrame(Mat frame)
Записывает кадр с помощью output_cap.
Mat MakeGrayFrame(Mat frame_to_be_grayed)
Возвращает серый кадр с блюром
double GetCurrentTimeOfFrame()
Возвращает текущее время кадра (таймкод в мс)
int GetInputFps()
Возвращает FPS считываемого видео
int GetCurrentPosOfFrame()
Возвращает текущее положение кадра относительно первого
Mat GenerateGradScale(int left_limit, int right_limit, int colored_point_mode)
Генерирует шкалу с градиентом и подписями. Ширина шкалы - ширина исходного видео. Высота регулируется...
Mat next_img_gray_
Следующий (или текущий после "предыдущего" - смотря как удобнее для понимания) кадр видео в грейскейл...
static void OnMouse(int event, int x, int y, int flags, void *userdata)
callback functions for detecting the click
Mat prev_img_gray_
Предыдущий кадр видео в грейскейл и с небольшим блюром (FrameHandler::MakeGrayFrame())
Mat current_tracking_frame_
Текущий Mat-instance только что найденного кадра из видео
std::vector< Point2f > c_point_queue_
Очередь на создание "цветных" точек
double frame_time_
Текущее время кадра в мс (таймкод)
std::vector< Point2f > FindGoodFeatures(Mat frame, Rect roi)
Находит подходящие для трекинга точки на изображении
void TrackAndCalc()
Трекает точки алгоритмом Лукаса-Канаде и вызывает БПФ
std::vector< Point > warping_figure_
Координаты фигуры для исправления перспективы
bool running_
Флаг запущенного основного алгоритма
void DrawAndOutput(Mat &frame)
Масштабирует, рисует и выводит на экран обработанный кадр с точками
Mat MakeWarpedFrame(Mat frame, std::vector< Point2i > warping_figure)
Удаляет перспективные искажения
Point2i tl_click_coords_
Координаты первой точки прямоугольник (top left, bottom left, top right, bottom right - смотря "в как...
void ServeTheQueues()
Обслуживает очереди на удаление и создание. Необходимо для того, чтобы не нарушить нумерацию точек во...

◆ FindAndDeleteUncofidentPoints()

void VibrationDetector::FindAndDeleteUncofidentPoints ( )
private

Удаляет "цветные" и "обычные" точки, если уровень доверия к нми слишком низкий

См. определение в файле vibration_detector.cpp строка 194

195{
196 for (int i = 0; i < vec_lonely_point_handlers_.size(); i++)
197 {
198 if (vec_lonely_point_handlers_[i]->GetCurrentConfidenceLevel() < 0.0)
199 {
200 delete(*(std::begin(vec_lonely_point_handlers_) + i));
201 // удаляем первую точку (первую в векторе и по сути первую по номеру)
203 }
204 }
205 for (int i = 0; i < vec_colored_point_handlers_.size(); i++)
206 {
207 if ((vec_colored_point_handlers_[i]->GetCurrentConfidenceLevel() < 0.0))
208 {
209 delete(*(std::begin(vec_colored_point_handlers_) + i));
210 // удаляем первую точку (первую в векторе и по сути первую по номеру)
212 }
213 }
214}

◆ FindGoodFeatures()

std::vector< Point2f > VibrationDetector::FindGoodFeatures ( Mat  frame,
Rect  roi 
)
private

Находит подходящие для трекинга точки на изображении

См. определение в файле vibration_detector.cpp строка 432

433{
434 std::vector<Point2f> good_features;
435 // Если изображение не черно-белое
436 if (frame.channels() > 2)
437 cvtColor(frame, frame, COLOR_BGR2GRAY);
438
439 // Устанавливаем ROI на нашем изображении
440 Mat frame_with_roi = frame(roi);
441 goodFeaturesToTrack(frame_with_roi, good_features, 1000, 0.1, 20, noArray(), 3);
442
443 // Перевод в координаты изначального изображения
444 for (int i = 0; i < good_features.size(); i++)
445 {
446 good_features[i].x = good_features[i].x + roi.tl().x;
447 good_features[i].y = good_features[i].y + roi.tl().y;
448 }
449
450 ContourHandler contour_handler(frame, &roi);
451 std::vector<Point2f> features_to_be_append = contour_handler.GetContinousContours();
452
453 auto itt = features_to_be_append.begin();
454 int count = 0;
455 while (itt != features_to_be_append.end())
456 {
457 good_features.push_back(*itt);
458 itt++;
459 count++;
460 }
461
462 return good_features;
463}
Класс для создания объектов-обработчиков контуров.

◆ LeftClickHandler()

void VibrationDetector::LeftClickHandler ( Point2f  mouse_coordinates)
private

Обработчик левых кликов

См. определение в файле vibration_detector.cpp строка 63

64{
65 // если вектор пустой - просто добавляем новую точку
67 {
68 bool flag_colored_interacted_ = false;
69 for (int i = 0; i < vec_colored_point_handlers_.size(); i++)
70 {
72 {
73 vec_colored_point_handlers_[i]->SetHistogramFlag(true);
74 flag_colored_interacted_ = true;
75 }
76 }
77 if (flag_colored_interacted_ == false)
78 CreateNewPoint(mouse_coordinates);
79 }
80 else
81 {
82 // проходим по всему вектору точек
83 bool flag_lonely_interacted_ = false;
84 bool flag_colored_interacted_ = false;
85 for (int i = 0; i < vec_lonely_point_handlers_.size(); i++)
86 {
87 // если произошло пересечение с мышкой, то новую точку не добавляем
89 {
90 vec_lonely_point_handlers_[i]->SetHistogramFlag(true);
91 //vec_lonely_point_handlers_[i]->SetHistogramWindowProperty(WND_PROP_TOPMOST, true);
92 flag_lonely_interacted_ = true;
93 }
94 }
95 for (int i = 0; i < vec_colored_point_handlers_.size(); i++)
96 {
98 {
99 vec_colored_point_handlers_[i]->SetHistogramFlag(true);
100 flag_colored_interacted_ = true;
101 }
102 }
103 if (flag_lonely_interacted_ == false && flag_colored_interacted_ == false)
104 CreateNewPoint(mouse_coordinates);
105 }
106}
void CreateNewPoint(Point2f mouse_coordinates)
Создаем "обычную" точку

◆ MakeWarpedFrame()

Mat VibrationDetector::MakeWarpedFrame ( Mat  frame,
std::vector< Point2i >  warping_figure 
)
private

Удаляет перспективные искажения

См. определение в файле vibration_detector.cpp строка 310

311{
312 int coeff = 1;
313
314 Point2f src[4] = { warping_figure[0], warping_figure[1], warping_figure[2], warping_figure[3] };
315
316 for (int i = 0; i < 4; i++)
317 {
318 src[i].x = src[i].x * coeff;
319 src[i].y = src[i].y * coeff;
320 warping_figure[i].x = warping_figure[i].x * coeff;
321 warping_figure[i].y = warping_figure[i].y * coeff;
322 }
323
324 /*float w =
325 sqrt((warping_figure[2].x - warping_figure[3].x) * (warping_figure[2].x - warping_figure[3].x)
326 +
327 (warping_figure[2].y - warping_figure[3].y) * (warping_figure[2].y - warping_figure[3].y)) * 2 / 3;*/
328 float h =
329 sqrt((warping_figure[1].x - warping_figure[3].x) * (warping_figure[1].x - warping_figure[3].x)
330 +
331 (warping_figure[1].y - warping_figure[3].y) * (warping_figure[1].y - warping_figure[3].y));
332 float w = h * 2 / 3;
333
334 Point2f dst[4] = { {0.0f,0.0f},{w,0.0f},{0.0f,h},{w,h} };
335
336 Mat matrix = getPerspectiveTransform(src, dst);
337 warpPerspective(frame, frame, matrix, Point(w, h));
338
339 return frame;
340}

◆ OnMouse()

void VibrationDetector::OnMouse ( int  event,
int  x,
int  y,
int  flags,
void *  userdata 
)
staticprivate

callback functions for detecting the click

См. определение в файле vibration_detector.cpp строка 217

218{
219 VibrationDetector* d = static_cast<VibrationDetector*>(userdata);
220 d->DetectEvent(event, x, y, flags);
221}
Класс для создания объектов-детекторов вибрации
void DetectEvent(int event, int x, int y, int flags)
callback functions for detecting the click

◆ RoiSelectionModeHandler()

void VibrationDetector::RoiSelectionModeHandler ( int  event,
int  x,
int  y 
)
private

Режим выделения региона интереса

См. определение в файле vibration_detector.cpp строка 272

273{
274 switch (event)
275 {
276 case EVENT_LBUTTONDOWN:
277 {
278 // Удаляем старые "цветные" точки
280 // Делаем флаг для выделения ROI активным
281 roi_selecting_ = true;
282 // Сохраняем координаты клика как одну из границ ROI
283 tl_click_coords_.x = x;
284 tl_click_coords_.y = y;
285 break;
286 }
287 case EVENT_LBUTTONUP:
288 {
289 if (roi_selecting_)
290 {
291 // Отключаем флаг для выделения ROI
292 roi_selecting_ = false;
293 roi_selected_ = true;
294 // Сохраняем последние позиции
297 }
298 break;
299 }
300 case EVENT_MOUSEMOVE:
301 {
302 // Координаты последнего перемещения мыши
305 break;
306 }
307 }
308}

◆ ServeTheQueues()

void VibrationDetector::ServeTheQueues ( )
private

Обслуживает очереди на удаление и создание. Необходимо для того, чтобы не нарушить нумерацию точек во время выполнения основного цикла

См. определение в файле vibration_detector.cpp строка 38

39{
40 for (int i = 0; i < l_click_queue_.size(); i++)
41 {
43 }
44 for (int i = 0; i < c_point_queue_.size(); i++)
45 {
47 }
48 for (int i = 0; i < delete_queue_.size(); i++)
49 {
51 }
52 l_click_queue_.clear();
53 c_point_queue_.clear();
54 delete_queue_.clear();
55}
void DeletePoints(Point2i mouse_coordinates)
Удаляем объект "обычную" точку
void CreateNewColoredPoint(Point2f mouse_coordinates)
Обработчик "цветных" точек
void LeftClickHandler(Point2f mouse_coordinates)
Обработчик левых кликов

◆ TrackAndCalc()

void VibrationDetector::TrackAndCalc ( )
private

Трекает точки алгоритмом Лукаса-Канаде и вызывает БПФ

См. определение в файле vibration_detector.cpp строка 342

343{
344 // Находим и удаляем точки с низким параметром confidence
346
347 std::vector<Point2f> PrevPts;
348 std::vector<Point2f> NextPts;
349 std::vector<uchar> status;
350 std::vector<float> error;
351
352 // "Достаем" из lonely point handler'ов последние найденные точки, чтобы использовать их в качестве "начальных" значений для calcOpticalFlowPyrLK()
353 for (int i = 0; i < vec_lonely_point_handlers_.size(); i++)
354 {
355 PrevPts.push_back(vec_lonely_point_handlers_[i]->GetLastFoundCoordinates());
356 }
357 // "Достаем" из colored point handler'ов последние найденные точки, чтобы использовать их в качестве "начальных" значений для calcOpticalFlowPyrLK()
358 for (int i = 0; i < vec_colored_point_handlers_.size(); i++)
359 {
360
361 PrevPts.push_back(vec_colored_point_handlers_[i]->GetLastFoundCoordinates());
362 }
363
364 if ((!vec_lonely_point_handlers_.empty()) || (!vec_colored_point_handlers_.empty()))
365 // вызов Lucas-Kanade алгоритма
366 calcOpticalFlowPyrLK(
369 PrevPts,
370 NextPts,
371 status,
372 error,
375 TermCriteria(
376 TermCriteria::MAX_ITER | TermCriteria::EPS,
377 500,
378 0.001
379 ),
380 OPTFLOW_LK_GET_MIN_EIGENVALS
381 );
382
383 // проверяем равны ли размеры векторов хэндлеров точек и найденных точек на картинке
384 if (NextPts.size() != (vec_lonely_point_handlers_.size() + vec_colored_point_handlers_.size()))
385 {
386 std::cout << "DEBUG: ERROR - NextPts size doesnt match vec_point_handlers_ size" << std::endl;
387 }
388
389 std::vector<double> point_amplitudes;
390
391 // Закидываем найденные значения обратно в point handler'ы
392 // Сначала проходимся по lonely хэндлерам
393 for (int i = 0; i < vec_lonely_point_handlers_.size(); i++)
394 {
395 vec_lonely_point_handlers_[i]->AddNewPointPosition(NextPts[i]);
396 vec_lonely_point_handlers_[i]->AddNewPointTime(frame_time_);
397 // Вызов БПФ (FFT)
398 vec_lonely_point_handlers_[i]->ExecuteFFT();
399 // Вычисляем амплитуду
400 vec_lonely_point_handlers_[i]->CalculateAmplitude();
401 double ampl_x = vec_lonely_point_handlers_[i]->GetCurrentAmplitude().x, ampl_y = vec_lonely_point_handlers_[i]->GetCurrentAmplitude().y;
402 point_amplitudes.push_back(sqrt(ampl_x * ampl_x + ampl_y * ampl_y));
403 }
404 // После проходимся по colored хэндлерам
405 //
406 // Небольшое пояснение:
407 // В контейнере NextPts содержатся одновременно lonely и colored точки (причём именно в таком порядке). По сути они делят NextPts на две части - левую (lonely) и правую (colored)
408 // Поэтому, добавляя в хэндлер цветных точек новые координаты, надо идти по NextPts, учитывая возможное (если таковые были добавлены) наличие lonely точек в левой части
409 // Для этого индекс у NextPts = индекс вектора с хэндлерами colored точек + размер вектора с хэндлерами lonely точек (i + vec_lonely_point_handlers_.size())
410 for (int i = 0; i < vec_colored_point_handlers_.size(); i++)
411 {
412 vec_colored_point_handlers_[i]->AddNewPointPosition(NextPts[i + vec_lonely_point_handlers_.size()]);
413 vec_colored_point_handlers_[i]->AddNewPointTime(frame_time_);
414 // Вызов БПФ (FFT)
415 vec_colored_point_handlers_[i]->ExecuteFFT();
416 // Вычисляем амплитуду
417 vec_colored_point_handlers_[i]->CalculateAmplitude();
418 double ampl_x = vec_colored_point_handlers_[i]->GetCurrentAmplitude().x, ampl_y = vec_colored_point_handlers_[i]->GetCurrentAmplitude().y;
419 point_amplitudes.push_back(sqrt(ampl_x * ampl_x + ampl_y * ampl_y));
420 }
421
423 {
424 int max_idx = HelperFunctions::FindGlobalMaxIdx(point_amplitudes);
425 int min_idx = HelperFunctions::FindGlobalMinIdx(point_amplitudes);
426
427 VibratingPoint::extremum_amplitude_.first = point_amplitudes[max_idx];
428 VibratingPoint::extremum_amplitude_.second = *(std::min_element(point_amplitudes.begin(), point_amplitudes.end()));
429 }
430}
void FindAndDeleteUncofidentPoints()
Удаляет "цветные" и "обычные" точки, если уровень доверия к нми слишком низкий
int FindGlobalMinIdx(std::vector< T > src)
Возвращает индекс самого маленького элемента вектора src.
Definition: helper.h:149
int FindGlobalMaxIdx(std::vector< T > src)
Возвращает индекс самого большого элемента вектора src.
Definition: helper.h:127

Данные класса

◆ c_point_queue_

std::vector<Point2f> VibrationDetector::c_point_queue_
private

Очередь на создание "цветных" точек

См. определение в файле vibration_detector.h строка 166

◆ colored_point_mode_

int VibrationDetector::colored_point_mode_
private

Текущий режим подсветки точек при выбранном регионе интереса (по амплитуде/по частоте)

См. определение в файле vibration_detector.h строка 213

◆ current_mode_

int VibrationDetector::current_mode_
private

Основной режим работы (enum main_mode)

См. определение в файле vibration_detector.h строка 150

◆ current_tracking_frame_

Mat VibrationDetector::current_tracking_frame_
private

Текущий Mat-instance только что найденного кадра из видео

См. определение в файле vibration_detector.h строка 199

◆ delete_queue_

std::vector<Point2i> VibrationDetector::delete_queue_
private

Очередь на удаление точек

См. определение в файле vibration_detector.h строка 170

◆ fps_

int VibrationDetector::fps_
private

ФПС входного видео (две ширины полосы частот вибрации, которые можно отследить)

См. определение в файле vibration_detector.h строка 281

◆ frame_handler

FrameHandler* VibrationDetector::frame_handler
private

Фреймпроцессор

См. определение в файле vibration_detector.h строка 129

◆ frame_time_

double VibrationDetector::frame_time_
private

Текущее время кадра в мс (таймкод)

См. определение в файле vibration_detector.h строка 285

◆ frame_to_be_shown_

Mat VibrationDetector::frame_to_be_shown_
private

Mat-instance, который будет показан в окне

См. также
DrawAndOutput()

См. определение в файле vibration_detector.h строка 204

◆ fullscreen_

bool VibrationDetector::fullscreen_
private

Флаг для полноэкранного режима

См. определение в файле vibration_detector.h строка 154

◆ grad_scale_

Mat VibrationDetector::grad_scale_
private

Изображение цветной шкалы внизу экрана

См. также
FrameHandler::GenerateGradScale() и DrawAndOutput()

См. определение в файле vibration_detector.h строка 209

◆ histograms_queue_

std::vector<Point2i> VibrationDetector::histograms_queue_
private

Очередь на отрисовку гистограм

См. определение в файле vibration_detector.h строка 174

◆ input_file_name_

std::string VibrationDetector::input_file_name_
private

Имя (путь) входного видео

См. определение в файле vibration_detector.h строка 235

◆ l_click_queue_

std::vector<Point2i> VibrationDetector::l_click_queue_
private

Очередь на создание "обычных" точек

См. определение в файле vibration_detector.h строка 162

◆ last_mouse_position_

Point VibrationDetector::last_mouse_position_
private

Последняя позиция курсора в главном окне

См. определение в файле vibration_detector.h строка 146

◆ level_amount_

int VibrationDetector::level_amount_
private

Количество слоев пирамиды изображений в алгоритме Л-К

См. определение в файле vibration_detector.h строка 274

◆ lk_win_size_

int VibrationDetector::lk_win_size_
private

Размер окна для алгоритма Лукаса-Канаде

См. определение в файле vibration_detector.h строка 270

◆ next_img_gray_

Mat VibrationDetector::next_img_gray_
private

Следующий (или текущий после "предыдущего" - смотря как удобнее для понимания) кадр видео в грейскейл и с небольшим блюром (FrameHandler::MakeGrayFrame())

См. определение в файле vibration_detector.h строка 266

◆ output_csv_file_name_

std::string VibrationDetector::output_csv_file_name_
private

Имя (путь) файла для хранения метаданных

См. также
OutputToCsv

См. определение в файле vibration_detector.h строка 244

◆ output_file_name_

std::string VibrationDetector::output_file_name_
private

Имя (путь) видео, в котором будет результат детектинга

См. определение в файле vibration_detector.h строка 239

◆ point_id_

int VibrationDetector::point_id_
private

Псевдо-id (порядковывй номер точки)

См. определение в файле vibration_detector.h строка 142

◆ prev_img_gray_

Mat VibrationDetector::prev_img_gray_
private

Предыдущий кадр видео в грейскейл и с небольшим блюром (FrameHandler::MakeGrayFrame())

См. определение в файле vibration_detector.h строка 262

◆ res_mp_

float VibrationDetector::res_mp_
private

Коэффициент автоскейла размеров окна в зависимости от разрешения исходного видео

См. определение в файле vibration_detector.h строка 138

◆ roi_selected_

bool VibrationDetector::roi_selected_
private

Флаг, показывающий был ли выделен ROI или нет

См. определение в файле vibration_detector.h строка 226

◆ roi_selecting_

bool VibrationDetector::roi_selecting_
private

Флаг, показывающий происходит ли в данный момент выделение ROI.

См. определение в файле vibration_detector.h строка 222

◆ running_

bool VibrationDetector::running_
private

Флаг запущенного основного алгоритма

См. также
ExecuteVibrationDetection()

См. определение в файле vibration_detector.h строка 134

◆ sensivity_in_percents_

int VibrationDetector::sensivity_in_percents_
private

Чувствительность при трекинге вибрации

Окно для изменения чувствительности вызывается кнопкой "A" при работающей проге

Чем выше значение - тем больше шумов будет поймано, но и тем меньше по амплитуде вибрации можно будет задетектить

См. определение в файле vibration_detector.h строка 194

◆ tl_click_coords_

Point2i VibrationDetector::tl_click_coords_
private

Координаты первой точки прямоугольник (top left, bottom left, top right, bottom right - смотря "в какую сторону" выделять ROI с помощью мыши (курсора))

См. определение в файле vibration_detector.h строка 230

◆ vec_colored_point_handlers_

std::vector<ColoredPointHandler*> VibrationDetector::vec_colored_point_handlers_
private

Вектор обработчиков "цветных" точек

См. определение в файле vibration_detector.h строка 182

◆ vec_lonely_point_handlers_

std::vector<LonelyPointHandler*> VibrationDetector::vec_lonely_point_handlers_
private

Вектор обработчиков "одиноких" точек

См. определение в файле vibration_detector.h строка 178

◆ warping_figure_

std::vector<Point> VibrationDetector::warping_figure_
private

Координаты фигуры для исправления перспективы

См. определение в файле vibration_detector.h строка 257

◆ warping_figure_selecting_

bool VibrationDetector::warping_figure_selecting_
private

Флаг, показывающий, происходит ли в данный момент выделение фигуры (эта возможность отключена временно)

См. определение в файле vibration_detector.h строка 253

◆ window_name_

std::string VibrationDetector::window_name_
private

Имя главного окна

См. определение в файле vibration_detector.h строка 248


Объявления и описания членов классов находятся в файлах: