Молодежная научная школа "Высокопроизводительные вычисления, оптимизация и приложения". Трек "Робототехника и компьютерное зрение"
Цель данной лабораторной работы состоит в том, чтобы решить одну из классических задач компьютерного зрения - детектирование объектов - с использованием средств библиотеки OpenCV. В качестве целевых объектов для детектирования рассматриваются логотипы ННГУ, OpenCV и Intel.
Основные задачи
- Разработать приложение, осуществляющее детектирование объектов определенного класса (один из предложенных классов логотипов) на одиночном изображении и видео с помощью каскадного классификатора.
- Обучить детектор логотипов выбранного класса на основе HAAR- и LBP-признаков.
- Применить полученные самостоятельно детекторы к тестовому видео. Визуально оценить качество детекторов.
Дополнительные задачи
- Разработать приложение, позволяющее детектировать логотипы нескольких классов на одном изображении/видео одновременно.
- Разработать приложение, осуществляющее детектирование логотипов
на изображении и видео с помощью HOG-детектора
(см. документацию
HOGDescriptor
). - Добавить в разработанное приложение возможность оценки качества детектирования при наличии файла с описанием истинных положений объектов на изображении/кадрах видео.
Общая схема решения задачи детектирования с использованием машинного обучения включает два основных этапа.
-
Обучение детектора. Обучение предполагает выполнение следующих действий:
- Подготовка тренировочных данных - множества положительных (содержащих объект) и отрицательных (не содержащих объект) примеров изображений.
- Извлечение признаков из каждого изображения тренировочного набора.
- Обучение детектора на полученном наборе признаков.
- Сохранение параметров обученной модели.
-
Тестирование детектора. Тестирование предполагает выполнение следующих действий:
- Получение изображения, на котором необходимо определить положения объектов.
- Извлечение признаков из полученного изображения. На данном этапе используется тот же алгоритм, что и при обучении детектора.
- Передачи построенных признаков детектору, который принимает решение о наличии/отсутствии объекта и его местоположении в системе координат изображения.
Для выполнения лабораторной работы требуется наличие следующего программного обеспечения:
- Библиотеки: OpenCV 3.1.
- Утилиты: CMake 2.8 и выше.
- Среда разработки: Microsoft Visual Studio 2015 (под Windows) или любая другая среда разработки, для которой CMake способен сгенерировать файлы для компиляции.
- Git-клиент (опционально).
Репозиторий содержит следующие директории и файлы:
-
include
- заголовочные файлы модулей библиотекиhpc_2016_logo_detection_lib
:detection
- модуль, с помощью которого решаются основные задачи;benchmark
- вспомогательный модуль для решения дополнительной задачи оценки качества работы детектора. -
samples
- примеры использования методов. Изначально директория содержит шаблонный пример консольного приложенияtemplate_demo.cpp
. Лабораторная работа предполагает разработку собственного приложения, обеспечивающего решение задачи детектирования на базе указанного шаблона. -
src
- исходные файлы модулей библиотекиhpc_2016_logo_detection_lib
. -
data
- директория, содержащая данные, необходимые для решения задачи:detection/cascades
- xml-файлы, содержащие обученные модели каскадного классификатора для логотипов ННГУ, OpenCV и Intel.detection/negatives
- негативные изображения.detection/positives
- позитивные изображения детектируемых логотипов.detection/vec_files
- vec-файлы, содержащие признаковые описанияnegatives.txt
- список негативных изображений.video/logo.mp4
- видео, содержащее сцены с логотипами.
-
CMakeLists.txt
- общий файл для сборки проектов с помощью CMake. -
README.md
- данный файл. -
.gitignore
- перечень директорий/файлов, которые игнорируются системой контроля версий.
В лабораторной работе основные задачи решаются на базе программного
модуля detection
библиотеки hpc_2016_logo_detection_lib
. Модуль
включает заголовочный файл include\detection.hpp
и исходный файлsrc\detection.cpp
. Модуль содержит объявление
абстрактного класса Detector
.
class Detector {
public:
static std::shared_ptr<Detector> CreateDetector(const std::string& name);
virtual bool Init(const std::string& model_file_path) = 0;
virtual void Detect(const cv::Mat& frame, std::vector<cv::Rect>& objects,
std::vector<double>& scores) = 0;
};
Класс имеет следующие чисто виртуальные методы:
Init
- метод загрузки детектора из файла.Detect
- метод детектирования объектов на одиночном изображении. Входные параметры:frame
- изображение. Выходные параметры:objects
- вектор прямоугольников, выделяющих найденные объекты на изображении;scores
- вектор, содержащий для каждого срабатывания детектора число, определяющее уверенность детектора в наличии объекта в соответствующей области изображения.
Также класс содержит фабричный метод CreateDetector
.
В данном разделе описана типичная последовательность действий, которую
необходимо выполнить для сборки проекта с использованием утилиты CMake и
Microsoft Visual Studio 2015. Далее для определенности выполняется сборка проекта
hpc_2016_logo_detection
.
-
Рядом с директорией проекта
hpcschool-2016-practice
создайтеhpcschool-2016-practice-build
. В новой директории будут размещены файлы решения и проектов, сгенерированные с помощью CMake.$ mkdir hpcschool-2016-practice-build
-
Перейдите в директорию
hpcschool-2016-practice-build
:$ cd ./hpcschool-2016-practice-build
-
Сгенерируйте файлы решения и проектов с помощью утилиты CMake. Для этого можно воспользоваться графическим приложением, входящим в состав утилиты, либо выполнить следующую команду:
$ cmake -DOpenCV_DIR="<OpenCVConfig.cmake-path>" -G <generator-name> <path-to-hpcschool-2016-practice>
# <OpenCVConfig.cmake-path> - директория, в которой установлена
# библиотека OpenCV и расположен файл OpenCVConfig.cmake
# в терминал-классе это директория c:\OpenCV31\opencv\build
# <generator-name> - название генератора, в случае тестовой
# инфраструктуры участников школы может быть "Visual Studio 14 2015 Win64"
# (если в командной строке набрать cmake без параметров, то можно просмотреть
# список доступных генераторов)
# <path-to-hpcschool-2016-practice> - путь до директории
# hpcschool-2016-practice, где лежат исходные коды проекта (если предыдущие действия
# выполнены корректно, то это директория`../hpcschool-2016-practice`)
Обратите внимание, что для сборки проекта необходима версия OpenCV 3.1.x,
например, 3.1.0, которую можно скачать здесь.
В терминал-классах OpenCV 3.1.0 установлена в директорию C:\OpenCV31
- Откройте сгенерированный файл решения
hpc_2016_logo_detection.sln
. В терминал-классах Microsoft Visual Studio располагается по пути:C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\devenv.exe
- Нажмите правой кнопкой мыши по проекту
ALL_BUILD
и выберите пунктRebuild
контекстного меню, чтобы собрать решение. В результате все бинарные файлы будут размещены в директорииhpcschool-2016-practice-build/bin
, библиотеки -hpcschool-2016-practice-build/lib
. - Для запуска приложения откройте командную строку (
cmd.exe
вПуск
) и перейдите в директорию с бинарными файлами, используя командуcd
. - Можно запустить шаблонное приложение
template_demo.exe
. Возможное сообщение при запуске:The program can't start because opencv_world310d.dll is missing from your computer. Try reinstalling the program to fix this problem.
. Решение 1: скопировать соответствующую библиотеку изC:\OpenCV31\opencv\build\x64\vc14\bin
к бинарным файлам проекта. Решение 2: добавить путьC:\OpenCV31\opencv\build\x64\vc14\bin
в переменную окруженияPATH
. Замечание: если сборка проекта производилась в Release-конфигурации, то данная библиотека называетсяopencv_world310.dll
.
-
Дополнить заголовочный файл
include\detection.hpp
объявлением классаCascadeDetector
, унаследовав его от классаDetector
. Замечания:cv::CascadeClassifier
- класс библиотеки OpenCV, используемый для представления сущности каскадного классификатора. Указанный класс объявлен в заголовочном файлеopencv2/objdetect/objdetect.hpp
.cv::Mat
- тип данных библиотеки OpenCV, используемый для хранения изображений.cv::Rect
- тип данных библиотеки OpenCV, используемый для преставления прямоугольника.
class CascadeDetector : public Detector {
public:
virtual bool Init(const std::string& model_file_path);
virtual void Detect(const cv::Mat& frame, std::vector<cv::Rect>& objects,
std::vector<double>& scores);
protected:
cv::CascadeClassifier detector;
};
- Добавить код для создания экземпляра класса
CascadeDetector
в фабричный методDetector::CreateDetector
.
if (name == "cascade") {
return std::make_shared<CascadeDetector>();
}
-
Реализовать метод
CascadeDetector::Init
. Метод предполагает выполнение следующей последовательности действий:- Произвести загрузку каскадного детектора из файла, с помощью метода
load
классаcv::CascadeClassifier
. - Обработать возможные ошибки при загрузке детектора
и вернуть
true
при успешной загрузке, иначеfalse
.
- Произвести загрузку каскадного детектора из файла, с помощью метода
-
Реализовать метод
CascadeDetector::Detector
. Метод предполагает выполнение следующей последовательности действий:- Проверить был ли загружен детектор из файла ранее.
- Если детектор был загружен, то осуществить детектирование
объектов на пирамиде изображений с использованием метода
cv::CascadeClassifier::detectMultiScale
. - В качестве значения параметра
score
вернуть число срабатываний детектора, пришедшихся на один объект.
-
Проверить, что после добавления класса
CascadeClassifier
проект по-прежнему компилируется. -
Сделать копию файла
samples\template_demo.cpp
под именемsamples\detection_demo.cpp
. Перегенерируйте решение с помощью CMake, чтобы среди проектов появился новый проектdetection_demo
. -
Разработать приложение
samples\detection_demo.cpp
в соответствии с требованиями, перечисленными в основных задачах.- Создать массив опций приложения:
image
- путь до исходного изображения;video
- путь до исходного видеофайла;camera
- идентификатор камеры, с которой требуется получить видеопоток;model
- путь до файла детектора. Опцииimage
,video
иcamera
взаимоисключающие, поэтому предлагается наращивать функционал постепенно, начиная с поддержки детектирования на изображении.
const char* kOptions = "{ i image | <none> | image to process }" "{ v video | <none> | video to process }" "{ c camera | <none> | camera to get video from }" "{ m model | <none> | path to detector file }" "{ h ? help usage | | print help message }";
-
Создать экземпляр класса
CascadeDetector
и загрузить детектор из файла. -
Загрузить изображение/очередной кадр видео и выполнить детектирование на нем.
-
Отрисовать все срабатывания детектора в виде прямоугольников на изображении и отобразить результат.
Примечания:
- Для загрузки изображения используйте функцию
imread
библиотеки OpenCV. - Для работы с видео используйте класс
VideoCapture
библиотеки OpenCV. - Для отображения изображения используйте функции
namedWindow
,imshow
,waitKey
модуляhighgui
библиотеки OpenCV. - Для отрисовки прямоугольника на изображении используйте функцию
rectangle
модуляimgproc
.
- Создать массив опций приложения:
-
Загрузить один из готовых детекторов из директории
data/detection/cascades/
и визуально оценить качество его работы на тестовом видео (data/video/logo.mp4
) или/и видео с веб-камеры. Также можно протестировать готовые модели для детектирования лиц/людей, которые предоставляются в составе библиотеки OpenCV (<source-каталог OpenCV>/data/*cascades/
).Примечание: для запуска приложения необходимо использовать командную строку, формат которой приведен ниже.
$ ./detection_demo.exe -d="<detector-type>" -m="<path-to-xml>" ... # <detector-type> - detector type (takes value "cascade") # <path-to-xml> - path to model (`data\detection\cascades\*.xml`).
-
Поочередно обучить детекторы на LBP- и HAAR-признаках для одного из логотипов из директории
data/detection/positives
.-
Скопировать папку
data/detection/negatives/
и файлdata/detection/negatives.txt
в текущую рабочую директорию. -
Запустить приложение
opencv_traincascade
из состава OpenCV (<build-каталог OpenCV>/bin/opencv_traincascade
или<build-каталог OpenCV>/x64/vc*/bin/opencv_traincascade
), указав следующие параметры:-
-vec <путь до vec-файла с позитивными примерами>
. Готовые vec-файлы c 2000 позитивов для некоторых логотипов можно найти в директорииdata/detection/vec_files/
. -
-numPos <кол-во позитивов для тренировки>
. -
-bg <путь до файла со списком негативных изображений>
. Файлnegatives.txt
как раз и содержит такой список. -
-numNeg <кол-во негативов для тренировки>
. -
-featureType <тип используемых признаков>
. Выберите HAAR или LBP. -
-data <путь до директории для сохранения полученного детектора>
. Директорию требуется создать заранее! -
-w <ширина объекта в пикселях> -h <высота объекта в пикселях>
. Так задается минимальный размер детектируемого объекта. -
-numStages <максимальное кол-во стадий каскада>
. -
-maxFalseAlarmRate <максимально допустимая частота ложных срабатываний>
.
-
$ opencv_traincascade -vec logo.vec -numPos 500 -bg negatives.txt -numNeg 500 -featureType HAAR -maxFalseAlarmRate 0.1 -numStages 5 -w 32 -h 32 -data logo_cascade
Замечание: работа данного приложения может занять несколько минут и время может существенно меняться в зависимости от указанных значений параметров.
-
-
Сгенерировать vec-файл для выбранного лого самостоятельно и повторить обучение детектора. Для генерации vec-файла предназначено приложение
opencv_createsamples
(<build-каталог OpenCV>/bin/opencv_createsamples
или<build-каталог OpenCV>/x64/vc*/bin/opencv_createsamples
). Данное приложение позволяет сгенерировать выборку позитивных изображений путем применения случайных геометрических преобразований и изменения яркости заданного позитивного изображения, а также наложения результата на негативное изображение. Запуск приложения без параметров приводит к перечислению всех допустимых параметров.
$ opencv_createsamples -img logo.png -bgthresh 1 -bg negatives.txt -maxxangle 0.7 -maxyangle 0.7 -maxzangle 0.5 -num 2000 -w 32 -h 32 -vec logo.vec
- Разработать приложения, решающие дополнительные задачи.