Пример использования SVM-HOG для поиска кругов и треугольников

Для примера возьмем несколько изображений кругов и треугольников на белом фоне.

data

И первую попавшуюся фотографию с нарисованным кругом и треугольником

DSCF2803

Запускаем Сlassifier Tool For OpenCV выбираем папки, для начало целью будут круги, устанавливаем WinSize 32/32, а detivAperature 1. Проводим обучение и получаем классификатор. На тестовом изображении получаем результат

testПовторяем тоже самое но меняем местами треугольники и круги но положительно результата не получается. В чем же дело. Причины тут две:

  • Для обучения классификатор нужно образцов порядка 5000-10000
  • В негативных образцах должны быть разнообразные изображения не содержащие искомые, а не однотипные

Видео создания классификатора

Создания HOG-SVM классификатора

Поиск и классификация объектов в OpenCV (HOG и неросеть)

Существует множество методов для поиска объектов на изображении и многие из них реализованы в OpenCV. Рассмотрю два самых популярных из них HOG+SVN и HAAR.

HOG

HOG (гистограмма ориентации градиента) если не умничать то это метод описание объекта (изображения) на основе изменения яркости.

В OpenCV есть такая замечательная вещь как HOG дескриптор – это массив чисел которой описывает как в изображении изменяется яркость, структуру ее перепадов. Самое замечательное в этом дескрипторе, что если серяи изображений будет иметь одну структуру (например табличка с названием улицы или люди идущие по улице) то и дескрипторы этих изображений будут похожи. Причём схожесть дескрипторов однотипных изображений может установить нейросеть или линейный классификатор. Из всего это следует вывод что на основе HOG дескриптора изображения можно:

1. Найти на изображении нужный нам объект;

2. Определить принадлежит ли изображения к нужному нам классу.

Как вычислить HOG дескриптор

Сперва нужно создать объект класса HOGDescriptor

HOGDescriptor hog = new HOGDescriptor(winSize, blockSize, blockStride, cellSize, nbins, aperature, winSigma);

winSize – это размер изображения оно должно совпадать с размером изображения дескриптор которого будем считать и кратно 2,например 64 на 128. Чем больше размер тем длиннее дескрипторю

все остальные параметры лучше оставить такими blockSize=(16, 16) blockStride=(8, 8) cellSize=(16, 16) nbins=9 aperature=1 winSigma=-1

Самое вычисление выглядит так

float[] f=hog.Compute(new Mat(image));

ВАЖНО!!! HOG это только для Grayscale

Как определить принадлежит ли изображения к нужному нам классу

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

Поиск объекта на изображении используя HOG+SVM

Поиск в OpenCV используя HOG+SVM задача тривиальная. Что такое SVM особо знать и не нужно это такой метод классификации. Сам поиск делается в 4 строки

HOGDescriptor hog = new HOGDescriptor();

hog.SetSVMDetector(HOGDescriptor.DefaultPeopleDetector);

CvRect[] r = hog.DetectMultiScale(new Mat(im),1)

В результате с массиве r будут координаты всех людей. Это стандартный пример поиска пешехода вшитый уже в OpenCV. Но что делать если нужно найти что то другое? Тогда нужно создать свой классификатор.

Создание своего классификатора для поиска с использованием используя HOG+SVM

Чтобы найти что-то на изображении отличное от пешехода нужно создать свой классификатор. Средств создания классификатора в OpenCV нет. Для этого можно использовать classifieropencv classifieropencv.codeplex.com. Для создания классификатора нужно множество изображений нужного объекта, и множество изображение где нет и части нужного нам объекта.

clip_image002

Запускаем программу вводим папку с положительными и отрицательными примерами в нужные поля, задаем размер искомого изображения WinSze (изображения с примерами могут быть других размеров они будут ресайзены, тут важно что потом при поиске будут искать не только объекты с таким размером но соотношении сторон должно примерно совпадать) и если нужно задаем другие парметры. Жмем большую кнопку «Create file, learn and copmute vector to DetectMultiScale» ждем и сохраняем классификатор в файл.

Как использовать свой классификатор

Тут ничего сложного все примерно также как в примере вшитом в OpenCV

HOGDescriptor hog = new OpenCvSharp.CPlusPlus.HOGDescriptor(winSize, blockSize, blockStride, cellSize, nbins, aperature, winSigma);

Важно чтобы все параметры били такими же как при создании классификатора.

hog.SetSVMDetector(d);

Здесь d это массив float из того файла что выдала программа, получить его можно так

string[] s = File.ReadAllText(файл).Split(‘ ‘);

float[] d = new float[s.Length];

for (int i = 0; i < s.Length; i++)

d[i] = (float)Convert.ToDouble(s[i]);

Продолжение кода поиска

IplImage im = new IplImage(openFileDialog1.FileName);

CvRect[] r = hog.DetectMultiScale(new Mat(im), 0);

0 – это порог чем он выше тем меньше ложных срабатываний но и больше пропусков искомых объектов, а в массиве r координаты найденных объектов