Перейти к содержимому
Compvision.ru
iskees

SVMDetector как его сделать

Recommended Posts

В OpenCV есть несколько примеров с svm детектором, в частности детектор пешехода, как он работает в принципе понятно. Собственно вопрос в том, как сделать свой детектор имея в наличии базу верных и ошибочных изображений, так чтобы можно было написать

using (HOGDescriptor des = new HOGDescriptor())

            {

               des.SetSVMDetector(HOGDescriptor.GetDefaultPeopleDetector());

               regions = des.DetectMultiScale(image);

            }

и получить результат.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Если это SVM+HOG, то посмотрите пост №134:

http://www.compvision.ru/forum/index.php?showtopic=63&view=findpost&p=6651

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

В статье из поста выше, только теоретическое описание действий без описание подробностей. Получаются нужно делать следующее:

1. Подготовить выборку положительных и отрицательных изображений с размерами толи степенями двойки толи кратные ей

2. Рассчитать HOG дескрипторы изображений, используя HOGDescriptor::compute.

3. Собрать из этих дескрипторов некий файл, верность которого можно проверить функцией библиотеки libsvm/tools/checkdata

4. Обучить SVM детектор при помощи libsvm, проверить на тестовой выборке ложные срабатывание запихать в обучающую выборку и обучить снова и так пока терпения хватит

5. Выковырять из обученного SVM детектора <float> getDefaultPeopleDetector () который и можно будет скормить openCV и добавить в его конец порог который нужно подобрать эмпирически.

Будем разбирается дальше

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

В результате экспериментов выяснилось следующее:

Hog дескриптор считается методом Compute объекта HOGDescriptor. Для этого создаем этот объект (во врапере OpenCVSharp)

OpenCvSharp.CPlusPlus.HOGDescriptor hog = new OpenCvSharp.CPlusPlus.HOGDescriptor(new CvSize(64, 16), new CvSize(16, 16), new CvSize(8, 8), new CvSize(8, 8), 9, 0, -1);

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

Первый параметр это размер изображения, чем больше размер, тем длиннее дескриптор.

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

А для создания собственно SVM детектора нужно

1. Сделать набор изображений положительных и отрицательных одного размера кратного двойке

2. Посчитать их дескрипторы

3. Дескрипторы записать в файл

Структура файла такая:

1 1:f[0] 2:f[1] .. i+1:f

Первая цифра 1-изображение из положительного набора -1-из отрицательного, потом через пробел пара индекс(считается от 1) двоеточие и значение из дескриптора

           List<string> b = new List<string>();

                foreach (string file in Положительные примеры)

                {

                        string s = "1 ";

                        IplImage im = new IplImage(file);

                        int j = 1;

                        foreach (float i in hog(im))

                        {

                            s += j.ToString() + ':' + i.ToString("0.00") + " ";

                            j++;

                        }

                        s = s.TrimEnd(' ').Replace(',', '.');

                        b.Add(s);


                }

            foreach (string file in Отрицательные примеры)

            { 

                    string s = "-1 ";

                    IplImage im = new IplImage(file);

                    int j = 1;

                    foreach (float i in hog(im))

                    {

                        s += j.ToString() + ':' + i.ToString("0.00") + " ";

                        j++;

                    }

                    s = s.TrimEnd(' ').Replace(',', '.');

                    b.Add(s); 

            }



            File.WriteAllLines("SVMHOG.dat", b.ToArray());


-----------------------------------------------------------------------


      float[] hog(IplImage im)

        {


            IplImage image = new IplImage(new CvSize(64, 16), im.Depth, im.NChannels);

            Cv.Resize(im, image);

            OpenCvSharp.CPlusPlus.HOGDescriptor hog = new OpenCvSharp.CPlusPlus.HOGDescriptor(new CvSize(64, 16), new CvSize(16, 16), new CvSize(8, 8), new CvSize(8, 8), 9, 0, -1);

            Mat m = new Mat(image);

            float[] f = hog.Compute(m);

            image.Dispose();

            m.Dispose();

            return f;


        }

4. Полученный файл скармливаем svm_learn.exe (http://svmlight.joachims.org/) через командную строку. Первый параметр это файл дескрипторов второй файл, куда будет записан результат.

5. Файл результат

SVM-light Version V6.02

0 # kernel type

3 # kernel parameter -d

1 # kernel parameter -g

1 # kernel parameter -s

1 # kernel parameter -r

empty# kernel parameter -u

252 # highest feature index

60677 # number of training documents

5160 # number of support vectors plus 1

13.06453 # threshold b, each following line is a SV (starting with alpha*y)

И затем набор векторов разделанных # и новой строкой. Берем самый последний первое число отбрасываем а все остальные в таком же формате (индекс:значение) и будут вектором который можно скормить SetSVMDetector.

Собственно все бы должно работать, ошибок не вылетает, но ничего не находит. Непонятно где ошибка.

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте учётную запись или войдите для комментирования

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

Создать учётную запись

Зарегистрируйтесь для создания учётной записи. Это просто!

Зарегистрировать учётную запись

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу

×