17 января 2014 в 02:59

Пару слов о распознавании образов tutorial

Давно хотел написать общую статью, содержащую в себе самые основы Image Recognition, некий гайд по базовым методам, рассказывающий, когда их применять, какие задачи они решают, что возможно сделать вечером на коленке, а о чём лучше и не думать, не имея команды человек в 20.
image

Какие-то статьи по Optical Recognition я пишу давненько, так что пару раз в месяц мне пишут различные люди с вопросами по этой тематике. Иногда создаётся ощущение, что живёшь с ними в разных мирах. С одной стороны понимаешь, что человек скорее всего профессионал в смежной теме, но в методах оптического распознавания знает очень мало. И самое обидное, что он пытается применить метод из близрасположенной области знаний, который логичен, но в Image Recognition полностью не работает, но не понимает этого и сильно обижается, если ему начать рассказывать что-нибудь с самых основ. А учитывая, что рассказывать с основ — много времени, которого часто нет, становится всё ещё печальнее.

Эта статья задумана для того, чтобы человек, который никогда не занимался методами распознавания изображений, смог в течении 10-15 минут создать у себя в голове некую базовую картину мира, соответствующую тематике, и понять в какую сторону ему копать. Многие методы, которые тут описаны, применимы к радиолокации и аудио-обработке.
Начну с пары принципов, которые мы всегда начинаем рассказывать потенциальному заказчику, или человеку, который хочет начать заниматься Optical Recognition:
  • При решении задачи всегда идти от простейшего. Гораздо проще повесить на персону метку оранжевого цвета, чем следить за человеком, выделяя его каскадами. Гораздо проще взять камеру с большим разрешением, чем разрабатывать сверхразрешающий алгоритм.
  • Строгая постановка задачи в методах оптического распознавания на порядки важнее, чем в задачах системного программирования: одно лишнее слово в ТЗ может добавить 50% работы.
  • В задачах распознавания нет универсальных решений. Нельзя сделать алгоритм, который будет просто «распознавать любую надпись». Табличка на улице и лист текста — это принципиально разные объекты. Наверное, можно сделать общий алгоритм(вот хороший пример от гугла), но это будет требовать огромного труда большой команды и состоять из десятков различных подпрограмм.
  • OpenCV — это библия, в которой есть множество методов, и с помощью которой можно решить 50% от объёма почти любой задачи, но OpenCV — это лишь малая часть того, что в реальности можно сделать. В одном исследовании в выводах было написано: «Задача не решается методами OpenCV, следовательно, она неразрешима». Старайтесь избегать такого, не лениться и трезво оценивать текущую задачу каждый раз с нуля, не используя OpenCV-шаблоны.

Очень сложно давать какой-то универсальный совет, или рассказать как создать какую-то структуру, вокруг которой можно строить решение произвольных задач компьютерного зрения. Цель этой статьи в структуризации того, что можно использовать. Я попробую разбить существующие методы на три группы. Первая группа это предварительная фильтрация и подготовка изображения. Вторая группа это логическая обработка результатов фильтрации. Третья группа это алгоритмы принятия решений на основе логической обработки. Границы между группами очень условные. Для решения задачи далеко не всегда нужно применять методы из всех групп, бывает достаточно двух, а иногда даже одного.

Список приведённых тут методов не полон. Предлагаю в комментариях добавлять критические методы, которые я не написал и приписывать каждому по 2-3 сопроводительных слова.

Часть 1. Фильтрация


В эту группу я поместил методы, которые позволяют выделить на изображениях интересующие области, без их анализа. Большая часть этих методов применяет какое-то единое преобразование ко всем точкам изображения. На уровне фильтрации анализ изображения не производится, но точки, которые проходят фильтрацию, можно рассматривать как области с особыми характеристиками.

Бинаризация по порогу, выбор области гистограммы

Самое просто преобразование — это бинаризация изображения по порогу. Для RGB изображения и изображения в градациях серого порогом является значение цвета. Встречаются идеальные задачи, в которых такого преобразования достаточно. Предположим, нужно автоматически выделить предметы на белом листе бумаги:
image
image
Выбор порога, по которому происходит бинаризация, во многом определяет процесс самой бинаризации. В данном случае, изображение было бинаризовано по среднему цвету. Обычно бинаризация осуществляется с помощью алгоритма, который адаптивно выбирает порог. Таким алгоритмом может быть выбор матожидания или моды. А можно выбрать наибольший пик гистограммы.
image
Бинаризация может дать очень интересные результаты при работе с гистограммами, в том числе в ситуации, если мы рассматриваем изображение не в RGB, а в HSV . Например, сегментировать интересующие цвета. На этом принципе можно построить как детектор метки так и детектор кожи человека.
image image

Классическая фильтрация: Фурье, ФНЧ, ФВЧ

Классические методы фильтрации из радиолокации и обработки сигналов можно с успехом применять во множестве задач Pattern Recognition. Традиционным методом в радиолокации, который почти не используется в изображениях в чистом виде, является преобразование Фурье (конкретнее — БПФ ). Одно из немногих исключение, при которых используется одномерное преобразование Фурье, — компрессия изображений. Для анализа изображений одномерного преобразования обычно не хватает, нужно использовать куда более ресурсоёмкое двумерное преобразование.
image
Мало кто его в действительности рассчитывает, обычно, куда быстрее и проще использовать свёртку интересующей области с уже готовым фильтром, заточенным на высокие (ФВЧ) или низкие(ФНЧ) частоты. Такой метод, конечно, не позволяет сделать анализ спектра, но в конкретной задаче видеообработки обычно нужен не анализ, а результат.
image
image
Самые простые примеры фильтров, реализующих подчёркивание низких частот (фильтр Гаусса) и высоких частот (Фильтр Габора).
Для каждой точки изображения выбирается окно и перемножается с фильтром того же размера. Результатом такой свёртки является новое значение точки. При реализации ФНЧ и ФВЧ получаются изображения такого типа:
image
image
Вейвлеты

Но что если использовать для свёртки с сигналом некую произвольную характеристическую функцию? Тогда это будет называться "Вейвлет-преобразование". Это определение вейвлетов не является корректным, но традиционно сложилось, что во многих командах вейвлет-анализом называется поиск произвольного паттерна на изображении при помощи свёртки с моделью этого паттерна. Существует набор классических функций, используемых в вейвлет-анализе. К ним относятся вейвлет Хаара, вейвлет Морле, вейвлет мексиканская шляпа, и.т.д. Примитивы Хаара, про которые было несколько моих прошлых статей (1, 2), относятся к таким функциям для двумерного пространства.
image image
image image
Выше приведено 4 примера классических вейвлетов. 3х-мерный вейвлет Хаара, 2х-мерные вейвлет Мейера, вейвлет Мексиканская Шляпа, вейвлет Добеши. Хорошим примером использования расширеной трактовки вейвлетов является задачка поиска блика в глазу, для которой вейвлетом является сам блик:
image
Классические вейвлеты обычно используются для сжатия изображений, или для их классификации (будет описано ниже).

Корреляция

После такой вольной трактовки вейвлетов с моей стороны стоит упомянуть собственно корреляцию, лежащую в их основе. При фильтрации изображений это незаменимый инструмент. Классическое применение — корреляция видеопотока для нахождения сдвигов или оптических потоков. Простейший детектор сдвига — тоже в каком-то смысле разностный коррелятор. Там где изображения не коррелируют — было движение.
image image
image

Фильтрации функций

Интересным классом фильтров является фильтрация функций. Это чисто математические фильтры, которые позволяют обнаружить простую математическую функцию на изображении (прямую, параболу, круг). Строится аккумулирующее изображение, в котором для каждой точки исходного изображения отрисовывается множество функций, её порождающих. Наиболее классическим преобразованием является преобразование Хафа для прямых. В этом преобразовании для каждой точки (x;y) отрисовывается множество точек (a;b) прямой y=ax+b, для которых верно равенство. Получаются красивые картинки:
image
(первый плюсег тому, кто первый найдёт подвох в картинке и таком определении и объяснит его, второй плюсег тому, кто первый скажет что тут изображено)
Преобразование Хафа позволяет находить любые параметризуемые функции. Например окружности. Есть модифицированное преобразование, которое позволяет искать любые фигуры. Это преобразование ужасно любят математики. Но вот при обработке изображений, оно, к сожалению, работает далеко не всегда. Очень медленная скорость работы, очень высокая чувствительность к качеству бинаризации. Даже в идеальных ситуациях я предпочитал обходиться другими методами.
Аналогом преобразования Хафа для прямых является преобразование Радона . Оно вычисляется через БПФ, что даёт выигрыш производительности в ситуации, когда точек очень много. К тому же его возможно применять к не бинаризованному изображению.

Фильтрации контуров

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

Чаще всего используется именно Кэнни, который хорошо работает и реализация которого есть в OpenCV (Собель там тоже есть, но он хуже ищёт контуры).
image
image

Прочие фильтры

Сверху приведены фильтры, модификации которых помогают решить 80-90% задач. Но кроме них есть более редкие фильтры, используемые в локальных задачах. Таких фильтров десятки, я не буду приводить их все. Интересными являются итерационные фильтры (например активная модель внешнего вида), а так же риджлет и курвлет преобразования, являющиеся сплавом классической вейвлет фильтрации и анализом в поле радон-преобразования. Бимлет-преобразование красиво работает на границе вейвлет преобразования и логического анализа, позволяя выделить контуры:
image
Но эти преобразования весьма специфичны и заточены под редкие задачи.

Часть 2. Логическая обработка результатов фильтрации


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

Морфология

Переходом от фильтрации к логике, на мой взгляд, являются методы математической морфологии (1, 2 , 3). По сути, это простейшие операции наращивания и эрозии бинарных изображений. Эти методы позволяют убрать шумы из бинарного изображения, увеличив или уменьшив имеющиеся элементы. На базе математической морфологии существуют алгоритмы оконтуривания, но обычно пользуются какими-то гибридными алгоритмами или алгоритмами в связке.
image

Контурный анализ

В разделе по фильтрации уже упоминались алгоритмы получения границ. Полученные границы достаточно просто преобразуются в контуры. Для алгоритма Кэнни это происходит автоматически, для остальных алгоритмов требуется дополнительная бинаризация. Получить контур для бинарного алгоритма можно например алгоритмом жука.
Контур является уникальной характеристикой объекта. Часто это позволяет идентифицировать объект по контуру. Существует мощный математический аппарат, позволяющий это сделать. Аппарат называется контурным анализом (1, 2 ).
image
Если честно, то у меня ни разу ни получилось применить контурный анализ в реальных задачах. Уж слишком идеальные условия требуются. То граница не найдётся, то шумов слишком много. Но, если нужно что-то распознавать в идеальных условиях — то контурный анализ замечательный вариант. Очень быстро работает, красивая математика и понятная логика.

Особые точки

Особые точки это уникальные характеристики объекта, которые позволяют сопоставлять объект сам с собой или с похожими классами объектов. Существует несколько десятков способов позволяющих выделить такие точки. Некоторые способы выделяют особые точки в соседних кадрах, некоторые через большой промежуток времени и при смене освещения, некоторые позволяют найти особые точки, которые остаются таковыми даже при поворотах объекта. Начнём с методов, позволяющих найти особые точки, которые не такие стабильные, зато быстро рассчитываются, а потом пойдём по возрастанию сложности:
Первый класс. Особые точки, являющиеся стабильными на протяжении секунд. Такие точки служат для того, чтобы вести объект между соседними кадрами видео, или для сведения изображения с соседних камер. К таким точкам можно отнести локальные максимумы изображения, углы на изображении (лучший из детекторов, пожалуй, детектор Хариса), точки в которых достигается максимумы дисперсии, определённые градиенты и.т.д.
Второй класс. Особые точки, являющиеся стабильными при смене освещения и небольших движениях объекта. Такие точки служат в первую очередь для обучения и последующей классификации типов объектов. Например, классификатор пешехода или классификатор лица — это продукт системы, построенной именно на таких точках. Некоторые из ранее упомянутых вейвлетов могут являются базой для таких точек. Например, примитивы Хаара, поиск бликов, поиск прочих специфических функций. К таким точкам относятся точки, найденные методом гистограмм направленных градиентов (HOG).
Третий класс. Стабильные точки. Мне известно лишь про два метода, которые дают полную стабильность и про их модификации. Это SURF и SIFT. Они позволяют находить особые точки даже при повороте изображения. Расчёт таких точек осуществляется дольше по сравнению с остальными методами, но достаточно ограниченное время. К сожалению эти методы запатентованы. Хотя, в России патентовать алгоритмы низя, так что для внутреннего рынка пользуйтесь.


Часть 3. Обучение


ретья часть рассказа будет посвящена методам, которые не работают непосредственно с изображением, но которые позволяют принимать решения. В основном это различные методы машинного обучения и принятия решений. Недавно Яндыкс выложил на Хабр курс по этой тематике, там очень хорошая подборка. Вот тут оно есть в текстовой версии. Для серьёзного занятия тематикой настоятельно рекомендую посмотреть именно их. Тут я попробую обозначить несколько основных методов используемых именно в распознавании образов.
В 80% ситуаций суть обучения в задаче распознавания в следующем:
Имеется тестовая выборка, на которой есть несколько классов объектов. Пусть это будет наличие/отсутствие человека на фотографии. Для каждого изображения есть набор признаков, которые были выделены каким-нибудь признаком, будь то Хаар, HOG, SURF или какой-нибудь вейвлет. Алгоритм обучения должен построить такую модель, по которой он сумеет проанализировать новое изображение и принять решение, какой из объектов имеется на изображении.
Как это делается? Каждое из тестовых изображений — это точка в пространстве признаков. Её координаты это вес каждого из признаков на изображении. Пусть нашими признаками будут: «Наличие глаз», «Наличие носа», «Наличие двух рук», «Наличие ушей», и.т.д… Все эти признаки мы выделим существующими у нас детекторами, которые обучены на части тела, похожие на людские. Для человека в таком пространстве будет корректной точка [1;1;1;1;..]. Для обезьяны точка [1;0;1;0...] для лошади [1;0;0;0...]. Классификатор обучается по выборке примеров. Но не на всех фотографиях выделились руки, на других нет глаз, а на третьей у обезьяны из-за ошибки классификатора появился человеческий нос. Обучаемый классификатор человека автоматически разбивает пространство признаков таким образом, чтобы сказать: если первый признак лежит в диапазоне 0.5<x<1, второй 0.7<y<1, и.т.д., тогда это человек.
По существу цель классификатора — отрисовать в пространстве признаков области, характеристические для объектов классификации. Вот так будет выглядеть последовательное приближение к ответу для одного из классификаторов (AdaBoost) в двумерном пространстве:
image image image
image
Существует очень много классификаторов. Каждый из них лучше работает в какой-то своей задачке. Задача подбора классификатора к конкретной задаче это во многом искусство. Вот тут немножко красивых картинок на тему.

Простой случай, одномерное разделение

Разберём на примере самый простой случай классификации, когда пространство признака одномерное, а нам нужно разделить 2 класса. Ситуация встречается чаще, чем может представиться: например, когда нужно отличить два сигнала, или сравнить паттерн с образцом. Пусть у нас есть обучающая выборка. При этом получается изображение, где по оси X будет мера похожести, а по оси Y -количество событий с такой мерой. Когда искомый объект похож на себя — получается левая гауссиана. Когда не похож — правая. Значение X=0.4 разделяет выборки так, что ошибочное решение минимизирует вероятность принятия любого неправильного решения. Именно поиском такого разделителя и является задача классификации.
image
Маленькая ремарка. Далеко не всегда оптимальным будет тот критерий, который минимизирует ошибку. Следующий график — это график реальной системы распознавания по радужной оболочке. Для такой системы критерий выбирается такой, чтобы минимизировать вероятность ложного пропуска постороннего человека на объект. Такая вероятность называется «ошибка первого рода», «вероятность ложной тревоги», «ложное срабатывание». В англоязычной литературе «False Access Rate ».
image

Что делать если измерений больше двух?

Алгоритмов много. Даже очень много. Если хотите подробно узнать про каждый из них читайте курс Воронцова, ссылка на который дана выше, и смотрите лекции Яндыкса. Сказать, какой из алгоритмов лучше для какой задачи часто заранее невозможно. Тут я попробую выделить основные, которые в 90% помогут новичку с первой задачей и реализацию которых на вашем языке программирования вы достоверно найдёте в интернете.
k-means (1, 2, 3 ) — один из самых простых алгоритмов обучения. Конечно, он в основном для кластеризации, но и обучить через него тоже можно. Работает в ситуации, когда группы объектов имеют неплохо разнесённый центр масс и не имеют большого пересечения.
AdaBoost (1, 2, 3) АдаБуста — один из самых распространённых классификаторов. Например каскад Хаара построен именно на нём. Обычно используют когда нужна бинарная классификация, но ничего не мешает обучить на большее количество классов.
SVM (1, 2, 3, 4 ) Один из самых мощных классификаторов, имеющий множество реализаций. В принципе, на задачах обучения, с которыми я сталкивался, он работал аналогично адабусте. Считается достаточно быстрым, но его обучение сложнее, чем у Адабусты и требуется выбор правильного ядра.

Ещё есть нейронные сети и регрессия. Но чтобы кратко их классифицировать и показать, чем они отличаются, нужна статья куда больше, чем эта.
________________________________________________
Надеюсь, у меня получилось сделать беглый обзор используемых методов без погружения в математику и описание. Может, кому-то это поможет. Хотя, конечно, статья неполна и нет ни слова ни о работе со стереоизображениями, ни о МНК с фильтром Калмана, ни об адаптивном байесовом подходе.
Если статья понравится, то попробую сделать вторую часть с подборкой примеров того, как решаются существующие задачки ImageRecognition.

И напоследок


Что почитать?
1) Когда-то мне очень понравилась книга «Цифровая обработка изображений» Б. Яне, которая написана просто и понятно, но в то же время приведена почти вся математика. Хороша для того, чтобы ознакомиться с существующими методами.
2) Классикой жанра является Р Гонсалес, Р. Вудс " Цифровая обработка изображений ". Почему-то она мне далась сложнее, чем первая. Сильно меньше математики, зато больше методов и картинок.
3) «Обработка и анализ изображений в задачах машинного зрения» — написана на базе курса, читаемого на одной из кафедр ФизТеха. Очень много методов и их подробного описания. Но на мой взгляд в книге есть два больших минуса: книга сильно ориентирована на пакет софта, который к ней прилагается, в книге слишком часто описание простого метода превращается в математические дебри, из которых сложно вынести структурную схему метода. Зато авторы сделали удобный сайт, где представлено почти всё содержание — wiki.technicalvision.ru
4) Почему-то мне кажется, что хорошая книжка, которая структурирует и увязывает картину мира, возникающую при занятии Image Recognition и Machine Learning — это «Об интеллекте» Джеффа Хокинса. Прямых методов там нет, но есть много мыслей на подумать, откуда прямые методы обработки изображений происходят. Когда вчитываешься, понимаешь, что методы работы человеческого мозга ты уже видел, но в задачах обработки видео.
Мальцев Антон @ZlodeiBaal
карма
293,7
рейтинг 0,0
Computer Vision, Machine Learning
Самое читаемое Разработка

Комментарии (51)

  • +4
    Приятно читать о CV, мало, кто этим занимается.

    Не хотите опубликовать статью о багах в OpenCV? Я бы дополнил в комментах. Было бы полезно тем, кто только знакомится с либой, а то не ожидаешь вначале, что это возможно)
    • +2
      Я обычно EmguCV пользуюсь, на С++ не удобно всё таки разрабатывать.
      А для тех кто с CV только знакомиться всё же есть шикарный robocraft.ru/page/opencv/, который закрывает 90% того, что нужно для первых 2-3 тестовых проектов.
      • 0
        Только хотел поблагодарить за отличный ресурс, как увидел, что у меня уже открыта одна из страниц с него: в Гугле наткнулся. Но всё равно спасибо: мог и не увидеть, что там целый курс.

        А сам я начал изучать CV с locv.ru, тоже довольно полезный сайт.
    • +2
      О найденных в OpenCV багах вы всегда можете написать тут.
      А для новичков(и не только) владеющих Аглийским есть такие ресурсы: docs.opencv.org, answers.opencv.org.
      • 0
        Я думаю, что речь не о багах как таковых, а об ошибках, которые можно допустить. Например с системой типов в OpenCV бывает на выходе получаешь очень странные артефакты, о которых лучше знать чем их дебажить.
        • 0
          эм… а можно поподробней, какого рода артефакты и когда выплывают?)
          • 0
            Чтобы не звучать голословным и сразу представить пример бага в одном маленьком кусочке кода:

            Код
            #include <cv.h>
            #include <highgui.h>
            using namespace cv;
            using namespace std;
             
            int main(int argc, char const *argv[])
            {
              Mat test = imread("/home/igor/Downloads/Lenna.png", CV_LOAD_IMAGE_GRAYSCALE);
              Mat floatImage(test.size(), CV_32F);
              for (int r = 0; r < floatImage.rows; ++r)
              {
                for (int c = 0; c < floatImage.cols; ++c)
                {
                  floatImage.at<int>(r, c) = test.at<int>(r, c);
                }
              }
              imwrite("test.png", floatImage);
              return 0;
            }


            Ожидаемый результат

            Что получилось то получилось

            И да, я понимаю почему так происходит. Это просто пример, как новичку запустить странный баг в свой год.
            Результат бывает выглядит даже еще более причудливо. Когда, к примеру, картинка сохранятся, но записывается в каждый третий пиксель изображения из-за разницы в размере типов.
            • +1
              Ябы сказал, что это скорей один из способов выстрелить себе в ногу разрабатывая на C++, чем баг библиотеки. Но если у вас есть идеи как это реализовать более красиво, вы можете сделать Pull Request в OpenCV и он будет рассмотрен.
              • 0
                Да как бы претензий нет. Все довольно логично, но это некоторая особенность, о которой стоит знать заранее и тогда это сэкономит просто тьму времени. И я считаю, что лучше, чтобы типы были непривязаны к системе на которой запускается код, а потому и так сделано хорошо :)
                Да и силенок у меня пока маловато, чтобы вот так сразу делать Pull Request в довольно устоявшуюся часть библиотеки.
  • +1
    А тайна того, что изображено на картинке с преобразованием Хафа, будет раскрыта в итоге?

    Я бы предположил, что там пять пар горизонтальных линий. Пары эти равноудалены друг от друга. Но расстояние между линиями в каждой паре понемногу увеличивается сверху вниз. Но меня смущает то, что «ромбы» между яркими точками не черные, и самая нижняя яркая точка. Либо на исходном изображении есть еще что-то, либо я в чем-то неверно понял это преобразование…
    • +1
      Думаю, что там 5 длинных отрезков и один вдвое короче (отрезки выровнены по одному из краёв). Отрезки двойные, с разной толщиной линий (сплошной, толстый+тонкий, два одинаковых...) «Подвох», вероятно, в том, что нарисованы не y=a*x+b, а более логичные x*cos(a)+y*sin(a)=b.
      • +1
        Во второй сверху группе отрезков вообще три… Это какой-то штрих-код. И что-то ещё явно есть. Может быть, какая-нибудь тонкая рамка.
      • +6
        Держите:
        • 0
          Обратное преобразование?
          Ожидал чего-то попроще) Спасибо.
          • 0
            Второй вариант был ещё банальнее: кто-то в инете найдёт картинку поиском, я её не сам делал:)
        • +3
          Не успел :)
          image
        • 0
          Ага, оно:)
      • 0
        Ага, с подвохом правильно угадали. Обычно считают именно x*cos(a)+y*sin(a)=b, так как там критической точки нет. Хотя я иногда и y=a*x+b делал, разбив пространство на два подпространства. Мне было лениво для скорости в очередной раз таблицу синусов-косинусов делать.
        Плюсег кинуть не могу: я вам его уже давным-давно кинул:)
  • 0
    Очень хорошая статья, спасибо.
    А для поиска номеров на автомобилях каким способом лучше пользоваться? Примитивами Хаара?
    Преобразование Хафа, как мне кажется, не очень подходит, т.к. на большом изображении будет много «шумных» линий от очертаний домов, дороги, столбов, машин,…
    • +1
      Иногда для распознавания номеров используют feature detection + какойнибудь классификатор на них обученный(Latent SVM например).
      • 0
        Кстати, а вы случайно не знаете чего-нибудь про Latent SVM почитать? Я знаю, что он есть в OpenCV, но в мануалах про его структуру поверхностно написано, а в инете на его счет как-то мало описаний и неполные они.
        • +1
          Ну там основная идея в том, что процесс обучения у нас итеративный, при осуществлении которого мы фиксируем разные латентные переменные и решаем задачу квадратичного программирования. Вообще я особо не углублялся в его изучение, но насколько я могу судить — этот алгоритм является модификацией алгоритма MI-SVM о котором можно почитать например тут. А по самому Latent SVM можно почитать тут но я не уверен что это источник хороший.
          • 0
            Огромное спасибо!
    • 0
      Там два основных способа. Первый через Хаара, второй через поиск рамки контурным анализом. Зависит от того, есть ли у вас мощный ИК-прожектор в системе, или нет.
      • 0
        ИК-прожектора нет
        • 0
          Тогда лучше всего либо Хааром, либо каким-нибудь другим обученным детектором, как выше BelBES ответил.
  • 0
    Как лучше решать задачу поиска «уголка шахматной доски» (точки, где смыкаются два тёмных и два светлых угла)? Отношение яркостей светлого к тёмному — от 1.5 и выше, причём на шкале яркостей они могут находиться где угодно (от 1% до 100% максимальной яркости картинки). Размер области, где цвета каждого угла однородны — от 10*10 до 100*100 пикселей и больше, в последнем случае границы между светлым и тёмным могут быть сильно размыты. Величина минимального угла (из-за перекоса) — от 30 градусов, он может быть как светлым, так и тёмным. Сейчас я для поиска проверяю окрестности каждой точки по критерию «являются ли они центрально-симметричными и самоподобными, и насколько велик разброс яркостей», но это получается довольно долго. В какую сторону лучше смотреть?
    • 0
      Первый глупый вопрос: а пробовали метод из OpenCV? Он, конечно, работает только когда доска неплохо и равномерно освещена, но работает хорошо. Мы обычно когда ректификации камеры производим — то им пользуемся (даже когде в самом проекте не используем OpenCV вообще).
      Второй вопрос. А классические детекторы углов? (1 2 ) пробовали?
      В принципе, в ситуации, когда мне хорошие углы нужно было искать делал так: проходил изображение детектором границ. Для всех точек, которые были определены как граница строил 2 окружности (10 пикселей и 15 пикселей радиусом) и смотрел что эти окружности пересекали. Если получалось 4 точки на каждой окружности — проверял порождают ли они 2 прямых пересекающихся в центре. Но такой детектор был конкретно заточен под мою задачу.
      • 0
        С окружностями пробовал. Правда, делал наоборот — по окружности считал вероятную границу между чёрным и белым, потом проверял, получается ли 4 «достаточно чёрных» и «достаточно белых» отрезка (с возможными серыми зонами между ними). Если получалось правильное чередование, искал наиболее вероятные точки перехода и соединял прямыми. Не помню, почему забраковал. Кажется, поленился посчитать все точки перехода внутри окружности и аппроксимации прямых по ним, и просто взял точку пересечения прямых. В итоге не хватило точности. А может быть, окружностей было слишком много, и надо было как-то отсеивать те из них, которые давали одинаковый результат — и дошел до критерия, что раскраска окружности должна быть центрально-симметричной.
        С детекторами углов плохо. Насколько я понял, многие из них предполагают, что угол один. А у меня всегда пара симметричных с общей вершиной. Какие-то критерии пробовал, но они давали огромное количество ложных срабатываний на пёстрых областях. С понятием «граница» тоже не лучше: для больших досок переход от чёрного к белому (от уровня 10% до 90%) может занимать 4-5 пикселей. А масштабирование применять дорого. Хотя боюсь, что придётся.
        • 0
          Ещё мысль. Для каждой гипотезы центра x0;y0 считаем интеграл по разности симметричных относительно x0;y0 пикселей для квадрата x0-l;y0-l;x0+l;y0+l. Каждая вершина это центр симметрии, так что такой интеграл должен стремиться к нулю. Главное правильно выбрать l, чтобы оно было меньше размера клетки.
          Но оно будет работать только если доска на плоскости и нет сильного наклона доски по отношению к камере.
          • 0
            Да, на втором этапе это у меня примерно так и делается. И наклон доски здесь нисколько не мешает: проекция прямой это всегда прямая. Хуже, когда точка оказывается в зоне больших угловых искажений (как на краю поля зрения «рыбьего глаза»).
            • 0
              Я не про поворот, а про наклон вперёд назад. Прямые то останутся прямыми, но симметричны будут уже разные точки изображений. Там в окрестности границ должны начаться проблемы.
              • 0
                Я тоже про наклон. Даже если физическое расстояние от центра до точек, изображение которых симметрично относительно изображения центра, будет разным, это не отменяет того, что изображения границ останутся прямыми. И изображение уголка будет выглядеть, как два чёрных и два белых угла. Дальних углов клеток у меня всё равно нет — есть только окрестность одного уголка.
    • 0
      постороить вектора градиентов, по ним опрелить поворот шахмотной доски в изображении, а потом пробежаться вейвлетом Хаара повёрнутый на соответствующий угол?
      • +1
        А зачем поворачивать вейвлеты? О_о картинку не проще повернуть?
        • +2
          ну или так. Просто я обычно работаю с системами реального времени, и повернуть картинку размера фулХД на произвольный угол обычно значительно дольше чем пересчитать фильтр.
          • 0
            Пожалуй вы правы, так оно быстрее будет.
            А если не тайна, что за системы вы разрабатываете?
            • 0
              Ну если точнее то пока не разрабатываю, а только собираюсь. Системы автосопровождения подвижных объектов. При условии что камера тоже находится на подвижном объекте, сопровождаемый объект может быть любой на сложном фоне, время обработки не должно превышать 10 микросекунд и точность зачастую должна быть субпиксельная — задача становится очень нетривиальной. Тут ещё ко всему прочему добавляется анализ движения, предсказание и так далее. Вот и собираю информацию, наработки, экспериментирую)
              • 0
                10 микросекунд на обработку? Это с какой частотой у вас камера снимает?
                • 0
                  Извините, опечатался. Конечно же 10 миллисекунд. Камеры работают от 50Гц до 1кГц, в зависимости от задач. Но в любом случае, чем меньше задержка, тем менее инертная система получается. А это особенно важно при работе на узких углах зрения когда весь кадр меньше одного градуса, а момент двигателей, поворачивающих камеру, увы, не такой большой как хотелось бы.
                  • 0
                    На каком расстоянии, что за объекты? Чувствую схожие проблемы. Что за камера снимает фуллХД с частотой 1 кгц?
                    • 0
                      Увы, не могу разглашать эту информацию(
              • 0
                Ну 10 миллисекунды — это ни оч ем не говорящая цифра без привязки к железу, на котором необходим такой FPS)
                Задача случаем не связанна с сопровождением пешеходов?)
                • 0
                  Железо — один 300-мегагерцовый ДСП, с поддержкой плавающей точки. Обычно без ОС. При необходимости ПЛИС для первичной обработки.

                  Не совсем. Для понимания моя задача больше всего похожа на сопровождение движущихся машин, мотоциклов или просто людей с полицейского вертолёта. По телевизору такие кадры часто показывают))
                  • 0
                    Суровая железка, на таком, при жлении, можно и Tegra K1 обогнать на всяких вычислениях оптического потока)

                    Не смотрели в сторону алгоритмов типа TLD для решения этой задачи?
            • +2
              Что-что, понятно что!
              • 0
                Ахаха, нет, всё намного банальнее) Кстате никогда не стал бы ставить на прицел линукс, всёж там больше подходит операционная система реального времени)
  • +10
    Спасибо вам за статью о IR без сисек. Наконец-то можно будет прочитать, не отвлекаясь.
  • +2
    А недавно распиаренный deep learning применяется сейчас в вашей практике?

    Действительно ли он может заметно улучшить распознавание по вашему мнению?
    • +1
      1) В задаче распознавания дорожных знаков сверточные нейронные сети превзошли человека: статья.
      2) Google использует те же сети для распознавания номеров зданий на Street View.
    • +2
      Я его ни разу не применял. Вообще везде где я участвовал очень странные отношения с нейросетями были. Слишком уж они непредсказуемые. А там где они работали — обычно SVM или AdaBoost их превосходил от пары процентов до десятков.

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