Цель данной работы - изучить базовые примитивы модуля opencv_core
и простейшие операции обработки изображений модуля opencv_imgproc
, научиться
разрабатывать интерфейс средствами модуля opencv_highgui
.
Проект представляет собой шаблон проекта для освоения основ работы с библиотекой OpenCV:
- Базовые примитивы и операции модуля
opencv_core
(методы классаcv::Mat
для представления изображения). - Обработка изображений с помощью простеших фильтров модуля
opencv_imgproc
(линейные фильтры, вычисление градиентов на изображении). - Основные операции модуля
opencv_highgui
(загрузка изображения средствамиimread
, сохранение изображения с использованиемimwrite
, отображение изображения с помощью функцийimshow
иwaitKey
, реализация сложных сценариев обработки событий).
Структура проекта:
sample_template
- исходные коды шаблонного проекта. Шаблонное приложение отображает исходное изображение и изображение, полученное в результате медианной фильтрации центральной части исходного изображения. Также в окне имеется 2 кнопки, позволяющие включить/отключить действие фильтра.testdata
- директория с данными для тестов..gitignore
- перечень расширений файлов, которые не выкладываются в проект..travis.yml
- конфигурационный файл для системы автоматического тестирования Travis-CI.CMakeLists.txt
- общий файл для сборки проекта с помощью CMake.README.md
- информация о проекте, которую вы сейчас читаете.
В шаблонном проекте имеются следующие модули:
- Основной модуль
main
, содержащий реализацию основного сценария работы шаблонного приложения: разбор аргументов командной строки, чтение кадра, ожидание нажатия на кнопки и обновление состояния окна с изображениями. - Модуль
processing
содержит метод медианной фильтрации центральной области изображения. - Модуль графичекого приложения
application
. Содержит метод обработки аргументов командной строкиparseArguments
; оберткуprocessFrame
над функцией обработки изображения с использованием метода, реализованного в модулеprocessing
; метод отображения окна с двуми изображениями - исходным и обработанным, если фильтр включен, либо двумя исходными, если фильтр выключен; методы, необходимые для обработки событий нажатия на кнопки включение/выключения фильтра.
Основные задачи:
- Обеспечить возможность изменения положения региона фильтрации со временем.
- Добавить третью кнопку, чтобы обеспечить возможность сохранения текущего изображения окна.
- Добавить несколько дополнительных кнопок, позволяющих изменять тип фильтра:
- Перевод центральной части изображения в оттенки серого вместо медианной фильтрации.
- Поддержка режима пикселизации центральной области изображения (подобно тому, как на телевидении скрывают лицо человека).
- Применение Канни детектора для определения ребер в центральной части исходного изображения.
Дополнительные задачи:
- Реализовать возможность получения кадров из видеофайла и/или камеры.
- Реализовать случайное перемешивание картинки как в игре в "пятнашки".
- Реализовать приложение для игры в пятнашки.
- Сделать форк upstream-репозитория, затем клонировать origin к себе на локальную машину. Для инструкций можно обратиться к разделу Общие инструкции по работе с Git в практической работе 1.
- Скомпилировать и запустить сэмпл на картинке (раздел Сборка проекта с помощью CMake и MS VS в практической работе 1.
- Создать новую ветку для разработки собственного приложения необходимые команды описаны в разделе Общие инструкции по работе с Git в практической работе 1.
- Создать копию директории с сэмплом, добавить ее построение в корневой
CMakeLists.txt
. - Убедиться, что новый сэмпл успешно собирается и запускается.
- Прислать Pull Request с еще неизмененным сэмплом. Пометить в конце названия
(NOT READY)
. По мере готовности решений основных задач Pull Request можно будет переименовать. - Сделать так, чтобы регион фильтрации менял со временем свое положение и размеры. Обновить Rull Request.
- Добавить третью кнопку, позволяющую сохранить текущее изображение на экране. Сохранять можно в текущую директорию с меткой времени. Обновить pull request.
- Добавить несколько дополнительных кнопок, позволяющих менять тип фильтра (см. перечень ниже) и обновить Rull Request.
- Решить задачи из списка Дополнительные задачи (документация к классу cv::VideoCapture для работы с видео).
-
Сделать форк upstream-репозитория и клонировать origin к себе на локальную машину (подробная последовательность действий описана в разделе Общие инструкции по работе с Git в практической работе 1.
-
Скомпилировать и запустить сэмпл на картинке (подробная последовательность действий описана в разделе Сборка проекта с помощью CMake и MS VS в практической работе 1).
-
Создать новую ветку для разработки собственного приложения необходимые команды описаны в разделе Общие инструкции по работе с Git в практической работе 1.
-
Создать копию директории с сэмплом, дав ей название
sample_YOUR_NAME
, и добавить ее построение в общийCMakeLists.txt
(add_subdirectory(sample_YOUR_NAME)
). В файлеCMakeLists.txt
, отноящемся к созданному проекту (расположен внутри директорииsample_YOUR_NAME
) необходимо заменитьset(target "sample_template")
наset(target "sample_YOUR_NAME")
-
Убедиться, что новый сэмпл с шаблонной реализацией успешно собирается и запускается (подробная последовательность действий описана в разделе Сборка проекта с помощью CMake и MS VS в практической работе 1).
-
Прислать Pull Request с еще неизмененным сэмплом. Пометить в конце названия
(NOT READY)
. По мере готовности решений основных задач Pull Request можно будет переименовать, нажав кнопкуEdit
напротив его названия. -
Сделать так, чтобы регион фильтрации менял со временем свое положение и размеры.
- Для этого необходимо в методе
processFrame
классаProcessing
заменить фиксированное положение фильтра на процедурную генерацию положения левого верхнего углаx
иy
регионаregion
при фиксированных размерах окна фильтрации. Положение окна может выбираться случайно, или по некоторому закону (например движение по прямой линии с отражением от краев изображения).
cv::Rect region(src.rows/4, src.cols/4, src.rows/2, src.cols/2);
При генерации следует учитывать, что окно фильтрации должно попадать в область изображения. Решение 1: пределы генерации координат должны быть зафиксированы так, чтобы окно всегда накрывало какую-то часть изображения. Решение 2: проверять, не вышло ли окно за пределы изображения, если вышло, то обрезать лишние части окна. 2. Не забывайте коммитить изменения в локальный репозиторий и выкладывать их в ветку на сервере. 3. По окончании решения данной задачи следует обновить Rull Request.
- Для этого необходимо в методе
-
Добавить третью кнопку, позволяющую сохранить текущее изображение на экране. Сохранять можно в текущую директорию с меткой времени.
- В структуру
GUIElementsState
(файлApplication.hpp
) добавить полеcv::Rect saveButtonPlace
. - В метод
drawButtons
классаApplication
добавить отрисовку третьей кнопки по аналогии с кнопками включения/выключения фильтрации. Расположить кнопку необходимо на одной линии с имеющимися. Также на кнопке следует добавить надписьSave
. Положение кнопки сохранить в полеsaveButtonPlace
объектаguiState
. - В структуру
GUIElementsState
добавить полеbool saveState
- флаг, обозначающий необходимость сохранения текущего окна с изображениями. Изначально присвоить ему значениеfalse
в конструкторе классаApplication
. - В реализацию метода
onButtonsOnOffClick
добавить еще одно условие для обработки события, связанного с нажатием кнопки сохранения.
if (onButtonClicked(elems->saveButtonPlace, x, y)) { elems->saveState = true; return; }
- В реализацию метода
showFrame
классаApplication
после отрисовки пары изображений и до отрисовки кнопок необходимо вставить условие для проверки необходимости сохранения текущей пары изображений.
if (elems->saveState) { // получить текущее время // сгенерировать название изображения // <image_name> - сгенерированное название изображения // с меткой текущего времени // вызвать функцию сохранения imwrite(<image_name>, display) // сбросить значение guiState.saveState в false }
- Обновить Pull Request.
- В структуру
-
Добавить несколько дополнительных кнопок, позволяющих менять тип фильтра (см. п.3 раздела Основные задачи.
- В класс
Processing
добавить перечисление для обозначения типа фильтра, который применяется к изображению.
enum FilterType { MEDIAN, CVT_CONVERT_GRAY, PIXELIZED, CANNY };
- В объявление метода
processFrame
классаProcessing
добавить параметр типаFilterType filter
. - В реализации метода
processFrame
классаProcessing
вместо вызова функции медианной фильтрацииmedianBlur(roi, roi, kSize)
добавить оператор множественного выбора по параметруfilter
. В зависимости от типа фильтра необходимо вызывать тот или набор функций библиотеки OpenCV. - Отрисовать дополнительные кнопки по аналогии с кнопкой сохранения
изображений. Положение кнопок сохранить в структуре
GUIElementsState
. Замечание: кнопкуOn
можно только переименовать вMedian
. - В структуру
GUIElementsState
добавить поле для хранения типа последнего вызванного для обработки фильтраProcessing::FilterType filter
. - В конструкторе класса установить начальное значение
guiState.filter
в значениеProcessing::MEDIAN
. - Вызов метода
processor.processFrame(src, dst)
заменить наprocessor.processFrame(src, dst, guiState.filter)
(метод класса приложенияint Application::processFrame(const Mat& src, Mat& dst)
). - Изменить обработчик события нажатия по кнопкам
onButtonsOnOffClick
, добавив несколько проверок, соответствующих нажатию по определенным кнопкам. Содержимое условного оператора приведено ниже.
elems->state = Application::OnFilter; elems->filter=Processing::MEDIAN; return;
- Проверить работоспособность приложения и обновить Rull Request.
- В класс
-
Решить задачи из списка Дополнительные задачи.