Продвигаемая

Курсовое проектирование (Весна-2019)

Общие данные

Цель курсовой простая — попробовать техники компьютерного зрения (CV) / работы с фреймбуфером (Game / VideoPlayer), попробовать себя в комбинаторике имеющихся методов.

В рамках курсового проекта вы:

  • будете находиться в ОС Linux, пользуясь её инфраструктурой и возможностями (можно в рамках виртуальной машины).
  • Попробуете Python (еще раз)
  • Освоите простейший подход для программирования: окно блокнота и компилятор gcc/g++.
  • Чтобы упростить сборку мы применим по отношению к вашей программе систему сборки. После небольших (или больших изменений) в коде вы сможете обновлять результат командой make. В примерах с системой cmake нужно будет сначала единожды вызвать cmake (настройка под ваш компьютер), а потом уже make.
  • Менеджмент CV-кода. Вам будут предложены различные варианты алгоритмов компьютерного зрения, читающие видео с камеры или различных источников (сеть, файл и т.д.). Это материал будет обрабатываться исходя из выбранной цели. Вам будет предложено изменение этого алгоритма или его улучшение (добавление информации в кадр, например). В задании будет базовая задача — дальнейшее улучшение полностью на ваше усмотрение, в интернете очень много материалов, которые позволяют вам накидать в ваш «проект мечты» нужный функционал.
  • [extra] Попробуете Mobile Dev (на примере Android). Для тех кто справляется с запуском базового примера и знает, что улучшение кода не вызовет у него существенных проблем я предлагаю попробовать себя в мобильной разработке. Установите на вашу ОС Android Studio( https://developer.android.com/studio) и скачайте сэмпл для Android. В рамках сэмпла вам предлагается вложить ваш пример в заранее подготовленное место в коде и немного модифицировать вход и выход данных (этому будет посвящено время на лекциях). В итоге ожидается получение функционала вашего приложения в мобильном варианте.

Язык программирования: C/C++ для основной ветки заданий. Возможен Python (и в чем-то вам будет много легче), но тут вам больше самостоятельно и придётся проявить. Попробуйте первые сэмплы этапа 1 для обоих языков и решите.

Подготовка к работе (рабочее окружение)

Сам Linux, если нет проще всего поставить в виртуальной машине. Ставите VirtualBox (Vmware не надо, он слишком тяжелый) и создаете виртуальную машину Linux. Параллельно качаем образ одного из современных GNU/Linux с самой легкой графической оболочкой (для виртуалки большего не надо). Если для себя будете ставить, то можете выбрать более красивые версии (Mate или Cinnamon)

https://linuxmint.com/edition.php?id=266 (Linux Mint XFCE 32bit) - если машина совсем дохлая
https://linuxmint.com/edition.php?id=265 (Linux Mint XFCE 64bit) - если что-то от Core2Duo и выше. 

После того, как образ виртуальной машины создался и вот он перед вами пустой, зайдите в его опции и в качестве CDROM/DVD-ROM выберите для него скачанный образ. Он будет подхвачен в качестве диска. Как запустите виртуалку — сразу начнется загрузка Linux LiveCD, где прямо на рабочем столе есть инсталлятор. Устанавливайте все по рекомендуемым настройкам и, вуаля, через 5-6 минут у вас в виртуальной машине полноценная ОС GNU/Linux. После этого в настройках можно удалить образ из CD-ROM/DVD-ROM, чтобы он не предлагал вам переустанавливать систему еще раз. Внимательно отнеситесь на этой стадии к паролю вашего аккаунта. Это пароль root-команд, он будет нужен довольно часто.

Для настройки системы можете попробовать воспользоваться вот этим скриптом:

..<ToDO>…

Запуск скрипта:

sh ..<ToDO>..

. Попробуйте, потому что я не гарантирую, что где-то в этих файлах не пройзойдет сбой — все файлы будут качаться с интернета, какие-то изменения всегда могут пустить сборку мимо кассы. Но в любом случае выкладываю запасную команду, если что-то пойдет не так и сборка будет заканчиваться с ошибками:

Запасные команды:

sudo apt install libopencv* ffmpeg x264 x265 python3 python3-numpy python3-matplotlib python-opencv python-opencv-apps cmake cmake-curses-gui g++ build-essential

для Python выполните еще (несколько строчек):

sudo apt-get install python python-dev —force-yes —assume-yes —fix-broken curl —silent —show-error —retry 5 https://bootstrap.pypa.io/get-pip.py | sudo python2.7 sudo -H pip install setuptools wheel virtualenv —upgrade

sudo apt-get install python-dev

pip install imutils pyopencv

pip install numpy

sudo pip install opencv-contrib-python

В Linux рекомендую пользоваться каким-нибудь текстовым редактором с подсветкой (geany, bluefish) — их можно легко поставить из консоли через волшебные sudo apt install <пакет>. В этом случае есть 2 варианта — их можно использовать как текстовый редактор, а сборку и запуск проводить в консоли рядом. Или же, посмотрите настройки и укажите редактору свою систему сборки и можете запускать и видеть выхлоп программы прямо в редакторе в спецокне. Я все же предпочитаю в таком подходе по старинке консоль — там больше информации видно, ее удобно развернуть на весь экран на соседнем виртуальном рабочем столе. Или же можете поставить целую среду программирования, из которой можно и запускать сразу (eclipse, codeblocks) — их нынче тоже уже можно поставить через менеджер пакетов.

Если будете писать на Python расклад то же самый. Разве что в качестве специализированных средств не ставьте гигантские комбайны типа Eclipse, а сконцентрируйтесь на чисто Python-средах, вроде PyDev. Их также ставьте через apt-менеджер.

Выбор задания

Не пугайтесь диаграммы, нужно делать только одну из веток, нумерованных зеленым лэйблом. Если вы выбираете одну из веток CA, то в случае успешной модификации кода вы сможете перенести ваш код в Android. Для этого вам нужно будет поставить упомянутую Android-студию и учитывать рекоммендации по внедрению кода и его адаптации для мобильной платформы.

Ядро 1. Алгоритм компьютерного зрения: в базовом варианте это алгоритм компьютерного зрения. им мы посвятим наибольшее количество времени. Это различные варианты обработки кадра, которые будут одна за одной вести нас к результату.

поиск лица в кадре
модификация: запомнить лица, выводить имя / нумерация детекций

поиск объекта определённого цвета
модификация: предложить пользователю палитру для выбора цвета объекта

обработка видео в реальном времени
модификация: по нажатию кнопки делать различные обработки видео.

Ядро 2. Игра. Второй вариант разработки. Возможно среди вас есть будущие игроделы или создатели виртуальных тренажеров (список игроподобных применений можно продолжать). У нас будет занятие по библиотеке SDL, которая представляет собой одну из самых низкоуровневых библиотек работы с графикой и звуком (мультимедиа). На базе SDL написано немало мультимедиа-приложений и игр в том числе. Здесь последовательность следующая — на занятии мы рассмотрим основной механизм SDL, рассмотрим вывод графики и основные проблемы. Этот сэмпл будет доступен и здесь. Далее я передаются вам исходники более сложного проекта, где подключается считывание кнопок управление. Так, размещая героя на экране, мы начинаем его перемещать по экрану. После того как я передам вам код вам его нужно будет запустить и немного модифицировать. Вариант более сложный, бесспорно. Я постараюсь идти навстречу.

Ядро 3. Альтернатива: если вы имеете навыки или уже делаете какой-то проект на базе существующих графических движков (Unity/Unreal3D) или с применением библиотек построения в том числе интерфейсов (Qt, wxWidgets и т.д.), или другой проект на базе OpenCV, то я приветствую такую активность. Прошу только определиться до конца марта и сообщить мне) Подходите и консультируйтесь, если есть идеи. Если вам интересно какое-то направление, то я без проблем приму и незаконченный проект. Главное, чтобы это было действительно вам интересно.


Формулировка задания

  1. Проверить работоспособность вашего рабочего окружения на базе исходников этапа 1.
  2. Внимательно исследовать исходники этапа 2, запустить их
  3. После ознакомления литературой провести модификацию, сохранить исходники этапа 3. Это результат, его нужно будет описать в небольшой записке к работе
  4. В случае если это задание группы CA(на С++), то возможно выполнение адаптации для Android (этап 4). Это по вашему желанию.

Исходные коды

Здесь будет таблица с исходными кодами для каждого из предлагаемых заданий

Рекомендации

№ ЗаданияРекомендации по заданию
CA1 (C++/Детектор лиц)http://study.rusvision.com/2019/03/ca1-детектор-лиц
СА2 (С++/Трекер моноцвет.)http://study.rusvision.com/2019/03/cа2-поиск-одноцветного-объекта
СА3 (С++/Видеопроцессинг)http://study.rusvision.com/2019/03/ca3-видеопроцессинг
CB (C++/Игра)—-
CC (С++/Плейер)—-
PA1http://study.rusvision.com/2019/03/ca1-детектор-лиц
PA2http://study.rusvision.com/2019/03/cа2-поиск-одноцветного-объекта
PA3http://study.rusvision.com/2019/03/ca3-видеопроцессинг
BAXСогласовать. Предпочтение проектам на 3D-движках и приложениям
компьютерного зрения (дополненая реальность, трекеры, анализаторы и т.д.).
CA++ (Android Dev)—-

CA3 (Видеопроцессинг)

Пожалуй, самый простой вариант. Вывод видео в OpenCV не сложнее, чем вывод одной картинки, только в данном случае потребуется использовать цикл для последовательного вывода кадров. Так же необходимо предусмотреть условия выхода из цикла, если не хотите смотреть видео до конца каждый раз.

Работа программы начинается с объявления экземпляра класса VideoCapture(), который предоставляет нам доступ к видео-файлу или любому другому видеопотоку (если дать ему «0» или «/dev/video0», то видео будет забираться с вашей веб-камеры, если она есть). Далее в бесконечном цикле мы последовательно получаем кадры видео один за другим с помощью функции cap >> frame, которая возвращает указатель на уже знакомую нам структуру картинки IplImage.
Показываем кадр в окошке, а затем при помощи функции WaitKey ждём 33 миллисекунды и затем цикл продолжается, если не нажата клавиша ESC.
33 выбрано не случайно — т.к. эта задержка даёт возможность просмотра 30 кадров в секунду.

Между получением кадра и задержкой перед возвращением в начало цикла за новым есть пространство для творчества. В приведенных примерах производится:

  1. Выделение контуров (проект contour_extraction)
  2. «Замыливание» (проект blur)

Задание

Задание творческое. В исходниках OpenCV-4.0.1 есть папка samples/cpp или samples/python. Их можно посмотреть и в вебе. Внутри очень большое число сэмплов, в большинстве из которых вы найдете волшебные слова VideoCapture и бесконечный цикл while(true) со считыванием кадра cap >> frame. Это значит, что пример вам подходит, переделок будет минимум скорее всего.

Вы можете создать отдельную папку для тестов, куда скопируете вашего подопечного и соберете. Если все прошло хорошо и программа запускается и делает что-то интересное (если изначально не понятно по названию), то предлагаю вам перенести ее функционал в ваш сэмпл с blur. Т.е. сделать GaussianBlur(), а потом уже поставить нужную функцию.

Пример выполнения задания

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

Я изначально копирую папку blur (ведь там готовая сборочная система под OpenCV) и называю новую папку-копию test. Заглянув в sample/cpp я вижу файл smiledetect.cpp и думаю «Россия — для грустных!». Это то, что мне надо! Программа будущего робота контроля за улыбками. Я забираю файл smiledetect.cpp в папку test, откуда параллельно убираю ненужный blur.cpp. В файле сборки не забываю заменить blur.cpp на новый smiledetect.cpp и меняю для удобства название выходного файла в последних 2 строчках с app на smiledetect. Все, теперь должно собираться (выполняем в консоли в текущей папке):

mkdir release

cd release

cmake ..

make

<в текущей директории release должен появиться исполняемый файл>

Внимательно следите за тем, как нужно запускать файл. Т.е. не просто «./smile_detect», а, скажем, «./smile_detect video.mp4». Хотя, о неправильном запуске сэмпл-программы вам сообщат — в них это предусмотрено почти всегда.

Заглянув в smiledetect.cpp я понял, что весь поиск улыбки производится в функции

void detectAndDraw( Mat& img, CascadeClassifier& cascade,
CascadeClassifier& nestedCascade,
double scale, bool tryflip) { …… }

я полностью забираю ее в свою программу. Так же как и в примере, размещая ее ниже чем основная функция main не забывая ее объявить выше (строчка 24 в smiledetect.cpp).
Это сложный пример, т.к. теперь нужно эту функцию использовать в моем коде, нужно передать ей все ее параметры-аргументы. Я смотрю, что в примере загружают в нее и понимаю, что это обученные каскады (мы уже использовали каскады в примере с поиском лица — тут еще есть параметр nestedCascade, который представляет собой отдельный каскад поиска улыбок). Чтобы не мучать свою программу лишними строками выбора каскадов я просто говорю функции, что есть у меня такие каскады и они рядом с запускаемым файлом.

Кроме того, scale (масштаб) я выставляю в 1, а параметр tryflip (перевернуть детектор и попробовать найти отрицательную улыбку) выставлю в 0 за ненадобностью.

Пример размещения файлов каскадов

После этого я помещаю в код функцию detectAndDraw аккурат за функцией blur.

GaussianBlur(image, image_blurred, Size(slider, slider), sigma);
imshow("Blurred Image", image_blurred);
detectAndDraw(image_blurred, "haarcascade_frontalface_alt.xml", "haarcascade_smile.xml", 1, 0 );
imshow("Smile Detector", image_blurred);

В результате выполнения программы у меня теперь выскакивает 2 окна — одно замыленное, а второе — результат поиска улыбок на размытом экране. Теперь я могу проводить целое исследование на тему «Зависимость результативности работы детектора улыбок на основе HOG от степени размытия кадра».

Да, этот пример достаточно сложный. Вы можете повторить его вслед за мной, но лучше поищите примеры попроще, заодно будете понимать, что в принципе умеет OpenCV.