Существует множество методов для поиска объектов на изображении и многие из них реализованы в 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. Для создания классификатора нужно множество изображений нужного объекта, и множество изображение где нет и части нужного нам объекта.
Запускаем программу вводим папку с положительными и отрицательными примерами в нужные поля, задаем размер искомого изображения 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 координаты найденных объектов