Презентацию к лабораторной работе Вы можете скачать здесь.
Дополнительные материалы к лабораторной работе Вы можете скачать здесь.
Детектирование людей на изображениях и видео является одной из важнейших задач компьютерного зрения. Целью детектирования является определение наличия искомого объекта на изображении (видео) и нахождение его положения. Алгоритмы, решающие данную задачу, лежат в основе современных интерфейсов взаимодействия компьютерных систем с человеком, находящих применение как в области развлечений, так и, например, в робототехнике, следящих системах, системах помощи водителю и т.д. Одной из наиболее актуальных и, в то же время, наиболее требовательных к качеству и скорости работы подобных систем сферой применения является детектирование пешеходов на видеопотоке с камеры, установленной на движущемся автомобиле, в режиме реального времени. Системы такого рода должны обеспечивать правильное обнаружение всех людей в поле зрения камеры для возможности своевременного предотвращения аварий. При этом критичной является устойчивость к ложным срабатываниям системы, т.к. ее вмешательство в процесс управления транспортным средством должно происходить только в случае обоснованной необходимости. Скорость работы системы определяет диапазон скоростей автомобиля, при котором эффективно работает данный подход, в то же время, позволяя распознать возможную аварийную ситуацию как можно раньше. Существенные сложности при решении данной задачи связаны с многообразием внешнего вида людей, окружающих предметов и их взаимного расположения, с тем, что детектирование должно производиться на видео с движущейся камеры. Следует отметить, что создание алгоритма детектирования пешеходов, обеспечивающего требуемый уровень качества, на настоящий момент остается открытой проблемой.
Данная лабораторная работа направлена на знакомство с некоторыми подходами к детектированию пешеходов на изображениях, а также с алгоритмами и их программными реализациями, входящими в состав библиотеки OpenCV. Так, в лабораторной работе рассматривается HOG-дескриптор и основанный на его использовании простейший алгоритм детектирования. Также, многие алгоритмы, разработанные для детектирования пешеходов, успешно находят свое применение и при решении задач детектирования других объектов и наоборот. Доказательством тому может являться алгоритм LatentSVM, предназначенный для поиска различных объектов на изображениях, который в данной работе рассматривается, как алгоритм детектирования пешеходов.
Цель данной работы – изучить некоторые алгоритмы детектирования пешеходов на изображениях с использованием соответствующих функций библиотеки компьютерного зрения OpenCV.
Данная цель предполагает решение следующих задач:
В работе приводится краткое описание алгоритма вычисления HOG-признаков и детектора пешеходов, основанного на методе бегущего окна, использующего HOG-признаки и машину опорных векторов в качестве классификатора. Приводятся и описываются интерфейсы классов библиотеки OpenCV, реализующих рассматриваемые алгоритмы. Приводится описание схемы самостоятельного обучения классификаторов для решения задачи детектирования. Приводится описание интерфейса класса, реализующего алгоритм детектирования LatentSVM. Предлагаются примеры программ, демонстрирующие использование рассмотренных классов.
Вычислительные эксперименты проводились с использованием следующей инфраструктуры (табл. 15.1).
| Операционная система | Microsoft Windows 7 |
| Среда разработки | Microsoft Visual Studio 2010 |
| Библиотека TBB | Intel® Threading Building Blocks 3.0 for Windows, Update 3 (в составе Intel® Parallel Studio XE 2011 SP1) |
| Библиотеки OpenCV | Версия 2.4.4 |
Для выполнения данной лабораторной работы требуется:
При выполнении данной лабораторной работы рекомендуется следующая последовательность действий:
Задача детектирования объектов на изображениях заключается в поиске положения всех объектов заданного класса на изображении. Положение объекта можно понимать по-разному, например, как множество пикселей, соответствующих объекту, или, как координаты прямоугольника, окаймляющего объект. В данной работе рассматривается второй подход, т.е. на выходе алгоритма детектирования требуется получить множество окаймляющих прямоугольников.
В связи с актуальностью и сложностью задачи детектирования пешеходов на настоящий момент существует множество разнообразных подходов к ее решению. Так, предпринимались попытки осуществить детектирование путем сравнения предобработанных изображений с некоторыми эталонами (шаблонами) с помощью специальной метрики [1]; использования детекторов и дескрипторов особых точек [2]; применения сегментации изображения [3] и т.д. Одним из наиболее популярных и перспективных на настоящий момент подходов к детектированию объектов на изображении является, так называемый, метод бегущего окна. Данный метод основан на осуществлении экстенсивного поиска объектов определенного размера в пикселях $$w \times h$$: последовательно рассматриваются области изображения заданного размера, им ставится в соответствие признаковое описание, на основе которого с помощью алгоритма классификации принимается решение, содержит ли данная область объект или нет. Более подробно данный подход и особенности его реализации рассматриваются ниже, здесь же, отметим, что ключевыми компонентами системы детектирования, основанной на таком подходе, являются алгоритмы получения признакового описания изображения и его классификации. Одним из наиболее популярных признаковых описаний, является HOG-дескриптор (Histogram of Oriented Gradients, гистограмма ориентированных градиентов), изначально разработанный для решения задачи детектирования пешеходов [4] и на настоящий момент в том или ином виде использующийся в большинстве современных детекторов.
Основная идея, лежащая в основе HOG, заключается в том, что внешний вид и форма части объекта могут быть достаточно хорошо описаны распределением градиентов интенсивности пикселей, соответствующих данной части, без точной информации о градиентах в каждой точке. Под градиентом здесь понимается аппроксимация градиента функции интенсивности (яркости), которая предполагается дифференцируемой, но известной лишь в узлах равномерной сетки – пикселях, в заданной точке с помощью некоторой разностной схемы. Алгоритм вычисления HOG-признаков за исключением некоторых моментов идентичен алгоритму вычисления SIFT-дескриптора, описанному в лекционной части курса. Основным отличием HOG от SIFT является то, что SIFT-описание составляется для окрестности ключевой точки, в то время как HOG-признаки покрывают все изображение (более того, с перекрытием).
Базовой единицей HOG-дескриптора является блок (block) – прямоугольная область пикселей изображения заданных размеров. Блок состоит из ячеек (cells), в свою очередь состоящих из пикселей. Каждой ячейке ставится в соответствие гистограмма ориентаций (углов наклона относительно горизонтали) градиентов из заданного количества полос (bins), при этом направление считается "беззнаковым", т.е. наклон в $$/alpha$$ и $$(2\pi-\alpha)$$ считаются эквивалентными. Подобно SIFT-дескриптору магнитуда градиента в некотором пикселе дает вклад в полосы гистограммы ячейки, которой принадлежит данный пиксель, а также в гистограммы соседних ячеек. При этом используется линейная интерполяция по углу наклона (полосам одной гистограммы), и билинейная по пространственному расположению (по гистограммам соседних ячеек). Также возможно взвешивание магнитуд градиентов с помощью гауссиана с центром, совпадающим с центром блока. После вычисления гистограмм в каждой ячейке блока, они конкатенируются, тем самым образуя вектор признаков блока. Полученный вектор подвергается нормализации. Такие признаковые описания вычисляются для всех блоков, не выходящих за пределы изображения, с координатами левого верхнего пикселя кратными заданным шагам по вертикали и горизонтали. Причем данные шаги, как правило, задаются так, что блоки перекрываются, т.е. градиент пикселя учитывается при вычислении признаковых описаний нескольких блоков. HOG-описание изображения получается путем конкатенации векторов признаков всех блоков.
В библиотеке OpenCV алгоритм вычисления HOG-признаков реализован в
классе HOGDescriptor, входящем в состав модуля objdetect. Указать
параметры HOG-дескриптора можно либо при создании объекта данного
класса с помощью конструктора:
HOGDescriptor(Size winSize,
Size blockSize,
Size blockStride,
Size cellSize,
int nbins,
int derivAperture=1,
double winSigma=-1, int histogramNormType=HOGDescriptor::L2Hys,
double L2HysThreshold=0.2,
bool gammaCorrection=false,
int nlevels=HOGDescriptor::DEFAULT_NLEVELS)
либо напрямую изменяя поля данного класса:
Size winSize; Size blockSize; Size blockStride; Size cellSize; int nbins; int derivAperture; double winSigma; int histogramNormType; double L2HysThreshold; bool gammaCorrection; int nlevels;
Рассмотрим данные параметры:
winSize – размер изображения, для которого требуется вычислить
HOG-описание. В терминах детектора объектов это размеры
бегущего окна (описание HOG-детектора, основанного на методе
бегущего окна, см. ниже). blockSize – размер блока в пикселях. blockStride – шаг сетки блоков.cellSize – размер ячейки в пикселях. Размер блока должен быть
кратен размеру ячейки. nbins – количество полос в гистограмме ориентации градиентов,
соответствующей одной ячейке. derivAperture – в текущей версии OpenCV реализация HOG не
использует данный параметр. winSigma – величина стандартного отклонения, определяющая
гауссиан для взвешивания вкладов магнитуд градиентов в
гистограммы: градиенты в пикселях, находящихся ближе к центру
блока дают больший вклад. Заданное по умолчанию значение
winSigma=-1 означает, что данное стандартное отклонение будет
вычислено как (blockSize.width + blockSize.height)/8. histogramNormType – определяет каким образом
осуществляется нормализация вектора признаков блока. В
настоящий момент поддерживается только алгоритм
HOGDescriptor::L2Hys, который заключается в нормализации
вектора по $$L_2$$-метрике, замене компонент полученного вектора, превышающих L2HysThreshold, на данное пороговое значение,
и повторной нормализации по $$L_2$$-метрике. L2HysThreshold – пороговое значение, используемое при
нормализации HOG-описания блока. gammaCorrection – определяет будет ли выполнена гамма-
коррекция изображения перед вычислением признаков. В случае,
если gammaCorrection=true, интенсивность каждого пикселя
обработанного изображения будет равняться корню из его
исходной интенсивности. nlevels – максимальное количество масштабов изображения,
используемых при осуществлении детектирования объектов
различных размеров. В данном разделе рассматривается использование HOG-признаков для детектирования объектов на изображении. Однако сначала рассмотрим, каким образом можно решить задачу классификации изображений при помощи HOG-дескриптора. Пусть нам требуется определить, является ли заданное изображение изображением пешехода или нет. Другими словами, мы хотим классифицировать изображения на те, которые содержат искомый объект (пешехода), и не содержат его. Для этого, мы можем поставить в соответствие изображению его признаковое описание, полученное с помощью HOG, а затем использовать алгоритмы машинного обучения, для непосредственного осуществления классификации. Поскольку большинство алгоритмов обучения с учителем работают в пространстве признаков фиксированной размерности, вектора HOG-признаков для различных изображений должны быть одинаковой длины, а, следовательно, классифицируемые изображения должны быть одинакового размера. Более того, для обеспечения приемлемого качества решения данной задачи предполагается, что данные изображения содержат объекты одинаковых (близких) размеров, которые занимают одну и ту же область изображения.
Теперь перейдем непосредственно к решению задачи детектирования. В том случае, если выполнены изложенные выше предположения относительно размеров и расположения объектов, то данная задача эквивалентна задаче классификации и, следовательно, может быть решена описанным методом. Однако, как правило, это не так. Для обобщения на такие случаи может использоваться метод бегущего окна, который сводится к рассмотрению задачи детектирования как множества задач классификации. Пусть мы хотим осуществить поиск на изображении всех объектов заданного размера $$w \times h$$. Для этого с некоторым шагом по вертикали $$dy$$ и по горизонтали $$dx$$ рассмотрим прямоугольные области изображения размера $$w \times h$$ с верхним левым углом с координатами $$(i \cdot dx, j \cdot dy),i=\overline{0,n},j=\overline{0,m}$$ и для каждого из них произведем классификацию. Таким образом, по изображению как бы "бежит" окно размера $$w \times h$$ . Дальнейшее обобщение метода на случай поиска объектов разного размера возможно за счет многократного масштабирования изображения и осуществления детектирования описанным выше методом.
Рассмотрим функционал библиотеки OpenCV для вычисления
HOG-признаков и детектирования методом бегущего окна. Метод
compute класса HOGDescriptor позволяет извлекать признаки всех или
некоторых окон детектирования для заданного изображения:
void compute(const Mat img,
vector<float> descriptors,
Size winStride=Size(),
Size padding=Size(),
const vector<Point>amp; locations=vector<Point>()) const;
Рассмотрим параметры данного метода.
img – изображение, матрица типа CV_8UC1 или CV_8UC3. Во
втором случае в каждой точке градиент вычисляется независимо по
каждому каналу, и из них выбирается вектор наибольшей длины. descriptors – вектор, в который последовательно будут
записаны признаковые описания заданных окон детектирования. winStride – шаг окна детектирования по горизонтали и
вертикали. По умолчанию используется winStride, равный
размеру ячейки HOG. padding – размер рамки, добавляемой к изображению. Перед
запуском метода бегущего окна вокруг (справа, сверху, слева,
снизу) изображения может быть сгенерирована рамка, прежде
всего, с целью обеспечения возможности поиска частично видимых
объектов на границе изображения. Размер границы будет выровнен
до размеров кратным наибольшему общему делителю шага окна
детектирования и размера блока HOG по соответствующему
направлению. Плюс к этому будет добавлена рамка в один пиксель,
для вычисления градиента в граничных пикселях. Генерация
данной рамки производится путем отражения пикселей
изображения, т.е., например, если значения цвета пикселей
изображения обозначить за abcdefg, то изображение с рамкой
слева и справа будет выглядеть следующим образом:
gfedcb|abcdefg|fedcba. locations – положения окон детектирования, для которых
требуется вычислить векторы HOG-признаков. По умолчанию
признаки вычисляются для всех окон. В OpenCV реализован HOG-детектор, использующий в качестве классификатора машину опорных векторов с линейным ядром. Обученный линейный SVM-классификатор представляется вектором коэффициентов уравнения разделяющей гиперплоскости в пространстве признаков. Перед тем, как осуществлять детектирование необходимо с помощью метода setSVMDetector задать используемую модель классификатора:
void setSVMDetector(InputArray svmdetector);
Библиотека OpenCV содержит обученные для решения задачи
детектирования пешеходов линейные SVM-модели, которые можно
получить с помощью методов getDefaultPeopleDetector (обучена
на базе INRIA [4, 9], размер окна детектирования 64x128) и
getDaimlerPeopleDetector (обучена на базе Daimler [5, 10], размер
окна детектирования 48x96).
Для непосредственного детектирования объектов фиксированного размера
(т.е. без использования масштабирования изображения) служит метод
detect:
void detect(const Mat img,
vector<Point> foundLocations,
vector<double> weights,
double hitThreshold=0,
Size winStride=Size(),
Size padding=Size(),
const vector<Point> searchLocations=vector<Point>()
) const;
img – изображение, матрица типа CV_8UC1 или CV_8UC3 . foundLocations – координаты верхних левых углов окон
детектирования, классифицированных как содержащие объект
(срабатываний детектора). weights – веса, присвоенные классификатором срабатываниям
детектора (пропорциональны расстоянию признакового вектора от
разделяющей SVM-гиперплоскости). Можно трактовать данный
параметр, как числовую характеристику надежности решения соответствующей задачи классификации: большие значения
обозначают большую надежность. hitThreshold – минимальное значение веса (см. параметр
weights), при котором происходит срабатывание детектора. winStride – шаг окна детектирования по горизонтали и
вертикали. padding – размер рамки, добавляемой к изображению. searchLocations – положения окон детектирования, по
умолчанию используются все. Для детектирования объектов различного размера (путем масштабирования
изображения) предназначен метод detectMultiScale :
void detectMultiScale(const Mat img,
vector<Rect> foundLocations,
vector<double> foundWeights,
double hitThreshold=0,
Size winStride=Size(),
Size padding=Size(),
double scale=1.05,
double finalThreshold=2.0,
bool useMeanshiftGrouping=false) const;
Параметры img, foundLocations, foundWeights, hitThreshold,
winStride, padding по смыслу совпадают с аналогичными
параметрами метода detect . Рассмотрим оставшиеся параметры:
scale – мультипликативный шаг изменения масштаба. Исходное
изображение последовательно уменьшается в $$1,scale,scale^2,...,scale^t$$ , …,
раз, тем самым позволяя осуществлять детектирование
более мелких объектов с использованием той же SVM-модели.
Масштабирование прекращается либо в том случае, когда
полученное изображение хотя бы по одному измерению становится
меньше окна детектирования, либо по совершению nlevels (см.
параметры конструктора класса HOGDescriptor ) итераций. finalThreshold – параметр группировки (non-maximum
suppression) срабатываний детектора на всех рассматриваемых
масштабах. Значение данного параметра зависит от типа
используемой группировки. useMeanshiftGrouping – параметр, определяющий
использовать ли группировку методом сдвига среднего (Mean
Shift), или группировку на основе разбиения на классы
эквивалентности. В связи с тем, что при использовании малого
шага по масштабу возможны случаи, когда объект будет продетектирован несколько раз на различных масштабах. Следует
отметить, что подобная ситуация возможна и при детектировании с
малыми шагами окна на одном масштабе. Для того чтобы
исключить множественные срабатывания детектора на один и тот
же объект применяется группировка. В случае если
useMeanshiftGrouping=false выполняется разбиение
множества срабатываний детектора на классы эквивалентности.
Эквивалентными считаются два прямоугольника $$r_1$$ и $$r_2$$ , у которых
координаты углов отличаются меньше, чем на
$$0.1(min(r_1.width,r_2.width)+(min(r_1.height,r_2.height))$$. Затем,
в классах, в которые попало больше чем finalThreshold
прямоугольников, вычисляются "типичные представители", путем
усреднения координат углов. Полученные прямоугольники
фильтруются так, чтобы исключить ситуации, когда маленький
прямоугольник находится в большом. На этом фильтрация
считается выполненной. Метод сдвига среднего заключается в
восстановлении плотности распределения точек в трехмерном
пространстве (координаты центра прямоугольника и масштаб) с
помощью ядерной оценки и нахождении максимумов плотности. В
результате получается набор прямоугольников соответствующих
максимумам и назначенных им весов. Все прямоугольники с весом
меньшим или равным finalThreshold отсеиваются. Перейдем к рассмотрению примера использования HOG-детектора.
#include <assert.h>
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace cv;
int main()
{
// загружаем тестовое изображение
Mat img = imread("testimg.jpg");
// увеличиваем начальный масштаб изображения для
// поиска мелких объектов
resize(img, img, Size(2 * img.cols, 2 * img.rows));
// параметры HOG-дескриптора и детектора
int nbins = 9;
Size cellSize(8, 8);
Size blockSize(16, 16);
Size blockStride(8, 8);
Size winSize(64, 128); Size winStride(4, 4);
// создаем HOG-дескриптор/детектор
HOGDescriptor hog(winSize, blockSize,
blockStride, cellSize, nbins);
// устанавливаем в качестве модели
// линейную машину опорных векторов,
// соответствующую размеру окна детектирования 64x128.
hog.setSVMDetector(
HOGDescriptor::getDefaultPeopleDetector());
// проверяем соответствие количества коэффициентов
// гиперплоскости SVM и размера HOG-дескриптора
// одного окна детектирования
assert(hog.checkDetectorSize());
// производим детектирование
vector<Rect> locations;
vector<double> weights;
hog.detectMultiScale(img, locations, weights,
0.0, winStride, Size(),
1.05, 2., true);
// уменьшаем изображение до начальных размеров
resize(img, img, Size(img.cols / 2, img.rows / 2));
// отрисовываем срабатывания детектора на изображении
for (size_t i = 0; i < locations.size(); ++i)
{
Rect detection = locations[i];
detection.x /= 2;
detection.y /= 2;
detection.width /= 2;
detection.height /= 2;
rectangle(img, detection, Scalar(0, 0, 255), 2);
}
// отображаем результат
namedWindow("detections");
imshow("detections", img);
waitKey();
destroyAllWindows();
return 0;
}
Результат работы данного приложения на тестовом изображении из базы
CalTech [6] приведен на рис. 15.1.
(рис 15.1) Результат работы HOG-детектора на тестовом изображении
Выше была рассмотрена схема детектирования пешеходов на изображении с использованием имеющихся в библиотеке OpenCV обученных классификаторов (линейных SVM). Однако библиотека не предоставляет функционал для непосредственного обучения классификатора. Данный раздел посвящен описанию популярного алгоритма обучения собственных моделей. Для обучения классификатора требуется сформировать обучающую выборку, содержащую признаковые описания изображений с объектом и без него. Так как источником таких изображений, как правило, являются фотографии, большую часть которых занимает фон, а не сам объект, большинство окон детектирования не будут содержать объект. В связи с этим, требуется аккуратная балансировка прецедентов различных классов в обучающей выборке. Одним из подходов к обучению классификатора является итерационный алгоритм добавления признаковых описаний изображений фона. На нулевой итерации в обучающую выборку добавляются признаковые описания всех изображений с объектом, приведенных к нужному размеру, и выбранные случайным образом области изображений с фоном. С использованием полученной выборки осуществляется обучение классификатора, после чего выполняется детектирование объектов на изображениях фона, и выборка дополняется признаковыми описаниями ложных срабатываний детектора. Классификатор обучается на измененной выборке заново. Данный процесс повторяется несколько раз. Подобная процедура позволяет автоматически отрегулировать количество прецедентов в обучающей выборке, соответствующих изображениям без искомого объекта и, тем самым, уменьшить количество ложных срабатываний полученного детектора.
Следует отметить, что в качестве классификатора не обязательно
использовать линейную машину опорных векторов, однако, в данном
случае функцию HOG-детектора, аналогичную методу
detectMultiScale, требуется реализовывать самостоятельно.
Библиотека OpenCV содержит не только реализацию HOG-детектора, способного решать задачу детектирования пешеходов, но также и других алгоритмов детектирования объектов. Таким примером может служить алгоритм LatentSVM [7, 8], предназначенный для детектирования объектов различных классов, среди которых есть и пешеходы. Общая схема работы LatentSVM-детектора описывается в соответствующей лабораторной работе курса. В данной работе рассматривается использование программной реализации алгоритма LatentSVM из библиотеки OpenCV для детектирования пешеходов.
Функционал по использованию LatentSVM-детектора в библиотеке
OpenCV сосредоточен в классе LatentSvmDetector. Перед
выполнением детектирования требуется создать объект данного класса и
загрузить модели объектов. Это может быть сделано путем использования
конструктора
LatentSvmDetector(const vector<string> filenames,
const vector<string> classNames=vector<string>());
или конструктора по умолчанию с последующим вызовом функции
bool load(const vector<string> filenames,
const vector<string> classNames=vector<string>());
Параметрами данных методов являются:
filenames – имена xml-файлов с обученными моделями. classNames – названия классов объектов соответствующих
загружаемым моделям. Для того чтобы в дальнейшем узнать количество загруженных моделей и
назначенные им имена используются методы getClassCount и
getClassNames соответственно:
size_t getClassCount() const; const vector<string> getClassNames() const;
Для сброса загруженных моделей и их имен предназначен метод clear:
void clear();
Детектирование с помощью загруженных моделей осуществляется с
использованием метода detect:
void detect(const Mat image,
vector<ObjectDetection> objectDetections,
float overlapThreshold=0.5f,
int numThreads=-1);
Рассмотрим параметры метода:
image – изображение, на котором будет производиться
детектирование. objectDetections – срабатывания детектора, представляемые
структурой ObjectDetection. Данная структура содержит
следующие поля: rect – окаймляющий прямоугольник, score –
вес срабатывания, classID – номер класса объекта. overlapThreshold – параметр группировки срабатываний. Для
группировки прямоугольников используется следующий алгоритм.
Все срабатывания детектора сортируются по убыванию
присвоенного им классификатором веса. После чего
рассматривается первый прямоугольник (имеющий наибольший
вес) и удаляются все такие прямоугольники, что отношение
площади их пересечения к области объединения не превосходит
величины overlapThreshold. Процесс повторяется со вторым
прямоугольником и т.д. numThreads – количество вычислительных потоков,
используемых алгоритмом детектирования. Значения numThreads
меньше единицы указывают на использование одного потока (т.е.
последовательной версии кода). В составе библиотеке OpenCV предоставляются модели объектов
различных классов [11]. Файл person.xml содержит модель для
детектирования пешеходов. Рассмотрим пример программы для
детектирования алгоритмом LatentSVM.
#include <assert.h>
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace cv;
int main()
{
// загружаем тестовое изображение
Mat img = imread("testimg.jpg");
// увеличиваем начальный масштаб изображения
// для лучшего поиска мелких объектов
resize(img, img, Size(2 * img.cols, 2 * img.rows));
// создаем объект класса LatentSvmDetector
// и загружаем модель для детектирвоания пешеходов
LatentSvmDetector lsvm;
vector<string> modelFiles;
modelFiles.push_back("person.xml");
vector<string> modelNames;
modelNames.push_back("pedestrian");
lsvm.load(modelFiles, modelNames);
assert(lsvm.getClassCount() > 0);
// запускаем LatentSVM-детектор в два потока
vector<LatentSvmDetector::ObjectDetection> detections;
lsvm.detect(img, detections, 0.5f, 2);
// уменьшаем изображение до начальных размеров
resize(img, img, Size(img.cols / 2, img.rows / 2));
// устанавливаем порог весов срабатываний
float threshold = -.1f;
// отрисовываем срабатывания детектора на изображении
for (size_t i = 0; i < detections.size(); ++i)
{
LatentSvmDetector::ObjectDetection detection =
detections[i];
if (detection.score < threshold)
{
continue;
}
Rect detectionRect = detection.rect;
detectionRect.x /= 2;
detectionRect.y /= 2;
detectionRect.width /= 2;
detectionRect.height /= 2;
rectangle(img, detectionRect,
Scalar(0, 0, 255), 2);
}
// отображаем результат
namedWindow("detections"); imshow("detections", img);
waitKey();
destroyAllWindows();
return 0;
}
Результат работы данной программы на тестовом изображении приведен на рис. 15.2.
(рис 15.2) Результат работы LatentSVM-детектора на тестовом изображении
В рамках данной лабораторной работы предлагается разработать приложение для детектирования пешеходов на изображениях с использованием рассмотренных алгоритмов. К приложению предъявляются следующие требования:
Разрабатываемое приложение должно осуществлять последовательную загрузку указанных (например, всех в заданной директории) изображений. Осуществлять на них детектирование выбранным алгоритмом с заданными параметрами и выводить результат в виде отрисованных на исходном изображении срабатываний детектора. Предлагается проследить, как влияет изменение тех, или иных параметров на получаемый результат.
Следует отметить, что существуют и более объективные методы оценивания качества детектирования, нежели визуальное: построение графика зависимости процента правильно детектированных объектов от среднего числа ложных срабатываний детектора, подсчет средней точности (average precision) и т.д. Однако данные подходы обладают множеством нюансов и рекомендуется использовать уже готовые решения, например, [12].
Презентацию к лабораторной работе Вы можете скачать здесь.
Дополнительные материалы к лабораторной работе Вы можете скачать здесь.
Детектирование людей на изображениях и видео является одной из важнейших задач компьютерного зрения. Целью детектирования является определение наличия искомого объекта на изображении (видео) и нахождение его положения. Алгоритмы, решающие данную задачу, лежат в основе современных интерфейсов взаимодействия компьютерных систем с человеком, находящих применение как в области развлечений, так и, например, в робототехнике, следящих системах, системах помощи водителю и т.д. Одной из наиболее актуальных и, в то же время, наиболее требовательных к качеству и скорости работы подобных систем сферой применения является детектирование пешеходов на видеопотоке с камеры, установленной на движущемся автомобиле, в режиме реального времени. Системы такого рода должны обеспечивать правильное обнаружение всех людей в поле зрения камеры для возможности своевременного предотвращения аварий. При этом критичной является устойчивость к ложным срабатываниям системы, т.к. ее вмешательство в процесс управления транспортным средством должно происходить только в случае обоснованной необходимости. Скорость работы системы определяет диапазон скоростей автомобиля, при котором эффективно работает данный подход, в то же время, позволяя распознать возможную аварийную ситуацию как можно раньше. Существенные сложности при решении данной задачи связаны с многообразием внешнего вида людей, окружающих предметов и их взаимного расположения, с тем, что детектирование должно производиться на видео с движущейся камеры. Следует отметить, что создание алгоритма детектирования пешеходов, обеспечивающего требуемый уровень качества, на настоящий момент остается открытой проблемой.
Данная лабораторная работа направлена на знакомство с некоторыми подходами к детектированию пешеходов на изображениях, а также с алгоритмами и их программными реализациями, входящими в состав библиотеки OpenCV. Так, в лабораторной работе рассматривается HOG-дескриптор и основанный на его использовании простейший алгоритм детектирования. Также, многие алгоритмы, разработанные для детектирования пешеходов, успешно находят свое применение и при решении задач детектирования других объектов и наоборот. Доказательством тому может являться алгоритм LatentSVM, предназначенный для поиска различных объектов на изображениях, который в данной работе рассматривается, как алгоритм детектирования пешеходов.
Цель данной работы – изучить некоторые алгоритмы детектирования пешеходов на изображениях с использованием соответствующих функций библиотеки компьютерного зрения OpenCV.
Данная цель предполагает решение следующих задач:
В работе приводится краткое описание алгоритма вычисления HOG-признаков и детектора пешеходов, основанного на методе бегущего окна, использующего HOG-признаки и машину опорных векторов в качестве классификатора. Приводятся и описываются интерфейсы классов библиотеки OpenCV, реализующих рассматриваемые алгоритмы. Приводится описание схемы самостоятельного обучения классификаторов для решения задачи детектирования. Приводится описание интерфейса класса, реализующего алгоритм детектирования LatentSVM. Предлагаются примеры программ, демонстрирующие использование рассмотренных классов.
Вычислительные эксперименты проводились с использованием следующей инфраструктуры (табл. 15.1).
| Операционная система | Microsoft Windows 7 |
| Среда разработки | Microsoft Visual Studio 2010 |
| Библиотека TBB | Intel® Threading Building Blocks 3.0 for Windows, Update 3 (в составе Intel® Parallel Studio XE 2011 SP1) |
| Библиотеки OpenCV | Версия 2.4.4 |
Для выполнения данной лабораторной работы требуется:
При выполнении данной лабораторной работы рекомендуется следующая последовательность действий:
Задача детектирования объектов на изображениях заключается в поиске положения всех объектов заданного класса на изображении. Положение объекта можно понимать по-разному, например, как множество пикселей, соответствующих объекту, или, как координаты прямоугольника, окаймляющего объект. В данной работе рассматривается второй подход, т.е. на выходе алгоритма детектирования требуется получить множество окаймляющих прямоугольников.
В связи с актуальностью и сложностью задачи детектирования пешеходов на настоящий момент существует множество разнообразных подходов к ее решению. Так, предпринимались попытки осуществить детектирование путем сравнения предобработанных изображений с некоторыми эталонами (шаблонами) с помощью специальной метрики [1]; использования детекторов и дескрипторов особых точек [2]; применения сегментации изображения [3] и т.д. Одним из наиболее популярных и перспективных на настоящий момент подходов к детектированию объектов на изображении является, так называемый, метод бегущего окна. Данный метод основан на осуществлении экстенсивного поиска объектов определенного размера в пикселях $$w \times h$$: последовательно рассматриваются области изображения заданного размера, им ставится в соответствие признаковое описание, на основе которого с помощью алгоритма классификации принимается решение, содержит ли данная область объект или нет. Более подробно данный подход и особенности его реализации рассматриваются ниже, здесь же, отметим, что ключевыми компонентами системы детектирования, основанной на таком подходе, являются алгоритмы получения признакового описания изображения и его классификации. Одним из наиболее популярных признаковых описаний, является HOG-дескриптор (Histogram of Oriented Gradients, гистограмма ориентированных градиентов), изначально разработанный для решения задачи детектирования пешеходов [4] и на настоящий момент в том или ином виде использующийся в большинстве современных детекторов.
Основная идея, лежащая в основе HOG, заключается в том, что внешний вид и форма части объекта могут быть достаточно хорошо описаны распределением градиентов интенсивности пикселей, соответствующих данной части, без точной информации о градиентах в каждой точке. Под градиентом здесь понимается аппроксимация градиента функции интенсивности (яркости), которая предполагается дифференцируемой, но известной лишь в узлах равномерной сетки – пикселях, в заданной точке с помощью некоторой разностной схемы. Алгоритм вычисления HOG-признаков за исключением некоторых моментов идентичен алгоритму вычисления SIFT-дескриптора, описанному в лекционной части курса. Основным отличием HOG от SIFT является то, что SIFT-описание составляется для окрестности ключевой точки, в то время как HOG-признаки покрывают все изображение (более того, с перекрытием).
Базовой единицей HOG-дескриптора является блок (block) – прямоугольная область пикселей изображения заданных размеров. Блок состоит из ячеек (cells), в свою очередь состоящих из пикселей. Каждой ячейке ставится в соответствие гистограмма ориентаций (углов наклона относительно горизонтали) градиентов из заданного количества полос (bins), при этом направление считается "беззнаковым", т.е. наклон в $$/alpha$$ и $$(2\pi-\alpha)$$ считаются эквивалентными. Подобно SIFT-дескриптору магнитуда градиента в некотором пикселе дает вклад в полосы гистограммы ячейки, которой принадлежит данный пиксель, а также в гистограммы соседних ячеек. При этом используется линейная интерполяция по углу наклона (полосам одной гистограммы), и билинейная по пространственному расположению (по гистограммам соседних ячеек). Также возможно взвешивание магнитуд градиентов с помощью гауссиана с центром, совпадающим с центром блока. После вычисления гистограмм в каждой ячейке блока, они конкатенируются, тем самым образуя вектор признаков блока. Полученный вектор подвергается нормализации. Такие признаковые описания вычисляются для всех блоков, не выходящих за пределы изображения, с координатами левого верхнего пикселя кратными заданным шагам по вертикали и горизонтали. Причем данные шаги, как правило, задаются так, что блоки перекрываются, т.е. градиент пикселя учитывается при вычислении признаковых описаний нескольких блоков. HOG-описание изображения получается путем конкатенации векторов признаков всех блоков.
В библиотеке OpenCV алгоритм вычисления HOG-признаков реализован в
классе HOGDescriptor, входящем в состав модуля objdetect. Указать
параметры HOG-дескриптора можно либо при создании объекта данного
класса с помощью конструктора:
HOGDescriptor(Size winSize,
Size blockSize,
Size blockStride,
Size cellSize,
int nbins,
int derivAperture=1,
double winSigma=-1, int histogramNormType=HOGDescriptor::L2Hys,
double L2HysThreshold=0.2,
bool gammaCorrection=false,
int nlevels=HOGDescriptor::DEFAULT_NLEVELS)
либо напрямую изменяя поля данного класса:
Size winSize; Size blockSize; Size blockStride; Size cellSize; int nbins; int derivAperture; double winSigma; int histogramNormType; double L2HysThreshold; bool gammaCorrection; int nlevels;
Рассмотрим данные параметры:
winSize – размер изображения, для которого требуется вычислить
HOG-описание. В терминах детектора объектов это размеры
бегущего окна (описание HOG-детектора, основанного на методе
бегущего окна, см. ниже). blockSize – размер блока в пикселях. blockStride – шаг сетки блоков.cellSize – размер ячейки в пикселях. Размер блока должен быть
кратен размеру ячейки. nbins – количество полос в гистограмме ориентации градиентов,
соответствующей одной ячейке. derivAperture – в текущей версии OpenCV реализация HOG не
использует данный параметр. winSigma – величина стандартного отклонения, определяющая
гауссиан для взвешивания вкладов магнитуд градиентов в
гистограммы: градиенты в пикселях, находящихся ближе к центру
блока дают больший вклад. Заданное по умолчанию значение
winSigma=-1 означает, что данное стандартное отклонение будет
вычислено как (blockSize.width + blockSize.height)/8. histogramNormType – определяет каким образом
осуществляется нормализация вектора признаков блока. В
настоящий момент поддерживается только алгоритм
HOGDescriptor::L2Hys, который заключается в нормализации
вектора по $$L_2$$-метрике, замене компонент полученного вектора, превышающих L2HysThreshold, на данное пороговое значение,
и повторной нормализации по $$L_2$$-метрике. L2HysThreshold – пороговое значение, используемое при
нормализации HOG-описания блока. gammaCorrection – определяет будет ли выполнена гамма-
коррекция изображения перед вычислением признаков. В случае,
если gammaCorrection=true, интенсивность каждого пикселя
обработанного изображения будет равняться корню из его
исходной интенсивности. nlevels – максимальное количество масштабов изображения,
используемых при осуществлении детектирования объектов
различных размеров. В данном разделе рассматривается использование HOG-признаков для детектирования объектов на изображении. Однако сначала рассмотрим, каким образом можно решить задачу классификации изображений при помощи HOG-дескриптора. Пусть нам требуется определить, является ли заданное изображение изображением пешехода или нет. Другими словами, мы хотим классифицировать изображения на те, которые содержат искомый объект (пешехода), и не содержат его. Для этого, мы можем поставить в соответствие изображению его признаковое описание, полученное с помощью HOG, а затем использовать алгоритмы машинного обучения, для непосредственного осуществления классификации. Поскольку большинство алгоритмов обучения с учителем работают в пространстве признаков фиксированной размерности, вектора HOG-признаков для различных изображений должны быть одинаковой длины, а, следовательно, классифицируемые изображения должны быть одинакового размера. Более того, для обеспечения приемлемого качества решения данной задачи предполагается, что данные изображения содержат объекты одинаковых (близких) размеров, которые занимают одну и ту же область изображения.
Теперь перейдем непосредственно к решению задачи детектирования. В том случае, если выполнены изложенные выше предположения относительно размеров и расположения объектов, то данная задача эквивалентна задаче классификации и, следовательно, может быть решена описанным методом. Однако, как правило, это не так. Для обобщения на такие случаи может использоваться метод бегущего окна, который сводится к рассмотрению задачи детектирования как множества задач классификации. Пусть мы хотим осуществить поиск на изображении всех объектов заданного размера $$w \times h$$. Для этого с некоторым шагом по вертикали $$dy$$ и по горизонтали $$dx$$ рассмотрим прямоугольные области изображения размера $$w \times h$$ с верхним левым углом с координатами $$(i \cdot dx, j \cdot dy),i=\overline{0,n},j=\overline{0,m}$$ и для каждого из них произведем классификацию. Таким образом, по изображению как бы "бежит" окно размера $$w \times h$$ . Дальнейшее обобщение метода на случай поиска объектов разного размера возможно за счет многократного масштабирования изображения и осуществления детектирования описанным выше методом.
Рассмотрим функционал библиотеки OpenCV для вычисления
HOG-признаков и детектирования методом бегущего окна. Метод
compute класса HOGDescriptor позволяет извлекать признаки всех или
некоторых окон детектирования для заданного изображения:
void compute(const Mat img,
vector<float> descriptors,
Size winStride=Size(),
Size padding=Size(),
const vector<Point>amp; locations=vector<Point>()) const;
Рассмотрим параметры данного метода.
img – изображение, матрица типа CV_8UC1 или CV_8UC3. Во
втором случае в каждой точке градиент вычисляется независимо по
каждому каналу, и из них выбирается вектор наибольшей длины. descriptors – вектор, в который последовательно будут
записаны признаковые описания заданных окон детектирования. winStride – шаг окна детектирования по горизонтали и
вертикали. По умолчанию используется winStride, равный
размеру ячейки HOG. padding – размер рамки, добавляемой к изображению. Перед
запуском метода бегущего окна вокруг (справа, сверху, слева,
снизу) изображения может быть сгенерирована рамка, прежде
всего, с целью обеспечения возможности поиска частично видимых
объектов на границе изображения. Размер границы будет выровнен
до размеров кратным наибольшему общему делителю шага окна
детектирования и размера блока HOG по соответствующему
направлению. Плюс к этому будет добавлена рамка в один пиксель,
для вычисления градиента в граничных пикселях. Генерация
данной рамки производится путем отражения пикселей
изображения, т.е., например, если значения цвета пикселей
изображения обозначить за abcdefg, то изображение с рамкой
слева и справа будет выглядеть следующим образом:
gfedcb|abcdefg|fedcba. locations – положения окон детектирования, для которых
требуется вычислить векторы HOG-признаков. По умолчанию
признаки вычисляются для всех окон. В OpenCV реализован HOG-детектор, использующий в качестве классификатора машину опорных векторов с линейным ядром. Обученный линейный SVM-классификатор представляется вектором коэффициентов уравнения разделяющей гиперплоскости в пространстве признаков. Перед тем, как осуществлять детектирование необходимо с помощью метода setSVMDetector задать используемую модель классификатора:
void setSVMDetector(InputArray svmdetector);
Библиотека OpenCV содержит обученные для решения задачи
детектирования пешеходов линейные SVM-модели, которые можно
получить с помощью методов getDefaultPeopleDetector (обучена
на базе INRIA [4, 9], размер окна детектирования 64x128) и
getDaimlerPeopleDetector (обучена на базе Daimler [5, 10], размер
окна детектирования 48x96).
Для непосредственного детектирования объектов фиксированного размера
(т.е. без использования масштабирования изображения) служит метод
detect:
void detect(const Mat img,
vector<Point> foundLocations,
vector<double> weights,
double hitThreshold=0,
Size winStride=Size(),
Size padding=Size(),
const vector<Point> searchLocations=vector<Point>()
) const;
img – изображение, матрица типа CV_8UC1 или CV_8UC3 . foundLocations – координаты верхних левых углов окон
детектирования, классифицированных как содержащие объект
(срабатываний детектора). weights – веса, присвоенные классификатором срабатываниям
детектора (пропорциональны расстоянию признакового вектора от
разделяющей SVM-гиперплоскости). Можно трактовать данный
параметр, как числовую характеристику надежности решения соответствующей задачи классификации: большие значения
обозначают большую надежность. hitThreshold – минимальное значение веса (см. параметр
weights), при котором происходит срабатывание детектора. winStride – шаг окна детектирования по горизонтали и
вертикали. padding – размер рамки, добавляемой к изображению. searchLocations – положения окон детектирования, по
умолчанию используются все. Для детектирования объектов различного размера (путем масштабирования
изображения) предназначен метод detectMultiScale :
void detectMultiScale(const Mat img,
vector<Rect> foundLocations,
vector<double> foundWeights,
double hitThreshold=0,
Size winStride=Size(),
Size padding=Size(),
double scale=1.05,
double finalThreshold=2.0,
bool useMeanshiftGrouping=false) const;
Параметры img, foundLocations, foundWeights, hitThreshold,
winStride, padding по смыслу совпадают с аналогичными
параметрами метода detect . Рассмотрим оставшиеся параметры:
scale – мультипликативный шаг изменения масштаба. Исходное
изображение последовательно уменьшается в $$1,scale,scale^2,...,scale^t$$ , …,
раз, тем самым позволяя осуществлять детектирование
более мелких объектов с использованием той же SVM-модели.
Масштабирование прекращается либо в том случае, когда
полученное изображение хотя бы по одному измерению становится
меньше окна детектирования, либо по совершению nlevels (см.
параметры конструктора класса HOGDescriptor ) итераций. finalThreshold – параметр группировки (non-maximum
suppression) срабатываний детектора на всех рассматриваемых
масштабах. Значение данного параметра зависит от типа
используемой группировки. useMeanshiftGrouping – параметр, определяющий
использовать ли группировку методом сдвига среднего (Mean
Shift), или группировку на основе разбиения на классы
эквивалентности. В связи с тем, что при использовании малого
шага по масштабу возможны случаи, когда объект будет продетектирован несколько раз на различных масштабах. Следует
отметить, что подобная ситуация возможна и при детектировании с
малыми шагами окна на одном масштабе. Для того чтобы
исключить множественные срабатывания детектора на один и тот
же объект применяется группировка. В случае если
useMeanshiftGrouping=false выполняется разбиение
множества срабатываний детектора на классы эквивалентности.
Эквивалентными считаются два прямоугольника $$r_1$$ и $$r_2$$ , у которых
координаты углов отличаются меньше, чем на
$$0.1(min(r_1.width,r_2.width)+(min(r_1.height,r_2.height))$$. Затем,
в классах, в которые попало больше чем finalThreshold
прямоугольников, вычисляются "типичные представители", путем
усреднения координат углов. Полученные прямоугольники
фильтруются так, чтобы исключить ситуации, когда маленький
прямоугольник находится в большом. На этом фильтрация
считается выполненной. Метод сдвига среднего заключается в
восстановлении плотности распределения точек в трехмерном
пространстве (координаты центра прямоугольника и масштаб) с
помощью ядерной оценки и нахождении максимумов плотности. В
результате получается набор прямоугольников соответствующих
максимумам и назначенных им весов. Все прямоугольники с весом
меньшим или равным finalThreshold отсеиваются. Перейдем к рассмотрению примера использования HOG-детектора.
#include <assert.h>
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace cv;
int main()
{
// загружаем тестовое изображение
Mat img = imread("testimg.jpg");
// увеличиваем начальный масштаб изображения для
// поиска мелких объектов
resize(img, img, Size(2 * img.cols, 2 * img.rows));
// параметры HOG-дескриптора и детектора
int nbins = 9;
Size cellSize(8, 8);
Size blockSize(16, 16);
Size blockStride(8, 8);
Size winSize(64, 128); Size winStride(4, 4);
// создаем HOG-дескриптор/детектор
HOGDescriptor hog(winSize, blockSize,
blockStride, cellSize, nbins);
// устанавливаем в качестве модели
// линейную машину опорных векторов,
// соответствующую размеру окна детектирования 64x128.
hog.setSVMDetector(
HOGDescriptor::getDefaultPeopleDetector());
// проверяем соответствие количества коэффициентов
// гиперплоскости SVM и размера HOG-дескриптора
// одного окна детектирования
assert(hog.checkDetectorSize());
// производим детектирование
vector<Rect> locations;
vector<double> weights;
hog.detectMultiScale(img, locations, weights,
0.0, winStride, Size(),
1.05, 2., true);
// уменьшаем изображение до начальных размеров
resize(img, img, Size(img.cols / 2, img.rows / 2));
// отрисовываем срабатывания детектора на изображении
for (size_t i = 0; i < locations.size(); ++i)
{
Rect detection = locations[i];
detection.x /= 2;
detection.y /= 2;
detection.width /= 2;
detection.height /= 2;
rectangle(img, detection, Scalar(0, 0, 255), 2);
}
// отображаем результат
namedWindow("detections");
imshow("detections", img);
waitKey();
destroyAllWindows();
return 0;
}
Результат работы данного приложения на тестовом изображении из базы
CalTech [6] приведен на рис. 15.1.
(рис 15.1) Результат работы HOG-детектора на тестовом изображении
Выше была рассмотрена схема детектирования пешеходов на изображении с использованием имеющихся в библиотеке OpenCV обученных классификаторов (линейных SVM). Однако библиотека не предоставляет функционал для непосредственного обучения классификатора. Данный раздел посвящен описанию популярного алгоритма обучения собственных моделей. Для обучения классификатора требуется сформировать обучающую выборку, содержащую признаковые описания изображений с объектом и без него. Так как источником таких изображений, как правило, являются фотографии, большую часть которых занимает фон, а не сам объект, большинство окон детектирования не будут содержать объект. В связи с этим, требуется аккуратная балансировка прецедентов различных классов в обучающей выборке. Одним из подходов к обучению классификатора является итерационный алгоритм добавления признаковых описаний изображений фона. На нулевой итерации в обучающую выборку добавляются признаковые описания всех изображений с объектом, приведенных к нужному размеру, и выбранные случайным образом области изображений с фоном. С использованием полученной выборки осуществляется обучение классификатора, после чего выполняется детектирование объектов на изображениях фона, и выборка дополняется признаковыми описаниями ложных срабатываний детектора. Классификатор обучается на измененной выборке заново. Данный процесс повторяется несколько раз. Подобная процедура позволяет автоматически отрегулировать количество прецедентов в обучающей выборке, соответствующих изображениям без искомого объекта и, тем самым, уменьшить количество ложных срабатываний полученного детектора.
Следует отметить, что в качестве классификатора не обязательно
использовать линейную машину опорных векторов, однако, в данном
случае функцию HOG-детектора, аналогичную методу
detectMultiScale, требуется реализовывать самостоятельно.
Библиотека OpenCV содержит не только реализацию HOG-детектора, способного решать задачу детектирования пешеходов, но также и других алгоритмов детектирования объектов. Таким примером может служить алгоритм LatentSVM [7, 8], предназначенный для детектирования объектов различных классов, среди которых есть и пешеходы. Общая схема работы LatentSVM-детектора описывается в соответствующей лабораторной работе курса. В данной работе рассматривается использование программной реализации алгоритма LatentSVM из библиотеки OpenCV для детектирования пешеходов.
Функционал по использованию LatentSVM-детектора в библиотеке
OpenCV сосредоточен в классе LatentSvmDetector. Перед
выполнением детектирования требуется создать объект данного класса и
загрузить модели объектов. Это может быть сделано путем использования
конструктора
LatentSvmDetector(const vector<string> filenames,
const vector<string> classNames=vector<string>());
или конструктора по умолчанию с последующим вызовом функции
bool load(const vector<string> filenames,
const vector<string> classNames=vector<string>());
Параметрами данных методов являются:
filenames – имена xml-файлов с обученными моделями. classNames – названия классов объектов соответствующих
загружаемым моделям. Для того чтобы в дальнейшем узнать количество загруженных моделей и
назначенные им имена используются методы getClassCount и
getClassNames соответственно:
size_t getClassCount() const; const vector<string> getClassNames() const;
Для сброса загруженных моделей и их имен предназначен метод clear:
void clear();
Детектирование с помощью загруженных моделей осуществляется с
использованием метода detect:
void detect(const Mat image,
vector<ObjectDetection> objectDetections,
float overlapThreshold=0.5f,
int numThreads=-1);
Рассмотрим параметры метода:
image – изображение, на котором будет производиться
детектирование. objectDetections – срабатывания детектора, представляемые
структурой ObjectDetection. Данная структура содержит
следующие поля: rect – окаймляющий прямоугольник, score –
вес срабатывания, classID – номер класса объекта. overlapThreshold – параметр группировки срабатываний. Для
группировки прямоугольников используется следующий алгоритм.
Все срабатывания детектора сортируются по убыванию
присвоенного им классификатором веса. После чего
рассматривается первый прямоугольник (имеющий наибольший
вес) и удаляются все такие прямоугольники, что отношение
площади их пересечения к области объединения не превосходит
величины overlapThreshold. Процесс повторяется со вторым
прямоугольником и т.д. numThreads – количество вычислительных потоков,
используемых алгоритмом детектирования. Значения numThreads
меньше единицы указывают на использование одного потока (т.е.
последовательной версии кода). В составе библиотеке OpenCV предоставляются модели объектов
различных классов [11]. Файл person.xml содержит модель для
детектирования пешеходов. Рассмотрим пример программы для
детектирования алгоритмом LatentSVM.
#include <assert.h>
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace cv;
int main()
{
// загружаем тестовое изображение
Mat img = imread("testimg.jpg");
// увеличиваем начальный масштаб изображения
// для лучшего поиска мелких объектов
resize(img, img, Size(2 * img.cols, 2 * img.rows));
// создаем объект класса LatentSvmDetector
// и загружаем модель для детектирвоания пешеходов
LatentSvmDetector lsvm;
vector<string> modelFiles;
modelFiles.push_back("person.xml");
vector<string> modelNames;
modelNames.push_back("pedestrian");
lsvm.load(modelFiles, modelNames);
assert(lsvm.getClassCount() > 0);
// запускаем LatentSVM-детектор в два потока
vector<LatentSvmDetector::ObjectDetection> detections;
lsvm.detect(img, detections, 0.5f, 2);
// уменьшаем изображение до начальных размеров
resize(img, img, Size(img.cols / 2, img.rows / 2));
// устанавливаем порог весов срабатываний
float threshold = -.1f;
// отрисовываем срабатывания детектора на изображении
for (size_t i = 0; i < detections.size(); ++i)
{
LatentSvmDetector::ObjectDetection detection =
detections[i];
if (detection.score < threshold)
{
continue;
}
Rect detectionRect = detection.rect;
detectionRect.x /= 2;
detectionRect.y /= 2;
detectionRect.width /= 2;
detectionRect.height /= 2;
rectangle(img, detectionRect,
Scalar(0, 0, 255), 2);
}
// отображаем результат
namedWindow("detections"); imshow("detections", img);
waitKey();
destroyAllWindows();
return 0;
}
Результат работы данной программы на тестовом изображении приведен на рис. 15.2.
(рис 15.2) Результат работы LatentSVM-детектора на тестовом изображении
В рамках данной лабораторной работы предлагается разработать приложение для детектирования пешеходов на изображениях с использованием рассмотренных алгоритмов. К приложению предъявляются следующие требования:
Разрабатываемое приложение должно осуществлять последовательную загрузку указанных (например, всех в заданной директории) изображений. Осуществлять на них детектирование выбранным алгоритмом с заданными параметрами и выводить результат в виде отрисованных на исходном изображении срабатываний детектора. Предлагается проследить, как влияет изменение тех, или иных параметров на получаемый результат.
Следует отметить, что существуют и более объективные методы оценивания качества детектирования, нежели визуальное: построение графика зависимости процента правильно детектированных объектов от среднего числа ложных срабатываний детектора, подсчет средней точности (average precision) и т.д. Однако данные подходы обладают множеством нюансов и рекомендуется использовать уже готовые решения, например, [12].
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.