Обработка изображений: Улучшение алгоритма для распознавания Coca-Cola Can


1659

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

Соответствие шаблона

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

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

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

Полный провал

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

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

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

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

Алгоритм : сам алгоритм, который я выбрал для этой задачи, был взят из этой удивительной книги по извлечению признаков и называется Обобщенным преобразованием Хафа (довольно сильно отличается от обычного преобразования Хафа). Это в основном говорит о нескольких вещах:

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

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

GHT

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

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

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

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

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


45
Можно было бы сказать, что этот вопрос более уместен на dsp.stackexchange.com или stats.stackexchange.com, и вам, безусловно, следует рассмотреть возможность повторного запроса и на этих сайтах.
Ely

49
Первое, что нужно сделать здесь, это проанализировать, почему происходят разные случаи сбоев. Например, выделите примеры мест, где выигрывают бутылки, где изображения нечеткие и т. Д., И проведите некоторый статистический анализ, чтобы узнать разницу между их представлениями Хафа и теми, которые вы хотели бы обнаружить. Здесь и здесь
есть

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

9
Как насчет подхода, похожего на reCAPTCHA ? ;)
Джордж Дакетт

39
Почему это было перенесено с dsp.stackexchange.com ? Кажется, что этот сайт будет даже лучше, чем stackoverflow o_O
BlueRaja - Дэнни Пфлугхофт

Ответы:


672

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

Это реализовано в OpenCV 2.3.1.

Вы можете найти хороший пример кода, используя функции в Features2D + Homography, чтобы найти известный объект

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

Введите описание изображения здесь

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

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

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


6
Я согласен с @stacker - SIFT - отличный выбор. Это очень устойчиво к операциям масштабирования и вращения. Это несколько устойчиво к деформации перспективы (это может быть улучшено в соответствии с предложением Stacker: база данных шаблонов с различными видами перспективы нужного объекта). Его ахиллесовой пятой в моем опыте были бы сильные изменения освещения и очень дорогие вычисления. Я не знаю ни одной реализации Java. Мне известна реализация OpenCV, и я использовал реализацию GPU c ++ / Windows ( SiftGPU ), подходящую для производительности в реальном времени.

31
Предупреждение: насколько я люблю SIFT / SURF и то, что они сделали со мной, они обременены патентами. Это может быть проблемой, в зависимости от ряда условий, включая географическое положение AFAIK.
Agos

12
Так что попробуйте OpenCV ORB или FREAK, у которых нет проблем с патентами. ORB намного быстрее, чем SIFT. ORB немного беден масштабами и легкими вариациями в моем опыте, но проверьте это сами.
Руи Маркиз

66
Как вы можете принять это как ответ ... Ни один из дескрипторов функций не может отличить бутылки от банок. Все они просто видят инвариантные локальные дескрипторы образца. Я согласен с тем, что SIFT, SURF, ORB, FREAK и т. Д. Могут помочь вам в подборе функций, но ... Как насчет других ваших частей вопроса, таких как окклюзия, бутылка против банок и т. Д. Я надеюсь, что это не является полным решением, если бы Ударил вашу проблему, вероятно, первым результатом будет только этот ответ.
G453

11
@ G453 ты абсолютно прав! Вероятно, он был очарован работой SHIFT и забыл, что извлечение и сопоставление функций НЕ было
проблемой

383

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

Линия сканирования подписи

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

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

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

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


24
Это отличное предложение, мне особенно нравится тот факт, что этот алгоритм должен быть довольно быстрым, даже если он, вероятно, будет содержать много ложных негативов. Одна из моих скрытых целей - использовать это обнаружение в режиме реального времени для робототехники, так что это может быть хорошим компромиссом!
Чарльз Менгю

42
Да, часто забывают (в области, характеризующейся точностью), что алгоритмы аппроксимации необходимы для большинства задач моделирования в реальном времени. (Я основал свой тезис на этой концепции.) Сохраните ваши алгоритмы, требующие много времени, для ограниченных регионов (чтобы исключить ложные срабатывания). И помните: в робототехнике вы обычно не ограничены одним изображением. Предполагая, что мобильный робот, быстрый алгоритм может искать десятки изображений с разных ракурсов за меньшее время, чем сложные алгоритмы тратят на одно, значительно уменьшая количество ложных негативов.
kmote

29
Мне нравится идея использовать то, что составляет сканер штрих-кода для чрезвычайно быстрого обнаружения логотипов Coca-Cola. +1!
Ли-Аунг Ип

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

34
@karlphillip: если вы скрываете подпись, то есть логотип, то любой метод, основанный на поиске логотипа, потерпит неудачу.
Ли-Аунг Ип

162

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

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

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


5
Да, я тоже думал об этом, но у меня не было много времени, чтобы сделать это. Как бы вы узнали бутылку, поскольку ее основная часть будет выглядеть как чешуйчатая банка? Я тоже подумывал о том, чтобы найти красную пробку и посмотреть, совпадает ли она с бутылочным центром, но это не очень надежно.
Чарльз Менгю

42
Если параллельно «кока-коле» есть красная крышка (или кольцо), то, скорее всего, это бутылка.
Лукаш Мадон

@linker Как вы тренировали свой алгоритм для банок? У вас были примеры банок? Как насчет тренировки с примерами бутылок?
Сиами

1
Сила этого алгоритма в том, что вам нужен только один шаблон для обучения, а затем он применяет все преобразования, чтобы сопоставить его с другими потенциальными банками. Я использовал бинаризованную и контурную версию этого шаблона для тренировки, поэтому единственной разницей между банкой и бутылкой была бы пробка, но я боюсь, что это принесет больше ложных срабатываний, поскольку центр тяжести будет где-то на краю или вне бутылки. Думаю, стоит попробовать. Но это удвоит мое время обработки, и я заплачу;)
Чарльз Менгуй

7
По сути это разумное направление. Я бы сформулировал это немного по-другому: сначала найдите всех кандидатов, а затем для каждого кандидата определите, является ли это бутылкой, банкой или чем-то еще.
MSalters

131

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

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

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

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

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

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

Введите описание изображения здесь

Говорят, что это реализация статьи «Геодезическая структура активного контура для поиска стекла» К. МакГенри и Дж. Понсе, CVPR 2006 .

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

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

Введите описание изображения здесь

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

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

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

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


+1 Я думал об этом и был на моем пути для реализации этого подхода. Тем не менее, @linker должен поделиться своим набором изображений, чтобы мы могли попытаться сделать более образованные догадки.
karlphillip

да .. я тоже думаю, что было бы хорошо, если бы было больше изображений.
Абид Рахман К

Учитывая, что у нас есть только этикетки для бутылок / банок и нет других отличительных факторов для крышки бутылки или прозрачности или банки сверху / снизу - ширина бутылки отличается от ширины банки.
Кен

Что делать, если перед логотипом бутылки находится банка?
AlgoRythm

51

Мне очень нравятся ответы Даррена Кука и укладчика на эту проблему. Я был в состоянии бросить свои мысли в комментарии к ним, но я считаю, что мой подход слишком сформирован, чтобы не уходить отсюда.

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

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

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

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

  • Правильна ли форма силуэта объекта, как вы набросали в своем вопросе ? Если так, +1.
  • Если мы предполагаем наличие естественного или искусственного света, обнаруживаем ли мы хромированный контур бутылки, который указывает на то, сделан ли он из алюминия? Если так, +1.
  • Определяем ли мы, что зеркальные свойства объекта являются правильными по отношению к нашим источникам света ( иллюстративная видеосвязь по обнаружению источника света )? Если так, +1.
  • Можем ли мы определить какие-либо другие свойства объекта, которые идентифицируют его как консервную банку, включая, но не ограничиваясь этим, перекос логотипа топологического изображения, ориентацию объекта, сопоставление объекта (например, на плоской поверхности как таблица или в контексте других банок), а наличие вкладки? Если так, для каждого +1.

Ваша классификация может выглядеть следующим образом:

  • Для каждого совпадения кандидатов, если обнаружен логотип Coca Cola, нарисуйте серую рамку.
  • Для каждого совпадения более +2 нарисуйте красную рамку.

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

Обнаружение каждого свойства несет в себе очень разную временную и пространственную сложность, и для каждого подхода быстрый переход по адресу http://dsp.stackexchange.com более чем оправдан для определения наиболее правильного и наиболее эффективного алгоритма для ваших целей. Моя цель здесь состоит в том, чтобы просто и просто подчеркнуть, что обнаружение, если что-то может, путем аннулирования небольшой части пространства обнаружения кандидата , не является самым надежным или эффективным решением этой проблемы, и в идеале вы должны предпринять соответствующие действия. соответственно.

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


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

Это своего рода то, о чем я думал: не исключайте конкретные виды ложных срабатываний. Правило в том, что делает колу. Но мне интересно: что ты делаешь со сплющенной банкой? Я имею в виду, если вы наступите на колу, это все равно будет кола. Но он больше не будет иметь такую ​​же форму. Или это проблема AI-Complete?
Ян

41

Смотреть на форму

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

Глядя на основные моменты

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

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


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

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

Я вижу, какой тип представления цветового пространства вы бы использовали в этом случае для отражения зеркальности в вашем алгоритме? Это кажется довольно трудным, чтобы войти в RGB или HSV
Чарльз Менгуй

3
Что, если источник света был позади банки? Я думаю, что вы не увидите основной момент.
Руи Маркес

37

Пожалуйста, взгляните на трекер Хищника Зденека Калала . Требуется некоторое обучение, но он может активно изучать, как отслеживаемый объект выглядит в разных ориентациях и масштабах, и делает это в режиме реального времени!

Исходный код доступен на его сайте. Это в MATLAB , но, возможно, есть реализация Java, уже сделанная членом сообщества. Я успешно повторно внедрил часть трекера TLD в C #. Если я правильно помню, TLD использует Папоротники в качестве детектора ключевых точек. Вместо этого я использую SURF или SIFT (уже предложенный @stacker) для повторного получения объекта, если он был потерян трекером. Обратная связь с трекером позволяет легко со временем построить динамический список шаблонов просеивания / сёрфинга, которые со временем позволяют повторно захватывать объект с очень высокой точностью.

Если вы заинтересованы в моей реализации C # трекера, не стесняйтесь спрашивать.


Спасибо за ссылку, которая выглядит интересно. Что касается обучения, какой размер тренировочного набора будет разумным для достижения разумных результатов? Если у вас есть реализация даже в c #, это было бы очень полезно!
Чарльз Менгю

Исследуя TLD, я обнаружил, что другой пользователь ищет реализацию C # - есть ли причина не размещать вашу работу на Github? stackoverflow.com/questions/29436719/…
spillner

2
NB Лет, позже, ссылка сейчас мертва
Дж Эванс

33

Если вы не ограничены только камерой, которая не входила ни в одно из ваших ограничений, возможно, вы можете перейти к использованию датчика диапазона, такого как Xbox Kinect . При этом вы можете выполнить глубину и цветовую согласованную сегментацию изображения. Это позволяет быстрее разделять объекты на изображении. Затем вы можете использовать сопоставление ICP или аналогичные методы, чтобы даже сопоставить форму банки, а не только ее контур или цвет, и учитывая, что она является цилиндрической, это может быть допустимым вариантом для любой ориентации, если у вас есть предыдущее 3D-сканирование цели. Эти методы часто бывают довольно быстрыми, особенно когда они используются для такой конкретной цели, которая должна решить вашу проблему со скоростью.

Также я мог бы предложить, не обязательно для точности или скорости, но для забавы вы могли бы использовать обученную нейронную сеть на вашем сегментированном изображении оттенка, чтобы идентифицировать форму банки. Это очень быстро и часто может быть до 80/90% точности. Обучение было бы немного долгим процессом, так как вы должны были бы вручную идентифицировать банку на каждом изображении.


3
На самом деле я не объяснил это в посте, но для этого задания мне дали набор из примерно 30 изображений, и мне пришлось создать алгоритм, который бы соответствовал им всем в различных ситуациях, как описано. Конечно, некоторые изображения были проведены для проверки алгоритма в конце. Но мне нравится идея датчиков Kinect, и я хотел бы прочитать больше на эту тему!
Чарльз Менгю

Каков примерно размер тренировочного набора с нейронной сетью, чтобы иметь удовлетворительные результаты? Что хорошо в этом методе, так это то, что мне нужен только один шаблон, чтобы соответствовать почти всем.
Чарльз Менгю

2
Если ваш набор изображений предопределен и ограничен, просто хардкорные идеальные результаты в вашей проге;)
sne11ius

Да, если я буду тренироваться на наборе данных, с которым я собираюсь запустить алгоритм, я уверен, что получу отличные результаты :) Но, например, для этого задания, учитель в конце протестировал программу на наборе выдвинутых изображений , Я хотел бы сделать что-то, что было бы надежным и не соответствовало бы тренировочным данным.
Чарльз Менгю

Количество тренировочных наборов варьируется, но вы должны быть осторожны в нескольких вещах: не перетренируйтесь, вы, вероятно, хотите, чтобы тестовый набор показал вашу точность. Также количество тренировочных наборов будет зависеть от количества слоев, которые вы будете использовать.
Фантастический мистер Фокс

24

Я бы обнаружил красные прямоугольники: RGB -> HSV, красный фильтр -> двоичное изображение, закрыть (расширить, затем разрушить, известный какimclose в Matlab)

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

Это оставит вас с красными прямоугольниками, а затем вам нужно будет как-то обнаружить логотипы, чтобы сказать, являются ли они красным прямоугольником или банкой кокса. Нравится OCR, но с известным логотипом?


2
Как это обсуждалось на DSP за короткое время, когда он был перемещен, некоторые бутылки могут не иметь пробок;) или пробка может быть частично скрыта.
Чарльз Менгю

22

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


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

Я также проверил, что отношение ширины к высоте очень похоже на бутылку и может, так что это тоже не вариант.
Чарльз Менгю

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

3
Чтобы объяснить немного больше. Предположим, что банка находится при z = 0, а бутылка при z = -100. Поскольку бутылка далеко позади, она будет выглядеть меньше. Но если я знаю, что бутылка находится при z = -100 и может при z = 0, тогда я могу рассчитать ожидаемый размер банки / бутылки, если оба значения будут переведены в z = 0. Так что теперь они на одной глубине, и, следовательно, я могу принимать решения в зависимости от размера.
Шарад

2
Это всего лишь комментарий, а не ответ, но он намного ближе к тому, чтобы быть ответом, чем приведенный выше комментарий с ответом со 120 голосами.
Толстяк

22

Хм, я на самом деле думаю, что я на что-то (это как самый интересный вопрос когда-либо - поэтому было бы стыдно не продолжать пытаться найти "идеальный" ответ, хотя приемлемый был найден) .. ,

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

Что это вокруг логотипа? Для банки можно увидеть металл, который, несмотря на воздействие света, не меняет своего основного цвета. Пока мы знаем угол метки, мы можем сказать, что находится прямо над ним, поэтому мы смотрим на разницу между ними:

Здесь то, что выше и ниже логотипа, полностью темное, соответствует цвету. Относительно легко в этом отношении.

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

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

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

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

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

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

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

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


Как заявление об отказе от ответственности, я не имею никакого опыта обработки изображений за пределами этого вопроса и никогда не думал об этом, но это настолько интересно, что заставило меня задуматься об этом, и после прочтения всех остальных ответов я считаю, что это, возможно, самый простой и эффективный способ сделать это. Лично я просто рад , что я не на самом деле надо думать о программировании это!

РЕДАКТИРОВАТЬ

плохой рисунок банки в краске MS Кроме того, посмотрите на этот рисунок, который я сделал в MS Paint ... Он абсолютно ужасный и неполный, но, основываясь только на форме и цветах, вы можете догадаться, что это будет. По сути, это единственные вещи, которые нужно сканировать. Когда вы смотрите на эту очень отличительную форму и сочетание цветов так близко, что еще это может быть? Часть, которую я не рисовал, белый фон, следует считать «чем-то непоследовательным». Если бы у него был прозрачный фон, он мог бы охватить практически любое другое изображение, и вы все равно могли бы его увидеть.


10
Конкретный оттенок красного является в основном субъективным и сильно зависит от освещения и баланса белого. Вы можете быть удивлены тем, насколько они могут измениться. Рассмотрим, к примеру, эту иллюзию шахматной доски .
Осьминог

2
Обновление по ссылке, опубликованной @Octopus
Hat

Иллюзия восприятия не влияет на то, что видит ваша веб-камера - то есть на то, что получает ваш код, - только на то, как человеческий глаз помогает (?) Обмануть мозг.
Барни

17

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

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


1
У меня была та же мысль, но я думаю, что серебряная подкладка на верхней части банки резко меняется в зависимости от угла наклона банки на изображении. Это может быть прямая линия или круг. Может быть, он мог использовать оба в качестве ссылки?
Алексис Дафреной

15

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

  1. Извлечение функций (ключевые точки, дескрипторы, такие как SIFT, SURF) логотипа
  2. Сопоставьте точки с модельным изображением логотипа (используя Matcher, например, Brute Force)
  3. Оценить координаты твердого тела (задача PnP - SolvePnP)
  4. Оцените положение крышки в соответствии с твердым телом
  5. Сделайте обратную проекцию и рассчитайте положение пикселя изображения (ROI) крышки бутылки (я предполагаю, что у вас есть внутренние параметры камеры)
  6. Проверьте методом, есть ли крышка или нет. Если есть, то это бутылка

Обнаружение шапки это еще одна проблема. Это может быть сложным или простым. На вашем месте я бы просто проверил цветовую гистограмму в ROI для простого решения.

Пожалуйста, дайте отзыв, если я ошибаюсь. Спасибо.


13

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


5
ОП сказал, что было 30 изображений с высоким разрешением, что, вероятно, не лучший сценарий для обучения ConvNets. Мало того, что они слишком малы (даже увеличены), часть с высоким разрешением уничтожит ConvNets.
Костас Моратидис

11

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

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

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

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


2
Интересный проект, но он относится только к вашей очень конкретной настройке.
Руи Маркес

11

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

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

Если вы не собираете очень большой набор данных, выполните трюк с использованием функций глубокого обучения для небольшого набора данных. Идеально использовать комбинацию машин опорных векторов (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


10

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

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


9

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

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

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

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

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


2
Хот-дог или не хот-дог?
YellowPillow

6

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

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


3

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

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


0

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

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


0

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

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

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


-1

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

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

Элемент 1 является своего рода кратким сокращением - предварительная обработка, если в изображении нет сопляков, - переходите к следующему этапу.

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

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

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


-9

Это старый проект, над которым я работал. Изображения MAP очень просты в использовании с JavaScript. Я предлагаю вам объект, вы читаете его и знаете, как его использовать. Нам не нужны JQuery и другие системы для использования изображений MAP.

    //Copyright Cherif yahiaoui, by ELEBAN.FR

//variables de flottement.
var myInstOne = null;
var globalize = null;

var eleban_preload_images = function (name, imgs, url){
try{
    var oThis = this;
    this.images = new Array();
    this.imageshover = new Array();
    this.imagesNames = new Array(imgs.split(";"));


        for(var i=0; i < this.imagesNames[0].length; i++){
            this.images[i] = new Image();
            this.imageshover[i] = new Image();
        }

    this.url = url;

    this.GetAbsoluteurl = function () {

    var img = new Image(); img.src = url;
    url = img.src; img = null; 
        this.url = url; 

    };

    this.Preload = function () {

        for(var i=0; i < this.imagesNames[0].length; i++){
            this.images[i].src = this.url+("btn-"+this.imagesNames[0][i]+".png");
            this.imageshover[i].src = this.url+("btn-"+this.imagesNames[0][i]+"-hover.png");
        }

    };
    this.GetAbsoluteurl();
    this.Preload();
}
finally {return;}
}

var g_preloaderhover = new eleban_preload_images("loaderhover","menu;malette;reservation;cabine;facebook;map;amis","./images/");


//variable arret flottement
var g_stopflo = false;

var myObjfloater = function(name, idname, itop, differ ) {
var oThis = this; // création d'une référence vers l'objet courant
this.name = name;
this.id =idname;
this.xstep= 0.3;
this.itime = 30;
this.obj = null;
this.y = itop;
this.yadd = 0;
this.up = true;
this.pause = false;
this.differ = differ;
this.coordsimage = null;
this.objimg = null;
this.initimages = false;
this.compteur = 0;
this.over = false;
this.timeoutstop = null;
try{
this.initimage = function(){
var img = this.obj.getElementsByTagName('img')[0];
this.coordsimage = new Array(img.width, img.height);
this.objimg = img;
this.initimages = true;
};


this.myMethod = function() {
if(!g_stopflo){
    if(this.differ != 0){ 
this.differ=this.differ-0.1; 
}else{

if(this.obj){
if(this.over == false){
    this.yadd=this.yadd+0.1; this.itime = this.itime + 10;
this.obj.style.visibility = "hidden";
this.y = ((this.up)? this.y - this.yadd : this.y + this.yadd);
this.obj.style.marginTop = this.y +"%" ;
this.obj.style.visibility = "visible";

if (this.yadd > this.xstep){ 
    this.up = (this.up)? false : true;
    this.yadd = -0.1; this.itime=180;
}
}
}else{
    if (document){
        if(document.getElementById) {
         this.obj = document.getElementById(this.id); 
        //this.y = this.obj.offsetTop;
        }else{
        if(document.getElementByTagName) { this.obj = document.getElementByTagName(this.id); this.y = this.obj.offsetTop;}
        }

    }
}
}
this.timeoutstop=setTimeout(function() { oThis.myMethod(); }, this.itime);
}    
};

this.callDelayed = function() {
    // utilisation de la référence vers l'objet
if(!g_stopflo){
    this.timeoutstop=setTimeout(function() { oThis.myMethod(); }, this.itime);
}
};
}
finally {return;}
};

// special creation des zones AREA
function eleban_createallarea(){
try{
var measur = new Array("w", "h");
measur["w"] = new Array(330,570,185,300,115,390,225);
measur["h"] = new Array(460,570,295,450,100,190,115);
var ititle = new Array("Voir les menus  et nos suggestions","Repas &agrave; emporter","R&eacute;servation d&rsquo;une table","Nous contacter","Nous rejoindre sur FaceBook","Calculer votre trajet","liste des amis");
var ihref = new Array("menus.html","emporter.html","reservation.html","contact.html","likebox.html","google.html","amis.html");
var b_map = new Array(0,1,2,3,4,5,6);
b_map[0] = "71,32,240,32,249,43,289,352,280,366,102,385,90,371,51,38";
b_map[1] = "66,52,95,14,129,56,115,91,100,93,112,273,128,284,122,366,176,343,193,296,191,194,147,189,145,166,201,111,199,84,545,105,532,354,509,388,412,478,32,401,77,383,87,375,82,286,95,269,94,221,24,195,11,165,9,120,89,123,89,94,78,92,77,92,77,93,75,93,77,93,76,93,79,92";
b_map[2] = "19,25,169,38,173,112,161,113,105,103,90,125,91,262,121,269,124,281,96,293,62,289,49,281,56,268,83,264,84,121,71,98,16,90";
b_map[3] = "60,0,216,1,226,20,225,403,168,421,42,410,45,10";
b_map[4] = "31,7,72,10,82,18,88,45,88,71,76,81,29,80,17,68,16,18";
b_map[5] = "91,40,141,38,178,27,184,4,211,5,223,24,240,23,386,135,229,121,103,180,6,156,49,94";
b_map[6] = "6,32,69,18,79,6,118,7,141,2,149,10,211,17,202,28,209,30,189,62,195,70,178,74,180,90,164,90,154,107,68,101,34,104,34,98,18,97,28,84,15,84,30,65";

if (document.getElementById){
for (var i=0; i<b_map.length;i++){
var obj = document.getElementById("pc_menu"+i);
    if(obj){
    var ct = '<img class=\"pc_menu\" src=\"'+g_preloaderhover.images[i].src+'\" alt=\"\" width=\"'+measur["w"][i]+'\" height=\"'+measur["h"][i]+'\" usemap=\"#MAP_INDEX'+i+'\" \/>';
    ct+='<map name=\"MAP_INDEX'+i+'\">';
    ct+='<area shape=\"poly\" coords=\"'+b_map[i]+'\" title=\"'+ititle[i]+'\" href=\"'+ihref[i]+'\" \/>';
    ct+='<\/map>';
    obj.innerHTML = ct;
    }
}
}
}
finally {return;}
}

//preload, creation et gestion de tous les evenements


var image_resizer = function(g_layer){


    b_org_elm = new Array("w",  "h");
    b_org_elm["w"] = new Array(330,570,185,300,115,390,225);
    b_org_elm["h"] = new Array(460,570,295,450,100,190,115);

    b_map = new Array(0,1,2,3,4,5,6);
    b_map[0] = new Array(71,32,240,32,249,43,289,352,280,366,102,385,90,371,51,38);
    b_map[1] = new Array(66,52,95,14,129,56,115,91,100,93,112,273,128,284,122,366,176,343,193,296,191,194,147,189,145,166,201,111,199,84,545,105,532,354,509,388,412,478,32,401,77,383,87,375,82,286,95,269,94,221,24,195,11,165,9,120,89,123,89,94,78,92,77,92,77,93,75,93,77,93,76,93,79,92);
    b_map[2] = new Array(19,25,169,38,173,112,161,113,105,103,90,125,91,262,121,269,124,281,96,293,62,289,49,281,56,268,83,264,84,121,71,98,16,90);
    b_map[3] = new Array(60,0,216,1,226,20,225,403,168,421,42,410,45,10);
    b_map[4] = new Array(31,6,70,10,78,18,84,23,88,44,88,70,78,80,75,81,33,82,23,76,18,69,16,22,21,13);
    b_map[5] = new Array(91,40,141,38,178,27,184,4,211,5,223,24,240,23,386,135,229,121,103,180,6,156,49,94);
    b_map[6] = new Array(6,32,69,18,79,6,118,7,141,2,149,10,211,17,202,28,209,30,189,62,195,70,178,74,180,90,164,90,154,107,68,101,34,104,34,98,18,97,28,84,15,84,30,65);


    b_layer = g_layer;

//gere mouseover
    this.mouseover = function(e){
        if (!e) var e = window.event;
        var tg = (window.event) ? e.srcElement : e.target
            if (tg.nodeName){
                if(tg.nodeName == "AREA"){
                var divpar = (tg.parentNode)? tg.parentNode.parentNode : tg.parentElement.parentElement;
                    if (divpar){
                        if(divpar.nodeName == "DIV"){
                            var iiobjimg = divpar.getElementsByTagName('img');
                                if (iiobjimg){
                                    ii = parseInt(divpar.id.substring(divpar.id.length-1,divpar.id.length));
                                    iiobjimg[0].src = g_preloaderhover.imageshover[ii].src;
                                }
                        }
                    }
                }
            }
    };

//gere mouseout
    this.mouseout = function(e){
        if (!e) var e = window.event;
        tg = (window.event) ? e.srcElement : e.target
            if (tg.nodeName){
                if(tg.nodeName == "AREA"){
                divpar = (tg.parentNode)? tg.parentNode.parentNode : tg.parentElement.parentElement;
                    if (divpar){
                        if(divpar.nodeName == "DIV"){
                            var iiobjimg = divpar.getElementsByTagName('img');
                                if (iiobjimg){
                                    ii = parseInt(divpar.id.substring(divpar.id.length-1,divpar.id.length));
                                    iiobjimg[0].src = g_preloaderhover.images[ii].src;
                                }
                        }
                    }
                }
            }
    };

//ajout evenements entree sortie à la page web lors du chargement de la page
    this.init = function () {

        for(var i=0; i<b_org_elm["w"].length;i++){
            w = document.getElementById("pc_menu"+i).offsetWidth;
            h = document.getElementById("pc_menu"+i).offsetHeight;

            xa = w/parseFloat(b_org_elm["w"][i]);
            ya = h/parseFloat(b_org_elm["h"][i]);

            area = document.getElementById("pc_menu"+i).getElementsByTagName('area')[0];

            b_map2 = area.coords.split(",");
            yswitch = true;
                for(m=0; m<b_map2.length;m++){
                b_map2[m] = Math.round(parseFloat(b_map[i][m]) * ((yswitch)? xa: ya));
                yswitch = (yswitch)? false :  true;
                }
            area.coords = b_map2.join(',');
        }
    }; 


    this.resize = function () {
    clearTimeout(myInstOne.timeoutstop);
    g_stopflo=true;

    globalize.init();
    g_stopflo=false;
    myInstOne.obj = null;
    myInstOne.callDelayed();
    };


    nar = document.getElementsByTagName('area').length;

        for(var i=0; i<nar;i++){
            var elem = document.getElementsByTagName('area')[i];
            if (elem.addEventListener){
                    elem.addEventListener("onmouseover",this.mouseover,true);
                elem.addEventListener("onmouseout",this.mouseout,true);
            }else if (elem.attachEvent) {
                    elem.attachEvent("onmouseover", this.mouseover);
                    elem.attachEvent("onmouseout", this.mouseout);
            }else{
                    elem["onmouseover"] = this.mouseover;
                    elem["onmouseout"] = this.mouseout;
            }
        }

            window.onresize = this.resize;
        window.onmouseover = this.mouseover;
        window.onmouseout = this.mouseout;
}


//permet de temporiser et éviter les erreurs de chargement des objets
function temporise_Init(Lastdiv){
if(document.getElementById){
    if(document.getElementById(Lastdiv)){

    eleban_createallarea();

    myInstOne = new myObjfloater('b_menumap11', 'pc_menu1', 1, 0);

    globalize = new image_resizer(document.getElementById('pc_redim'));
    globalize.init();
        globalize.resize();



    }else{
    setTimeout(temporise_Init(Lastdiv), 30);
    }
}
}


window.onload = function () {
temporise_Init("pc_bandeau");
}

4
что это делает?
user8408080
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.