Нахожу в тесте вопросы, которые в принципе не освещаются в лекции. Нужно гуглить на других ресурсах, чтобы решить тест, или же он всё же должен испытывать знания, полученные в ходе лекции? |
Самостоятельная работа 1: Сборка и установка библиотеки OpenCV. Использование библиотеки в среде Microsoft Visual Studio
5.2.6. Отображение прямоугольников на изображении
Как было описано в предыдущем разделе, при детектировании лиц с помощью функции detectMultiScale возвращается вектор окаймляющих прямоугольников. Поэтому естественно, чтобы увидеть результат детектирования необходимо знать, как отображать эти прямоугольники на изображении.
В общем случае, чтобы отобразить изображение, на котором отрисованы какие-либо геометрические примитивы (прямоугольники, квадраты, окружности и т.п.), необходимо выполнить две операции: нарисовать примитив на изображении и отобразить полученное изображение так, как описано в разделе 4.2.4. Отметим, что функции отрисовки примитивов, как правило, называются в соответствии с англоязычными названиями этих примитивов.
Чтобы нарисовать прямоугольник, достаточно вызвать функцию rectangle, которой в качестве входных параметров передать изображения img, координаты левого верхнего pt1 и правого нижнего угла pt2 прямоугольника, а также цвет линии color для RGB- изображения или яркость для изображения в оттенках серого, толщину thickness и тип lineType. Обратите внимание, что если передать отрицательное значение толщины, что соответствует константе CV_FILLED, то будет отрисован прямоугольник, залитый цветом. Параметр shift означает количество дробных бит в координатах точек.
void rectangle(CvArr* img, CvPoint pt1, CvPoint pt2, CvScalar color, int thickness=1, int lineType=8, int shift=0)
Заметим, что наряду с геометрическими примитивами подобным образом можно написать текст на изображении. Для этого достаточно вызвать функцию putText. Подробнее с возможным набором примитивов можно ознакомиться в документации [17].
5.3. Разработка приложения для детектирования лиц на видео
Создадим проект 02_FaceDetection и файл исходного кода main.cpp в существующем решении. Конечная цель – разработать консольное приложение, которое позволяет детектировать лица на видеопотоке с использованием классификатора Хаара. Предполагается, что видеопоток извлекается из файла или поступает с веб-камеры. В качестве аргументов командной строки будем передавать название файла, содержащего натренированную модель лица, и при необходимости путь до видеофайла. Также требуется предусмотреть возможность принудительной остановки обработки видео.
const char* helper = "02_FaceDetection.exe <model_file> [<video>]\n\ \t<model_file> - полное имя файла с моделью\n\ \t<video> - путь до видеофайла (по умолчанию \n\ видеопоток принимается с камеры)\n";
Создадим функцию main с пустым телом. Перед функцией объявим пару констант DELAY и ESC_KEY. DELAY будем использовать, чтобы зафиксировать время задержки при последовательном отображении кадров видео, ESC_KEY – чтобы обозначить код клавиши Esc, при нажатии которой будет происходить принудительная остановка обработки видеопотока.
#define DELAY 30 #define ESC_KEY 27
Обратимся к разработке кода основной функции. Для этого необходимо реализовать следующую последовательность операций:
- Разобрать аргументы командной строки, чтобы извлечь полное
название файла с моделью лица и при необходимости имя видеофайла.
char *modelFileName = 0, *videoFileName = 0; if (argc < 2) { printf("%s", helper); return 1; } modelFileName = argv[1]; if (argc > 2) { videoFileName = argv[2]; }
- Создать классификатор и загрузить модель.
// создание классификатора и загрузка модели CascadeClassifier cascade; cascade.load(modelFileName);
- Загрузить видео из файла или открыть видеопоток с веб-камеры, если
название файла отсутствует в параметрах командной строки.
// загрузка видеофайла или перехват видеопотока VideoCapture capture; if (videoFileName == 0) { capture.open(0); } else { capture.open(videoFileName); } if (!capture.isOpened()) { printf("Incorrect capture name.\n"); return 1; }
- Создать окно для отображения видео.
const char* winName = "video"; // создание окна для отображения видео namedWindow(winName);
- Разработать цикл обработки последовательности кадров видепотока.
На каждой итерации цикла необходимо конвертировать текущий кадр в
оттенки серого, продетектировать лица, отрисовать полученные
окаймляющие прямоугольники на изображении и отобразить это
изображение. Тело цикла будет выполняться до тех пор, пока не будет
достигнут конец трека, либо не будет нажата клавиша Esc.
char key = -1; Mat image, gray; vector<Rect> objects; // получение кадра видеопотока capture >> image; while (image.data != 0 && key != ESC_KEY) { cvtColor(image, gray, CV_BGR2GRAY); cascade.detectMultiScale(gray, objects); for (i = 0; i < objects.size(); i++) { rectangle(image, Point(objects[i].x, objects[i].y), Point(objects[i].x+objects[i].width, objects[i].y+objects[i].height), CV_RGB(255, 0, 0), 2); } imshow(winName, image); key = waitKey(DELAY); capture >> image; gray.release(); objects.clear(); }
- Освободить ресурсы и закрыть видеопоток.
capture.release();
5.4. Запуск приложения и анализ результатов
Сделаем проект 02_FaceDetection рабочим, выполнив команду контекстного меню Set as StartUp Project…. Скомпилируем и запустим приложение. Будем считать, что видеопоток принимается с веб-камеры, поэтому передадим в качестве параметра командной строки только файл модели. Используем файл haarcascade_frontalface_default.xml.
На рис.8.24 показан результат детектирования на одном из кадров видеопотока. Приведенное изображение демонстрирует идеальный случай, когда классификатор достаточно точно обнаружил лицо человека. В данном случае неплохой результат во многом обусловлен наличием однородного фона и отсутствием предметов со сложным цветом и текстурой. Тем не менее, среди кадров даже "простого" трека всегда можно найти такие, где классификатор ошибается, т.е. вообще не находит лицо либо считает отдельные части изображения лицами.
В качестве дополнительных заданий читателю предлагается поэкспериментировать со сценами, содержащими группы людей, посмотреть результаты детектирования лиц и проанализировать полученные результаты.