Monday, February 21, 2011

Распознавание образов на Topcoder, мой подход

Topcoder NASA Tournament Lab Marathon Match подошел к концу и ваш покорный слуга, все-таки, принял в нем участие. О чем ничуть не жалею. Напомню, что задача состояла в том, чтобы определить есть ли на данном изображении какое-либо транспортное средство. Изображения представляли собой нарезанные кусочки аэро-фотоснимков, максимального размера 150х150 пикселей. Под транспортным средством авторы могли подразумевать все что угодно, от газонокосилки до фуры. На одной из картинок, как мне кажется, я нашел даже детскую коляску. Иногда на фотографии торчал лишь кусочек капота автомобиля. Кроме того, качество изображения оставляло желать лучшего, далеко не всегда даже человек мог определить, есть ли на этом изображении транспортное средство или нет. Например тут, я до сих пор не уверен, что это


Но, несмотря на все эти проблемы в методологии, задача получилась интересная.

Итак, мой подход… Сразу отмечу, что в computer vision я полный нуб, так что будет интересно услышать, критический взгляд опытных коллег.

Мой подход состоял в том, чтобы разбить изображение на несколько регионов. Далее, каждый из этих регионов передавался на вход первой нейронной сети. Задачей этой нейронной сети было определить, к какому классу объектов относится данный регион. Я выделил около десятка классов объектов: крыши, капоты и стекла автомобилей, тени, трава, земля, камни, трубы, дороги, дорожные линии и конечно неопределенный класс, к которому приписывались все остальные объекты. Дальше результат распознания самых больших 10 регионов подавался на вход второй нейронной сети, которая принимала окончательное решение: транспорт или не транспорт.

Для разбиения на регионы, я воспользовался слегка модифицированным алгоритмом детектирования границ Canny edge detector. Классическая версия этого алгоритма работает с монохромными изображениями. Можно было бы просто преобразовать нашу картинку в черно-белый вариант, но терять цветовую составляющую при столь грязных входных данных мне показалось непозволительной роскошью. Поэтому я модифицировал алгоритм для работы с цветом. В следующих статьях, обязательно расскажу, как это происходило. Кроме того, прежде чем детектировать границы, я провел балансировку изображения по каждому из цветовых составляющих RGB.

После разбиения картинки на регионы, для каждого региона определялись его размер в пикселях, геометрический размер (длинна и толщина), средний цвет, и крайние цвета. О цветах расскажу поподробнее, использовать пространство цветов RGB мне показалось неразумным (может зря?) поэтому все цвета были преобразованы в пространство L*a*b* и в дальнейшем работа велась исключительно с компонентами L, a и b. Под крайними цветами я подразумеваю значение соответствующей компоненты L, a или b на расстоянии 80% от центра для данного региона. Таким образом на вход первой нейронной сети подавалось 12 параметров.

Кроме нейронной сети я пробовал использовать другие классификаторы на данном этапе SVM, Naive Bayes, Decision Tree, но ни для одного из них я не обнаружил сколь-нибудь значительного преимущества в распознании. В итоге нейронная сеть состояла из двух скрытых слоев и корректно классифицировала около 50% регионов.

На следующем этапе, результаты классификации регионов передавались на вход второй нейронной сети. Которая, в свою очередь, принимала решение, является ли данное изображение транспортным средством или нет. Эта нейронная сеть, так же как и предыдущая, состояла из двух скрытых слоев и в сумме с первой давала 85% точность при классификации. Эти результаты были получены на случайной выборке состоящей из 10% исходных данных, данные в этой выборке не участвовали в тренировке нейронной сети.
Когда полный цикл работы алгоритма был построен, требовалось создать большое количество маркированных данных для первой сети. Времени на это методичное занятие у меня, естественно, не было. Поэтому я маркировал регионы только на тех картинках, которые были неправильно классифицированы. Этот подход не совсем честен, но за неимением времени, мне он показался оптимальным. Для того чтобы маркировать данные вручную не было слишком скучно, было написано небольшое приложение:


Слева отображалась оригинальная картинка, справа границы, которые мне удалось обнаружить, с подсвеченным регионом, которые рассматривается в данный момент. А в центре, сбалансированная картинка с отмеченным регионом.

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

UPD: И по последнем данным, я занял 10-ое место, что в общем-то неплохо учитывая полное отсутствие опыта в этой области. Результаты еще могут слегка подвинуться, поскольку идет пересмотр изображений, но, едва ли, изменятся принципиально.

1 comment:

  1. круто! 10е место с нуля - это впечатляет, computer vision не самая простая тема =)

    ReplyDelete