Одним из самых интересных проектов, над которым я работал за последние пару лет, был проект по обработке изображений . Цель состояла в том, чтобы разработать систему, позволяющую распознавать «банки» от Coca-Cola (обратите внимание, что я подчеркиваю слово «банки», через минуту вы поймете, почему). Ниже вы можете увидеть образец банки, распознанной в зеленом прямоугольнике с указанием масштаба и поворота.

Template matching

Некоторые ограничения по проекту:

  • Фон мог быть очень шумным.
  • банка может иметь любой масштаб , поворот или даже ориентацию (в разумных пределах).
  • Изображение может иметь некоторую нечеткость (контуры могут быть не совсем прямыми).
  • На изображении могут быть бутылки с кока-колой, и алгоритм должен обнаруживать только банку !
  • Яркость изображения может сильно различаться (поэтому вы не можете слишком полагаться на определение цвета).
  • банка может быть частично спрятана по бокам или в середине и, возможно, частично спрятана за бутылкой.
  • На изображении не могло быть никакого банки , и в этом случае вам нужно было ничего не найти и написать сообщение об этом.

Таким образом, вы можете получить такие хитрые вещи (в этом случае мой алгоритм полностью потерпел неудачу):

Total fail

Я работал над этим проектом некоторое время назад, мне было очень весело, и я получил достойную реализацию. Вот некоторые подробности о моей реализации:

Язык : выполнено на C ++ с использованием библиотеки OpenCV.

Предварительная обработка : для предварительной обработки изображения, т. е. преобразования изображения в более необработанную форму для придания алгоритму, я использовал 2 метода:

  1. Изменение цветовой области с RGB на HSV и фильтрация на основе «красного» оттенка, насыщенность выше определенного порога чтобы избежать оранжевых цветов, и фильтрацию низкого значения, чтобы избежать темных тонов. Конечным результатом было двоичное черно-белое изображение, где все белые пиксели представляли пиксели, соответствующие этому порогу. Очевидно, что в изображении все еще много мусора, но это уменьшает количество измерений, с которыми вам нужно работать. Бинаризованное изображение
  2. Фильтрация шума с использованием медианной фильтрации (взятие среднего значения пикселя для всех соседей и замена пикселя на это значение) для уменьшения шума.
  3. Использование Canny Edge Detection Filter для получения контуров всех элементов после 2 предшествующих шагов. Обнаружение контура

Алгоритм . Сам алгоритм, который я выбрал для этой задачи, был взят из этого замечательная книга по извлечению признаков, которая называется Generalized Hough Transform (сильно отличается от обычного Hough Преобразовать). В основном это говорит о нескольких вещах:

  • Вы можете описать объект в космосе, не зная его аналитического уравнения (как здесь).
  • Он устойчив к деформациям изображения, таким как масштабирование и вращение, так как в основном проверяет ваше изображение на каждую комбинацию коэффициента масштабирования и коэффициента поворота.
  • Он использует базовую модель (шаблон), которую алгоритм будет «изучать».
  • Каждый пиксель, оставшийся в контурном изображении, будет голосовать за другой пиксель, который предположительно будет центром (с точки зрения силы тяжести) вашего объекта, в зависимости от того, что он узнал из модели.

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

GHT

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

Результаты . Хотя этот подход работал в основных случаях, в некоторых областях его сильно не хватало:

  • Это очень медленно ! Я недостаточно это подчеркиваю. На обработку 30 тестовых изображений потребовался почти полный день, очевидно, потому что у меня был очень высокий коэффициент масштабирования для вращения и перевода, поскольку некоторые банки были очень маленькими.
  • Он был полностью утерян, когда на изображении были бутылки, и по какой-то причине почти всегда обнаруживалась бутылка вместо банки (возможно, потому, что бутылки были больше, поэтому в них было больше пикселей, а значит, больше голосов).
  • Нечеткие изображения также не годились, поскольку голоса заканчивались пикселями в случайных местах вокруг центра, что приводило к очень шумной тепловой карте.
  • Достигнута инверсия в поступлении и вращении, но не в ориентации, а это означает, что банка, не обращенная непосредственно к объективу камеры, не распознается.

Можете ли вы помочь мне улучшить мой конкретный алгоритм, используя исключительно функции OpenCV , для решения упомянутых четырех конкретных проблем?

Я надеюсь, что некоторые люди тоже извлекут уроки из этого, в конце концов, я думаю, что не только люди, которые задают вопросы, должны учиться. :)

1788
Charles Menguy 16 Апр 2012 в 08:23

14 ответов

Лучший ответ

Альтернативным подходом было бы извлечение функций (ключевых точек) с помощью масштабно-инвариантного преобразования функций ( SIFT) или Ускоренные надежные функции (SURF).

Вы можете найти хороший пример кода OpenCV в Java, C++ и Python на этой странице: Features2D + Homography для поиска известного объекта

Оба алгоритма инвариантны к масштабированию и вращению. Поскольку они работают с функциями, вы также можете справиться с окклюзией (пока видно достаточно ключевых точек).

Enter image description here

Источник изображения: пример учебника

Для SIFT обработка занимает несколько сотен мс, SURF немного быстрее, но не подходит для приложений реального времени. ORB использует FAST, более слабый в отношении инвариантности вращения.

Оригинальные документы

717
Nicolas Gervais 25 Сен 2020 в 17:07

Первое, что я хотел бы искать, это цвет - например, КРАСНЫЙ, при обнаружении красных глаз на изображении - есть определенный цветовой диапазон, который нужно обнаружить, некоторые характеристики, касающиеся окружающей области, и такие как расстояние от другого глаза, если он действительно видно на изображении.

1: Первая характеристика - цвет, и красный цвет преобладает. После обнаружения Coca Cola Red возникает несколько вопросов, представляющих интерес 1A: Насколько велика эта красная область (достаточно ли ее количества для определения истинной банки или нет - 10 пикселей, вероятно, недостаточно), 1B: Содержит ли она цвет Этикетки - «Кока-Кола» или волна. 1B1: Достаточно ли этого, чтобы учесть высокую вероятность того, что это ярлык.

Пункт 1 - это своего рода короткий путь - предварительная обработка, если на изображении присутствуют эти ланиные сопли - двигайтесь дальше.

Так что, если это так, я могу затем использовать этот сегмент моего изображения и начать немного увеличивать масштаб рассматриваемой области - в основном смотрю на окружающую область / края ...

2: Учитывая вышеупомянутый идентификатор области изображения, установленный в 1 - проверьте окружающие точки [края] рассматриваемого элемента. A: Есть ли что-то вроде верха или низа банки - серебро? B: Бутылка может казаться прозрачной, но также может показаться стеклянный стол - также есть стеклянный стол / полка или прозрачная область - если это так, существует несколько возможных выходов. У бутылки МОЖЕТ быть красный колпачок, а может и нет, но он должен иметь форму крышки бутылки / винта с резьбой или колпачка. C: Даже если это не удается, A и B, это все равно может быть частичное ... Это более сложно, когда оно частичное, потому что частичная бутылка / частичный может выглядеть так же, поэтому еще немного обработки измерения края красной области до края .. маленькая бутылка может быть похожей по размеру ..

3: После проведенного выше анализа я бы посмотрел на буквы и логотип с волнами - потому что я могу ориентировать свой поиск на некоторые буквы в словах, поскольку у вас может не быть всего текста из-за того, что у вас нет всех может, волна выровнялась бы в определенных точках относительно текста (на расстоянии), чтобы я мог искать эту вероятность и знать, какие буквы должны существовать в этой точке волны на расстоянии x.

1
Ken 4 Сен 2017 в 11:40

Если вы заинтересованы в том, чтобы это происходило в реальном времени, вам нужно добавить фильтр предварительной обработки, чтобы определить, что сканируется с помощью сверхмощных материалов. Хороший быстрый фильтр предварительной обработки в режиме реального времени, который позволит вам сканировать вещи, которые, скорее всего, являются банкой кока-колы, прежде чем переходить к более сомнительным вещам, выглядит примерно так: найдите изображение на предмет самых больших пятен. цвета, который отличается определенным допуском от sqrt(pow(red,2) + pow(blue,2) + pow(green,2)) вашей банки кока-колы. Начните с очень строгих допусков по цвету и постепенно переходите к более мягким допускам по цвету. Затем, когда у вашего робота заканчивается отведенное время для обработки текущего кадра, он использует найденные в данный момент бутылки для ваших целей. Обратите внимание, что вам нужно будет настроить цвета RGB в sqrt(pow(red,2) + pow(blue,2) + pow(green,2)), чтобы получить их правильно.

Кроме того, это может показаться действительно глупым, но вы обязательно включили оптимизацию компилятора -oFast при компиляции кода C?

1
user7892745user7892745 12 Май 2017 в 22:07

Может быть, уже на много лет позже, но все же теория, которую стоит попробовать.

Отношение ограничивающего прямоугольника области красного логотипа к общему размеру бутылки / банки другое. В случае банки должно быть 1: 1, тогда как в случае бутылки (с крышкой или без нее) будет иным. Это должно облегчить различие между ними.

Обновление: горизонтальная кривизна области логотипа будет отличаться между банкой и бутылкой из-за разницы в размерах. Это может быть особенно полезно, если вашему роботу нужно подобрать банку / бутылку, и вы соответственно выбираете захват.

2
banerjk 5 Фев 2018 в 19:33

Существует пакет компьютерного зрения под названием HALCON от MVTec, демонстрации которого могут дать вам хорошие идеи для алгоритмов. Существует множество примеров, похожих на вашу проблему, которые вы могли бы запустить в демонстрационном режиме, а затем посмотреть на операторы в коде и увидеть, как их реализовать из существующих операторов OpenCV.

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

5
Darien Pardinas 9 Апр 2014 в 23:40

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

Это может быть полезно для извлечения только консервных банок и может сочетаться с обнаружением прозрачных объектов.

7
madduci 5 Дек 2014 в 08:20

Вам нужна программа, которая учится и повышает точность классификации на собственном опыте.

Я предлагаю глубокое обучение, с глубоким обучением это становится тривиальной проблемой.

Вы можете переобучить начальную модель v3 на Tensorflow:

Как перенастроить последний слой Inception для новых категорий.

В этом случае вы будете обучать сверточную нейронную сеть классифицировать объект как может или нет кока-кола.

11
sg7 18 Мар 2018 в 01:01

Существует множество цветовых дескрипторов, используемых для распознавания объектов, в статье ниже приводится сравнение многих из них. Они особенно эффективны в сочетании с SIFT или SURF. Сами по себе SURF или SIFT не очень полезны в изображении кока-колы, потому что они не распознают много интересных точек, вам нужна информация о цвете, чтобы помочь. Я использую BIC (классификацию пограничных / внутренних пикселей) с SURF в проекте, и он отлично справлялся с распознаванием объектов.

Цветовые дескрипторы для поиска изображений в Интернете: сравнительное исследование

11
Guilherme Defreitas 3 Янв 2013 в 15:26

Глубокое обучение

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

Если вы не собираете очень большой набор данных, попробуйте использовать функции глубокого обучения для небольшого набора данных. В идеале использовать комбинацию машин опорных векторов (SVM) с глубокими нейронными сетями.

После того, как вы загрузите изображения в ранее обученную модель глубокого обучения (например, GoogleNet), вместо использования (финального) слоя принятия решений нейронной сети для выполнения классификаций используйте данные предыдущих слоев в качестве функций для обучения классификатора.

OpenCV и Google Net: http://docs.opencv.org/trunk/d5/de7/tutorial_dnn_googlenet.html

OpenCV и SVM: http://docs.opencv.org/2.4/doc/tutorials /ml/introduction_to_svm/introduction_to_svm.html

12
Community 20 Июн 2020 в 09:12

Мне нравится ваш вопрос, вне зависимости от того, не по теме он или нет: P

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

Нам пришлось разработать робота, который использовал бы Xbox Kinect для обнаружения бутылок и банок из-под кокса при любой ориентации, при различных условиях освещения и окружающей среды. Наше решение включало использование полосового фильтра на канале Hue в сочетании с преобразованием круга Хаффа. Мы смогли немного ограничить среду (мы могли выбрать, где и как расположить робота и сенсор Kinect), в противном случае мы собирались использовать преобразования SIFT или SURF.

Вы можете прочитать о нашем подходе в моем сообщении в блоге по этой теме :)

12
aaronsnoswell 4 Янв 2013 в 06:10

Я опаздываю на несколько лет с ответом на этот вопрос. В связи с тем, что за последние 5 лет CNN довели до предела современные возможности, я бы не стал использовать OpenCV для выполнения этой задачи сейчас! ( Я знаю, что вы конкретно хотели использовать функции OpenCv в вопросе ). Я считаю, что алгоритмы обнаружения объектов, такие как Faster-RCNN, YOLO, SSD и т. д., решат эту проблему со значительным запасом по сравнению с функциями OpenCV. Если бы я решил эту проблему сейчас (через 6 лет !!), я бы определенно использовал Faster-RCNN .

16
Abhijit Balaji 16 Мар 2018 в 04:18

Не сложно ли даже человеку отличить бутылку от банки на втором изображении (при условии, что прозрачная область бутылки скрыта)?

Они почти такие же, за исключением очень маленькой области (то есть ширина в верхней части банки немного мала, а обертка бутылки одинакова по всей ширине, но небольшое изменение, верно?)

Первое, что пришло мне в голову, это проверить красную крышку бутылки. Но это все равно проблема, если у бутылки нет крышки или она частично спрятана (как упоминалось выше).

Второе, о чем я подумал, было о прозрачности бутылки. OpenCV имеет некоторые работы по поиску прозрачных объектов на изображении. Проверьте ссылки ниже.

В частности, посмотрите, насколько точно они обнаруживают стекло:

Смотрите результат их реализации:

Enter image description here

Они говорят, что это реализация бумажной "Основы геодезического активного контура" в поисках стекла »К. МакГенри и Дж. Понсе, CVPR 2006.

Это может быть немного полезно в вашем случае, но проблема возникает снова, если бутылка заполнена.

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

Enter image description here

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

В любом случае, это решение также имеет другие проблемы, как и другие решения.

  1. Это работает, только если ваша бутылка пуста. В этом случае вам придется искать красную область между двумя черными цветами (если жидкость Coca Cola черная).
  2. Еще одна проблема, если прикрыта прозрачная часть.

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

141
Wilfred Hughes 20 Май 2019 в 15:12

Забавная проблема: когда я взглянул на изображение вашей бутылки, я подумал, что это тоже банка. Но, как человек, я заметил разницу в том, что потом заметил, что это тоже бутылка ...

Итак, чтобы отличить банки от бутылок, как насчет того, чтобы сначала просто сканировать бутылки? Если вы его найдете, закройте этикетку, прежде чем искать банки.

Не так уж сложно реализовать, если вы уже занимаетесь консервными банками. Реальный недостаток - это удвоение времени обработки. (Но если подумать о реальных приложениях, вы все равно захотите делать бутылки ;-)

173
Darren Cook 16 Апр 2012 в 05:03

Чтобы ускорить процесс, я бы воспользовался тем фактом, что вас просят найти не произвольное изображение / объект, а, в частности, изображение с логотипом Coca-Cola. Это важно, потому что этот логотип очень отличительный, и он должен иметь характерную масштабно-инвариантную подпись в частотной области, особенно в красном канале RGB. Другими словами, чередующийся узор красного к белому и красному, встречаемый горизонтальной линией сканирования (обученной на горизонтально выровненном логотипе), будет иметь характерный «ритм», когда он проходит через центральную ось логотипа. Этот ритм будет «ускоряться» или «замедляться» в разных масштабах и ориентациях, но останется пропорционально эквивалентным. Вы можете идентифицировать / определить несколько десятков таких строк развертки, как по горизонтали, так и по вертикали через логотип, и еще несколько по диагонали в виде звездообразования. Назовите их «линиями сканирования подписи».

Signature scan line

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

Я был бы удивлен, если бы это был не линейно эффективный алгоритм или почти такой. Очевидно, это не касается вашей дискриминации из-за консервных банок, но, по крайней мере, у вас будут свои логотипы.

(Обновление: для распознавания бутылки я бы поискал кокс (коричневую жидкость) рядом с логотипом, то есть внутри бутылки. Или, в случае пустой бутылки, я бы поискал колпачок , который всегда будет иметь одинаковую базовую форму, размер и расстояние от логотипа и, как правило, будет полностью белым или красным. Найдите однотонную эллиптическую форму там, где должна быть крышка относительно логотипа. Конечно, это не надежно, но ваша цель здесь должна заключаться в том, чтобы найти простые быстрые .)

(Прошло несколько лет с тех пор, как я начал обрабатывать изображения, поэтому я сохранил это предложение на высоком уровне и концептуально. Я думаю, что оно может немного приблизиться к тому, как может работать человеческий глаз - или, по крайней мере, как работает мой мозг!)

410
Peter Mortensen 19 Май 2012 в 20:46