6. Контрольные вопросы
- Перечислите основные способы установки библиотеки OpenCV, их преимущества и недостатки.
- Назначение утилиты CMake. Причины использования данной утилиты в процессе разработки крупных проектов.
- Приведите примеры сложных задач, в которых возникает задача детектирования контуров в качестве подзадачи.
- Приведите примеры систем, в которых используется решение задачи детектирования лиц.
7. Дополнительные задания
- Модифицируйте приложение для поиска контуров объекта так, чтобы результирующее изображение сохранялось в файл.
- Модифицируйте приложение для поиска контуров объекта так, чтобы отображалось изображение, конвертированное в оттенки серого, и бинаризованное изображение, т.е. то, что показано на рис. 6.17.
- Как будет изменяться результат работы приложения для определения контуров, если изменить способ восстановления контуров? Проведите эксперименты со всеми возможными значениями параметра mode в функции findContours.
- Модифицируйте приложения, которое выполняет детектирование лиц на видеопотоке, так, чтобы результат детектирования сохранялся в видеофайл. Примечание: используйте возможности класса VideoWriter.
- Снимите видео, где была бы группа людей с разным ракурсом лица. Проанализируйте результаты детектирования на данном видео. Сравните результаты детектирования лиц с использованием других моделей лиц. Модифицируйте приложение так, чтобы добиться максимального качества детектирования. Примечание: комбинируйте результаты детектирования с помощью моделей фаса и профиля.
- Добавьте в приложение для детектирования лиц возможность детектирования глаз и других частей лица с использованием классификатора Хаара. Примечание: используйте натренированные модели, входящие в состав библиотеки OpenCV.
8. Приложения
8.1. Приложение А. Исходный код программы для поиска контуров на изображении
#include <opencv2/opencv.hpp>
using namespace cv;
int main()
{
// создание окон для отображения
const char *srcWinName = "src",
*contourWinName = "contour";
namedWindow(srcWinName, 1);
namedWindow(contourWinName,1);
// загрузка исходного изображения
Mat src = imread("apple.bmp", 1);
if (src.data == 0)
{
printf("Incorrect image name or format.\n");
return 1;
}
// создание копии исходного изображения
Mat copy = src.clone();
// создание одноканального изображения для
// конвертирования исходного изображения в
// оттенки серого
Mat gray, grayThresh;
cvtColor(src, gray, CV_BGR2GRAY);
threshold(gray, grayThresh, 120,
255, CV_THRESH_BINARY);
// поиск контуров
vector<vector<Point> > contours;
findContours(grayThresh, contours, CV_RETR_CCOMP,
CV_CHAIN_APPROX_SIMPLE);
// отображение контуров
Scalar color(0, 255, 0);
drawContours(copy, contours, -1, color, 2);
// отображение изображений
imshow(contourWinName, copy);
imshow(srcWinName, src);
// ожидание нажатия какой-либо клавиши
waitKey(0);
// освобождение ресурсов
gray.release();
grayThresh.release();
copy.release();
src.release();
return 0;
}
8.2. Приложение Б. Исходный код приложения для детектирования лиц на видепотоке
#include <opencv2/opencv.hpp>
#define DELAY 30
#define ESC_KEY 27
using namespace cv;
const char* helper =
"02_FaceDetection.exe <model_file> [<video>]\n\
\t<model_file> - model file name\n\
\t<video> - video file name (video stream will \n\
be taken from web-camera by default)\n\
";
int main(int argc, char *argv[])
{
const char* winName = "video";
char *modelFileName = 0, *videoFileName = 0;
int i;
char key = -1;
Mat image, gray;
VideoCapture capture;
vector<Rect> objects;
if (argc < 2)
{
printf("%s", helper);
return 1;
}
modelFileName = argv[1];
if (argc > 2)
{
videoFileName = argv[2];
}
// создание классификатора и загрузка модели
CascadeClassifier cascade;
cascade.load(modelFileName);
// загрузка видеофайла или перехват видеопотока
if (videoFileName == 0)
{
capture.open(0);
}
else
{
capture.open(videoFileName);
}
if (!capture.isOpened())
{
printf("Incorrect capture name.\n");
return 1;
}
// создание окна для отображения видео
namedWindow(winName);
// получение кадра видеопотока
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();
return 0;
}