|
| 1 | +# Практика 2. Основы работы с библиотекой OpenCV |
| 2 | + |
| 3 | +[](https://travis-ci.org/Itseez-NNSU-SummerSchool2015/practice2-opencv-intro) |
| 4 | + |
| 5 | +## Цели |
| 6 | + |
| 7 | +__Цель данной работы__ - изучить базовые примитивы модуля `opencv_core` |
| 8 | +и простейшие операции обработки изображений модуля `opencv_imgproc`, научиться |
| 9 | +разрабатывать интерфейс средствами модуля `opencv_highgui`. |
| 10 | + |
| 11 | +Проект представляет собой шаблон проекта для освоения основ работы |
| 12 | +с библиотекой OpenCV: |
| 13 | + |
| 14 | + - Базовые примитивы и операции модуля `opencv_core` |
| 15 | + (методы класса `cv::Mat` для представления изображения). |
| 16 | + - Обработка изображений с помощью простеших фильтров модуля `opencv_imgproc` |
| 17 | + (линейные фильтры, вычисление градиентов на изображении). |
| 18 | + - Основные операции модуля `opencv_highgui` (загрузка изображения |
| 19 | + средствами `imread`, сохранение изображения с использованием |
| 20 | + `imwrite`, отображение изображения с помощью функций `imshow` и `waitKey`, |
| 21 | + реализация сложных сценариев обработки событий). |
| 22 | + |
| 23 | +## Общая структура проекта |
| 24 | + |
| 25 | +Структура проекта: |
| 26 | + |
| 27 | + - `sample_template` - исходнодные коды шаблонного проекта. Шаблонное |
| 28 | + приложение отображает исходное изображение и изображение, полученное в |
| 29 | + результате медианной фильтрации центральной части исходного изображения. |
| 30 | + Также в окне имеется 2 кнопки, позволяющие включить/отключить действие |
| 31 | + фильтра. |
| 32 | + - `testdata` - директория с данными для тестов. |
| 33 | + - `.gitignore` - перечень расширений файлов, которые не выкладываются в |
| 34 | + проект. |
| 35 | + - `.travis.yml` - конфигурационный файл для системы автоматического |
| 36 | + тестирования Travis-CI. |
| 37 | + - `CMakeLists.txt` - общий файл для сборки проекта с помощью CMake. |
| 38 | + - `README.md` - информация о проекте, которую вы сейчас читаете. |
| 39 | + |
| 40 | +В шаблонном проекте имеются следующие модули: |
| 41 | + |
| 42 | + - Основной модуль `main`, содержащий реализацию основного сценария работы |
| 43 | + шаблонного приложения: разбор аргументов командной строки, чтение кадра, |
| 44 | + ожидание нажатия на кнопки и обновление состояния окна с изображениями. |
| 45 | + - Модуль `processing` содержит метод медианной фильтрации центральной области |
| 46 | + изображения. |
| 47 | + - Модуль графичекого приложения `application`. Содержит метод обработки |
| 48 | + аргументов командной строки `parseArguments`; обертку `processFrame` над |
| 49 | + функцией обработки изображения с использованием метода, реализованного в |
| 50 | + модуле `processing`; метод отображения окна с двуми изображениями - исходным |
| 51 | + и обработанным, если фильтр включен, либо двумя исходными, если фильтр |
| 52 | + выключен; методы, необходимые для обработки событий нажатия на кнопки |
| 53 | + включение/выключения фильтра. |
| 54 | + |
| 55 | +## Задачи |
| 56 | + |
| 57 | +__Основные задачи:__ |
| 58 | + |
| 59 | + 1. Обеспечить возможность изменения положения региона фильтрации со временем. |
| 60 | + 2. Добавить третью кнопку, чтобы обеспечить возможность сохранения текущего |
| 61 | + изображения окна. |
| 62 | + 3. Добавить несколько дополнительных кнопок, позволяющих изменять тип фильтра: |
| 63 | + - Перевод центральной части изображения в оттенки серого вместо медианной |
| 64 | + фильтрации. |
| 65 | + - Поддержка режима пикселизации центральной области изображения (подобно |
| 66 | + тому, как на телевидении скрывают лицо человека). |
| 67 | + - Применение Канни детектора для определения ребер в центральной части |
| 68 | + исходного изображения. |
| 69 | + |
| 70 | +__Дополнительные задачи:__ |
| 71 | + |
| 72 | + 1. Реализовать возможность получения кадров из видеофайла и/или камеры. |
| 73 | + 2. Реализовать случайное перемешивание картинки как в игре в "пятнашки". |
| 74 | + 3. Реализовать приложение для игры в пятнашки. |
| 75 | + |
| 76 | +## Общая последовательность действий |
| 77 | + |
| 78 | + 1. Сделать форк upstream-репозитория, затем клонировать origin к себе на |
| 79 | + локальную машину. Для инструкций можно обратиться к разделу |
| 80 | + [Общие инструкции по работе с Git][git-intro] в [практической работе 1][practice1]. |
| 81 | + 2. Скомпилировать и запустить сэмпл на картинке (раздел |
| 82 | + [Сборка проекта с помощью CMake и MS VS][cmake-msvs] |
| 83 | + в [практической работе 1][practice1]. |
| 84 | + 4. Создать копию директории с сэмплом, добавить ее построение в корневой |
| 85 | + `CMakeLists.txt`. |
| 86 | + 5. Убедиться, что новый сэмпл успешно собирается и запускается. |
| 87 | + 6. Прислать Pull Request с еще неизмененным сэмплом. Пометить в конце названия |
| 88 | + `(NOT READY)`. По мере готовности решений основных задач Pull Request можно |
| 89 | + будет переименовать. |
| 90 | + 7. Сделать так, чтобы регион фильтрации менял со временем свое положение и |
| 91 | + размеры. Обновить Rull Request. |
| 92 | + 4. Добавить третью кнопку, позволяющую сохранить текущее изображение на |
| 93 | + экране. Сохранять можно в текущую директорию с меткой времени. Обновить |
| 94 | + pull request. |
| 95 | + 5. Добавить несколько дополнительных кнопок, позволяющих менять тип фильтра |
| 96 | + (см. перечень ниже) и обновить Rull Request. |
| 97 | + - Простой перевод в оттенки серого (функция [cvtColor][cvtColor]. |
| 98 | + - Режим пикселизации (подробнее можно прочитать [здесь][pixelation]. |
| 99 | + - Режим применения Канни детектора (пример использования функции |
| 100 | + [Canny][canny]. |
| 101 | + 6. Решить задачи из списка [Дополнительные задачи][tasks] (документация к |
| 102 | + классу [cv::VideoCapture][capture] для работы с видео). |
| 103 | + |
| 104 | +## Детальная инструкция по выполнению работы |
| 105 | + |
| 106 | + 1. Сделать форк upstream-репозитория и клонировать origin к себе на локальную |
| 107 | + машину (подробная последовательность действий описана в разделе |
| 108 | + [Общие инструкции по работе с Git][git-intro] в [практической работе 1][practice1]. |
| 109 | + 2. Скомпилировать и запустить сэмпл на картинке (подробная последовательность |
| 110 | + действий описана в разделе [Сборка проекта с помощью CMake и MS VS][cmake-msvs] |
| 111 | + в [практической работе 1][practice1]). |
| 112 | + 4. Создать копию директории с сэмплом, дав ей название `sample_YOUR_NAME`, и |
| 113 | + добавить ее построение в общий `CMakeLists.txt` |
| 114 | + (`add_subdirectory(sample_YOUR_NAME)`). |
| 115 | + 5. Убедиться, что новый сэмпл с шаблонной реализацией успешно собирается |
| 116 | + и запускается (подробная последовательность действий описана в разделе |
| 117 | + [Сборка проекта с помощью CMake и MS VS][cmake-msvs] |
| 118 | + в [практической работе 1][practice1]). |
| 119 | + 6. Прислать Pull Request с еще неизмененным сэмплом. Пометить в конце |
| 120 | + названия `(NOT READY)`. По мере готовности решений основных задач Pull |
| 121 | + Request можно будет переименовать, нажав кнопку `Edit` напротив его |
| 122 | + названия. |
| 123 | + 7. Сделать так, чтобы регион фильтрации менял со временем свое положение и |
| 124 | + размеры. |
| 125 | + |
| 126 | + 1. Для этого необходимо в методе `processFrame` класса `Processing` |
| 127 | + заменить фиксированное положение фильтра на процедурную генерацию |
| 128 | + положения левого верхнего угла `x` и `y` региона `region` при |
| 129 | + фиксированных размерах окна фильтрации. Положение окна может выбираться |
| 130 | + случайно, или по некоторому закону (например движение по прямой линии с |
| 131 | + отражением от краев изображения). |
| 132 | + |
| 133 | + ``` |
| 134 | + cv::Rect region(src.rows/4, src.cols/4, src.rows/2, src.cols/2); |
| 135 | + ``` |
| 136 | +
|
| 137 | + 2. При генерации следует учитывать, что окно фильтрации должно попадать в |
| 138 | + область изображения. Решение 1: пределы генерации координат должны быть |
| 139 | + зафиксированы так, чтобы окно всегда накрывало какую-то часть |
| 140 | + изображения. Решение 2: проверять, не вышло ли окно за пределы |
| 141 | + изображения, если вышло, то обрезать лишние части окна. |
| 142 | + 3. По окончании решения данной задачи следует обновить Rull Request. |
| 143 | +
|
| 144 | + 4. Добавить третью кнопку, позволяющую сохранить текущее изображение на |
| 145 | + экране. Сохранять можно в текущую директорию с меткой времени. |
| 146 | +
|
| 147 | + 1. В структуру `GUIElementsState` добавить поле `cv::Rect saveButtonPlace`. |
| 148 | + 2. В метод `drawButtons` класса `Application` добавить отрисовку третьей |
| 149 | + кнопки по аналогии с кнопками включения/выключения фильтрации. |
| 150 | + Расположить кнопку необходимо на одной линии с имеющимися. Также на |
| 151 | + кнопке следует добавить надпись `Save`. Положение кнопки сохранить в |
| 152 | + поле `saveButtonPlace` объекта `guiState`. |
| 153 | + 3. В структуру `GUIElementsState` добавить поле `bool saveState` - флаг, |
| 154 | + обозначающий необходимость сохранения текущего окна с изображениями. |
| 155 | + Изначально присвоить ему значение `false` в конструкторе класса |
| 156 | + `Application`. |
| 157 | + 4. В реализацию метода `onButtonsOnOffClick` добавить еще одно условие для |
| 158 | + обработки события, связанного с нажатием кнопки сохранения. |
| 159 | +
|
| 160 | + ``` |
| 161 | + if (onButtonClicked(elems->saveButtonPlace, x, y)) |
| 162 | + { |
| 163 | + elems->saveState = true; |
| 164 | + return; |
| 165 | + } |
| 166 | + ``` |
| 167 | +
|
| 168 | + 5. В реализацию метода `showFrame` класса `Application` после отрисовки |
| 169 | + пары изображений и до отрисовки кнопок необходимо вставить условие для |
| 170 | + проверки необходимости сохранения текущей пары изображений. |
| 171 | +
|
| 172 | + ``` |
| 173 | + if (elems->saveState) |
| 174 | + { |
| 175 | + // получить текущее время |
| 176 | + // сгенерировать название изображения |
| 177 | + // <image_name> - сгенерированное название изображения |
| 178 | + // с меткой текущего времени |
| 179 | + // вызвать функцию сохранения imwrite(<image_name>, display) |
| 180 | + } |
| 181 | + ``` |
| 182 | +
|
| 183 | + 6. Обновить Pull Request. |
| 184 | +
|
| 185 | + 5. Добавить несколько дополнительных кнопок, позволяющих менять тип фильтра |
| 186 | + (см. п.3 раздела [Основные задачи][tasks]. |
| 187 | +
|
| 188 | + 1. В класс `Processing` добавить перечисление для обозначения типа фильтра, |
| 189 | + который применяется к изображению. |
| 190 | +
|
| 191 | + ``` |
| 192 | + enum FilterType |
| 193 | + { |
| 194 | + MEDIAN, |
| 195 | + CVT_CONVERT_GRAY, |
| 196 | + PIXELIZED, |
| 197 | + CANNY |
| 198 | + }; |
| 199 | + ``` |
| 200 | +
|
| 201 | + 2. В объявление метода `processFrame` класса `Processing` добавить параметр |
| 202 | + типа `FilterType filter`. |
| 203 | + 3. В реализации метода `processFrame` класса `Processing` вместо вызова |
| 204 | + функции медианной фильтрации `medianBlur(roi, roi, kSize)` добавить |
| 205 | + оператор множественного выбора по параметру `filter`. В зависимости от |
| 206 | + типа фильтра необходимо вызывать тот или набор функций библиотеки |
| 207 | + OpenCV. |
| 208 | + 4. Отрисовать дополнительные кнопки по аналогии с кнопкой сохранения |
| 209 | + изображений. Положение кнопок сохранить в структуре `GUIElementsState`. |
| 210 | + Замечание: кнопку `On` можно только переименовать в `Median`. |
| 211 | + 5. В структуру `GUIElementsState` добавить поле для хранения типа |
| 212 | + последнего вызванного для обработки фильтра `Processing::FilterType |
| 213 | + filter`. |
| 214 | + 6. В конструкторе класса установить начальное значение `guiState.filter` в |
| 215 | + значение `Processing::MEDIAN`. |
| 216 | + 7. Вызов метода `processFrame(src, dst)` заменить на |
| 217 | + `processFrame(src, dst, guiState.filter)`. |
| 218 | + 8. Изменить обработчик события нажатия по кнопкам `onButtonsOnOffClick`, |
| 219 | + добавив несколько проверок, соответствующих нажатию по определенным |
| 220 | + кнопкам. Содержимое условного оператора приведено ниже. |
| 221 | +
|
| 222 | + ``` |
| 223 | + elems->state = Application::OnFilter; |
| 224 | + elems->filter=Processing::MEDIAN; |
| 225 | + return; |
| 226 | + ``` |
| 227 | +
|
| 228 | + 9. Проверить работоспособность приложения и обновить Rull Request. |
| 229 | +
|
| 230 | + 6. Решить задачи из списка [Дополнительные задачи][tasks]. |
| 231 | +
|
| 232 | +<!-- LINKS --> |
| 233 | +
|
| 234 | +[practice1]: https://github.com/Itseez-NNSU-SummerSchool2015/practice1-devtools |
| 235 | +[git-intro]: https://github.com/Itseez-NNSU-SummerSchool2015/practice1-devtools#Общие-инструкции-по-работе-с-git |
| 236 | +[cmake-msvs]: https://github.com/Itseez-NNSU-SummerSchool2015/practice1-devtools#Сборка-проекта-с-помощью-cmake-и-microsoft-visual-studio |
| 237 | +[tasks]: https://github.com/Itseez-NNSU-SummerSchool2015/practice2-opencv-intro#Задачи |
| 238 | +
|
| 239 | +[cvtColor]: http://docs.opencv.org/modules/imgproc/doc/miscellaneous_transformations.html#cvtcolor |
| 240 | +[pixelation]: http://opencv-code.com/tutorials/photo-to-colored-dot-patterns-with-opencv |
| 241 | +[canny]: http://docs.opencv.org/doc/tutorials/imgproc/imgtrans/canny_detector/canny_detector.html |
| 242 | +[capture]: http://docs.opencv.org/modules/highgui/doc/reading_and_writing_images_and_video.html#videocapture |
0 commit comments