Обробка зображень: вдосконалення алгоритму розпізнавання "кока-кола"


1658

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

Збіг шаблонів

Деякі обмеження щодо проекту:

  • Фон може бути дуже галасливим.
  • Банка може мати будь-який масштаб або обертання або навіть орієнтацію (в розумних межах).
  • Зображення може мати певний ступінь нечіткості (контури можуть бути не зовсім прямими).
  • Там може бути Coca-Cola пляшки в зображенні, і алгоритм повинен виявити тільки баночку !
  • Яскравість зображення може сильно відрізнятися (тому ви не можете покладатися "надто" на виявлення кольорів).
  • Може , може бути частково приховані з боків або в середині і , можливо , частково приховані за пляшкою.
  • На зображенні взагалі не може бути жодної канди, в цьому випадку вам нічого не потрібно було знайти і написати повідомлення про це.

Таким чином, ви можете закінчити такі складні речі (які в цьому випадку мій алгоритм повністю вийшов з ладу):

Загальний збій

Я робив цей проект деякий час тому, і мені було дуже весело робити його, і я отримав гідну реалізацію. Ось кілька деталей щодо моєї реалізації:

Мова : Зроблено на C ++ за допомогою бібліотеки OpenCV .

Попередня обробка : Для попередньої обробки зображення, тобто перетворення зображення в більш необроблену форму для надання алгоритму, я використав 2 способи:

  1. Зміна кольорового домену з RGB на HSV та фільтрація на основі "червоного" відтінку, насичення вище певного порогу, щоб уникнути кольорів, що нагадують помаранчевий, та фільтрація низького значення, щоб уникнути темних тонів. Кінцевим результатом було двійкове чорно-біле зображення, де всі білі пікселі представляли б пікселі, що відповідають цьому порогу. Очевидно, що в зображенні все ще багато лайна, але це зменшує кількість вимірів, з якими вам доведеться працювати. Бінаризоване зображення
  2. Шум фільтрація за допомогою медіанної фільтрації (приймаючи середнє значення пікселів усіх сусідів і замінюючи піксель на це значення), щоб зменшити шум.
  3. Використовуючи фільтр Canni Edge Detection, щоб отримати контури всіх елементів після 2 попередніх кроків. Виявлення контуру

Алгоритм : Сам алгоритм, який я вибрав для цього завдання, взятий із цієї дивовижної книги про вилучення функцій і назвав Генералізована трансформація Hough (сильно відрізняється від звичайної Hough Transform). В основному це говорить кілька речей:

  • Ви можете описати об'єкт у просторі, не знаючи його аналітичного рівняння (що тут справа).
  • Він стійкий до деформацій зображення, таких як масштабування та обертання, оскільки в основному він перевірить ваше зображення на кожну комбінацію коефіцієнта масштабу та коефіцієнта обертання.
  • Він використовує базову модель (шаблон), яку алгоритм "вивчить".
  • Кожен піксель, що залишився на контурному зображенні, буде голосувати за інший піксель, який нібито буде центром (з точки зору тяжкості) вашого об'єкта, виходячи з того, що він дізнався з моделі.

Зрештою, ви закінчуєте теплову карту голосів, наприклад, тут усі пікселі контуру банки можуть проголосувати за її гравітаційний центр, тож у вас буде багато голосів у тому ж пікселі, що відповідає центр, і буде показано пік на тепловій карті, як показано нижче:

GHT

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

Результати : Хоча цей підхід працював у основних випадках, у деяких сферах його сильно бракувало:

  • Це надзвичайно повільно ! Я недостатньо наголошую на цьому. На обробку 30 тестових зображень знадобився майже повний день, очевидно, тому що у мене дуже високий коефіцієнт масштабування для обертання та перекладу, оскільки деякі банки були дуже маленькими.
  • Це було повністю втрачено, коли пляшки були на зображенні, і чомусь майже завжди знаходили пляшку замість банки (можливо, тому, що пляшки були більшими, таким чином, було більше пікселів, таким чином більше голосів)
  • Нечіткі зображення також не принесли користі, оскільки голоси опинилися в пікселях у випадкових місцях по центру, таким чином закінчившись дуже галасливою тепловою картою.
  • Було досягнуто різницю в перекладі та обертанні, але не в орієнтації, що означає, що бляшанка, яка не була безпосередньо стоїть перед ціллю камери, не була розпізнана.

Чи можете ви допомогти мені вдосконалити свій конкретний алгоритм, використовуючи виключно функції OpenCV , щоб вирішити чотири конкретні проблеми?

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


45
Можна сказати, що це питання є більш підходящим на dsp.stackexchange.com або stats.stackexchange.com, і ви, звичайно, повинні також розглянути питання про повторне запитання на цих сайтах.
ely

49
Перше, що потрібно зробити тут - проаналізувати, чому трапляються різні випадки відмов. Наприклад, виділіть приклади місць, де виграють пляшки, де зображення нечіткі тощо, і проведіть статистичний аналіз, щоб дізнатися різницю між їхніми представленнями Хоха та тими, які ви хочете, щоб вони виявили. Деякі великі місця , щоб дізнатися про альтернативні підходи тут і тут
Елайте

7
@stacker робить хороший момент. Для швидкості ви хочете отримати дешеві функції обчислення, як гістограми орієнтованих градієнтів. По-справжньому наївним першим підходом було б вручну позначити купу прямокутників на деяких навчальних зображеннях і використовувати ці плюс випадкові негативні приклади для підготовки SVM або класифікатора дерева дерев. Навчання займе більше часу, але виконання на нових зображеннях буде набагато швидшим. Я планую написати цей метод, коли отримаю більше вільного часу для включення правильних посилань.
ely

9
Як щодо підходу, подібного до reCAPTCHA ? ;)
Джордж Дакетт

39
Чому це переміщено з dsp.stackexchange.com ? Здається, що цей сайт був би ще кращим, ніж
stackoverflow

Відповіді:


672

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

Він реалізований у OpenCV 2.3.1.

Ви можете знайти приклад хорошого коду, використовуючи функції в Features2D + Homography, щоб знайти відомий об’єкт

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

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

Джерело зображення: приклад підручника

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

Оригінальні папери


6
Я згоден з @stacker - SIFT - відмінний вибір. Це дуже надійно проти операцій масштабування та обертання. Це дещо надійно проти перспективної деформації (це можна покращити, як це запропонував укладальник: база даних шаблонів з різними перспективними видами потрібного об'єкта). На моєму досвіді, Ахіллесова п'ята - це сильні варіанти освітлення та дуже дорогі обчислення. Я не знаю жодної реалізації Java. Мені відомо про реалізацію OpenCV і використовував реалізацію GPU c ++ / Windows ( SiftGPU ), що підходить для роботи в режимі реального часу.

31
Нота попередження: наскільки я люблю SIFT / SURF і те, що вони зробили для мене, вони обтяжені патентом. Це може бути проблемою, залежно від ряду умов, включаючи географічне розташування AFAIK.
Agos

12
Тому спробуйте ORB або FREAK OpenCV, які не мають жодних патентних питань. ORB набагато швидше, ніж SIFT. ORB - це трохи бідно, коли в моєму досвіді є масштабні та легкі зміни, але протестуйте самі.
Rui Marques

66
Як ви можете прийняти це як відповідь ... Жоден із дескрипторів функцій не може відрізняти пляшки від банок. Усі вони просто переглядають інваріантні локальні дескриптори. Я погоджуюся, що SIFT, SURF, ORB, FREAK тощо можуть допомогти вам у поєднанні функцій, але .. Що стосується інших ваших частин питання, таких як оклюзії, Bottle vs Can тощо. Я сподіваюся, що це не є повноцінним рішенням, якщо ви GOOGLED ваша проблема, ймовірно, першим результатом буде лише ця відповідь.
G453

11
@ G453 ви абсолютно праві! Ймовірно, він був захоплений виконанням SHIFT і забув, що вилучення та узгодження функції НЕ ПРОБЛЕМА ...
sepdek

383

Щоб пришвидшити справи, я б скористався тим, що вас просять не знайти довільне зображення / об'єкт, а конкретно один із логотипом Coca-Cola. Це важливо, оскільки цей логотип є дуже виразним, і він повинен мати характерну, масштабну-інваріантну підпис у частотній області, особливо у червоному каналі RGB. Тобто змінний малюнок червоно-білого-червоного, що зустрічається горизонтальною лінією сканування (навчена горизонтально вирівняним логотипом), матиме характерний «ритм», коли він проходить через центральну вісь логотипу. Цей ритм "прискориться" або "сповільниться" в різних масштабах і орієнтаціях, але залишиться пропорційно рівноцінним. Ви могли визначити / визначити кілька десятків таких ліній, як горизонтально, так і вертикально через логотип та ще кілька діагонально, у зоряному візерунку. Назвіть їх "лініями сканування підпису".

Рядок сканування підписів

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

Я був би здивований, якби це був не лінійно ефективний алгоритм, або майже так. Очевидно, це не стосується вашої дискримінації, яку ви можете використовувати, але принаймні ви матимете свої логотипи.

(Оновлення: для розпізнавання пляшки я б шукав кокс (коричневу рідину), що прилягає до логотипу - тобто всередині пляшки. Або, у випадку порожньої пляшки, я б шукав ковпачок, який завжди матиме однакова основна форма, розмір та відстань від логотипу і зазвичай будуть усі білі або червоні. Шукайте суцільну кольорову еліптичну форму там, де має бути шапка , відносно логотипу. Звичайно, не безглуздо, але ваша мета тут має бути знайти прості з них швидко .)

(Минуло кілька років з моїх днів обробки зображень, тому я підтримав цю пропозицію на високому рівні та концептуальною. Я думаю, що це може дещо наблизитись до того, як може діяти людське око - або, принаймні, як працює мій мозок!)


24
Це чудова пропозиція, мені особливо подобається те, що цей алгоритм повинен бути досить швидким, навіть якщо він, мабуть, матиме багато помилкових негативів. Одна з моїх прихованих цілей - використовувати це виявлення в режимі реального часу для робототехніки, щоб це міг стати хорошим компромісом!
Чарльз Менгуй

42
Так, часто забувають (у полі, що характеризується точністю), що алгоритми наближення є найважливішими для більшості завдань моделювання в реальному реальному часі. (Я базував свою тезу на цій концепції.) Збережіть свої вимогливі до часу алгоритми для обмежених регіонів (щоб підрізати помилкові позитиви). І пам’ятайте: у робототехніці зазвичай ви не обмежуєтесь одним зображенням. Якщо припустити, що мобільний робот, швидка водорость може шукати десятки зображень з різних ракурсів за менший час, ніж складні водорості витрачають на одного, значно зменшуючи помилкові негативи.
кмоте

29
Мені подобається ідея використання того, що означає сканер штрих-коду для надзвичайно швидкого виявлення логотипів Coca-Cola. +1!
Li-aung Yip

8
Проблема пошуку підписів у цьому випадку полягає в тому, що якщо ми повернемо банку в іншу сторону, тобто приховати підпис, алгоритм не зможе виявити балончик.
karlphillip

34
@karlphillip: Якщо ви ховаєте підпис, тобто логотип, будь-який метод, заснований на пошуку логотипу, вийде з ладу.
Лі-аун Іп

162

Проблема із задоволенням: коли я поглянув на ваше зображення пляшки, я подумав, що це теж консервна банка. Але, як людина, те, що я зробив, щоб сказати різницю, це те, що я потім помітив, що це теж пляшка ...

Отже, щоб розказати банки і пляшки окремо, як щодо просто сканування спочатку пляшок? Якщо ви знайдете його, замаскуйте етикетку, перш ніж шукати банки.

Не надто складно реалізувати, якщо ви вже робите банки. Справжній мінус - це подвоєння часу на обробку. (Але якщо заздалегідь подумати над реальними програмами, ви все одно хочете робити пляшки ;-)


5
Так, я теж думав про це, але не мав багато часу для цього. Як би ви розпізнали пляшку, оскільки основна її частина буде виглядати як масштабована банка? Я думав також шукати червону штепсельну вилку і бачити, чи суміщена вона з пляшковою центром, але це не здається дуже надійним.
Чарльз Менгуй

42
Якщо паралельна «кока-кола» є червона кришка (або кільце), швидше за все, пляшка.
Лукаш Мадон

@linker Як ви тренували свій алгоритм для банок? Чи були у вас приклади банок? Як щодо навчання з прикладами пляшок?
siamii

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

7
По суті це розумний напрямок. Я б сказав це дещо інакше: спочатку знайдіть усіх кандидатів, а потім для кожного кандидата визначте, чи це пляшка, банка чи щось інше.
MSalters

131

Чи не важко навіть людям розрізнити пляшку і банку на другому зображенні (за умови, що прозора область пляшки прихована)?

Вони майже однакові, за винятком дуже невеликого регіону (тобто ширина у верхній частині банки є невеликою, тоді як обгортка пляшки однакової ширини по всій, але незначна зміна, правда?)

Перше, що мені прийшло в голову, - це перевірити на червоний верх пляшки. Але це все ще проблема, якщо для пляшки немає верху, або якщо вона частково прихована (як було сказано вище).

Друге, що я подумав - про прозорість пляшки. OpenCV має деякі роботи з пошуку прозорих об'єктів у зображенні. Перевірте наведені нижче посилання.

Особливо подивіться на це, щоб побачити, наскільки точно вони виявляють скло:

Дивіться результат їх впровадження:

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

Вони кажуть, що це реалізація документа "Геодезичні рамки активного контуру для пошуку скла" К. Макенрі та Дж. Понсе, CVPR 2006 .

У вашому випадку це може бути корисним трохи, але проблема виникає знову, якщо пляшку наповнити.

Тому я думаю, що тут ви можете шукати спочатку прозоре тіло пляшок або червону область, з'єднану з двома прозорими предметами збоку, що, очевидно, є пляшкою. (Коли ви працюєте в ідеалі, зображення виглядає наступним чином.)

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

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

У будь-якому випадку це рішення також має різні проблеми, як і в інших рішеннях.

  1. Він працює лише в тому випадку, якщо ваша пляшка порожня. У такому випадку вам доведеться шукати червону область між двома чорними кольорами (якщо рідина Coca Cola - чорна).
  2. Ще одна проблема, якщо покрита прозора частина.

Але все одно, якщо на знімках немає жодної з перерахованих вище проблем, це здається кращим способом.


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

так .. я занадто думаю, що це було б добре, якщо було більше зображень.
Абід Рахман K

Враховуючи, чи є у нас лише етикетки для пляшок / банок і жоден з інших відмінних факторів кришки пляшки або прозорості чи може зверху / знизу - Ширина пляшки відрізняється від ширини банки.
Кен

Що робити, якщо банку розміщують перед логотипом для пляшки?
AlgoRythm

51

Мені дуже подобаються відповіді Даррена Кука та стакера на цю проблему. Я був у розпалі, коли я кидав свої думки в коментар до цих питань, але я вважаю, що мій підхід є занадто формою відповіді, щоб не залишати тут.

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

Секрет тут полягає в визначенні , які візуальні ознаки може , містить або через негативне простір, які функції присутні для інших продуктів коксу, які не присутні в банках. З цією метою нинішня відповідь наводить основний підхід до вибору "може" тоді і лише тоді, коли "пляшка" не ідентифікована, або наявністю кришки пляшки, рідини або іншої подібної візуальної евристики.

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

З цією метою найбільш правильними критеріями відбору банок є такі:

  • Чи правильна форма силуету об'єкта, як ви замальовували у своєму запитанні ? Якщо так, +1.
  • Якщо ми припускаємо наявність природного чи штучного світла, чи виявляємо хромовий контур пляшки, який означає, чи зроблено це з алюмінію? Якщо так, +1.
  • Чи визначимо ми правильність окулярів властивості об'єкта щодо наших джерел світла ( ілюстративний відеопосилання на виявлення джерела світла )? Якщо так, +1.
  • Чи можемо ми визначити будь-які інші властивості щодо об’єкта, що ідентифікують його як консервну, включаючи, але не обмежуючись цим, топологічне перекос зображення логотипу, орієнтацію об'єкта, складання об'єкта (наприклад, на площинній поверхні як таблиця або в розрізі інших банок), і наявність висувної вкладки? Якщо так, для кожного +1.

Тоді ваша класифікація може виглядати наступним чином:

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

Це візуально підкреслює користувачеві те, що було виявлено, підкреслюючи слабкі позитиви, які, правильно, можуть бути виявлені як перероблені банки.

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

І ей, вітаємо з публікацією Hacker News! В цілому, це досить приголомшливе питання, гідне розголосу, яке воно отримало. :)


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-зіставлення на двовимірне зіставлення) можливо, що пляшка може здатися скороченою, і різниці в розмірах немає Ви можете відновити деяку глибинну інформацію за допомогою стереообразування, а потім відновити початковий розмір.


3
Насправді ні: немає обмежень щодо розміру чи орієнтації (або орієнтації, але я не дуже впорався з цим), тому ви можете мати пляшку дуже далеко у фоновому режимі, а банку на передньому плані, а може бути набагато більша ніж пляшка.
Чарльз Менгуй

Я також перевірив, що співвідношення ширини до висоти досить схоже на пляшку і може, тому це теж насправді не варіант.
Чарльз Менгуй

Коефіцієнт етикетки (будучи торговою маркою) однаковий. Тож якщо пляшка (більша) трохи далі від картинки, її розмір буде точно такий же, як у банки.
littleadv

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

2
Це просто коментар, а не відповідь, але це набагато ближче до відповіді, ніж коментар як відповідь вище зі 120 голосами.
Fattie

22

Хм, я насправді думаю, що я щось вирішую (це як найцікавіше питання коли-небудь - тому було б прикро не продовжувати намагатися знайти "ідеальну" відповідь, навіть якщо прийнятну знайдено). .

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

Що це навколо логотипу? На бляшанці ми бачимо метал, який, незважаючи на вплив освітлення, не змінює жодного в основному кольорі. Поки ми знаємо кут етикетки, ми можемо сказати, що знаходиться безпосередньо над ним, тому ми розглядаємо різницю між цими:

Тут те, що вище і нижче логотипу, є абсолютно темним, послідовним кольором. Відносно легко в цьому відношенні.

Ось, що зверху і знизу, - це світлий, але все ж стійкий колір. Це все-срібло, а металевий суцільний срібло насправді здається досить рідкісним, як і сріблясті кольори взагалі. Крім того, він знаходиться в тонкій щілині і достатньо близько до червоного, який вже був визначений, щоб ви могли простежити його форму по всій довжині, щоб обчислити відсоток того, що можна вважати металевим кільцем банки. Дійсно, вам потрібна лише невелика частка того, що десь уздовж банки може сказати, що вона є частиною цього, але все одно потрібно знайти баланс, який гарантує, що це не просто порожня пляшка з чимось металевим позаду.

І нарешті, хитра. Але це не так складно, коли ми лише переходимо до того, що можемо побачити прямо (і знизу) червону обгортку. Його прозоре, а значить, воно покаже все, що за ним стоїть. Це добре, тому що речі, що стоять за ним, швидше за все, не будуть настільки стійкими за кольором, як срібний круглий метал з банки. За цим може бути багато різних речей, які б сказали нам, що це порожня пляшка (або наповнена прозорою рідиною) або однаковий колір, який може означати, що вона заповнена рідиною, або що пляшка просто перед суцільний колір. Ми працюємо з тим, що знаходиться найближче до верху і знизу, і шанси на те, що правильні кольори знаходяться в потрібному місці, відносно невеликі. Ми знаємо, що це пляшка, тому що в ній немає цього ключового візуального елементу,

(що останній був найкращим, що я міг знайти із порожньої великої пляшки з кока-колою - цікаво, що кришка І кільця жовті, що вказує на те, що на почервоніння шапки, напевно, не слід покладатися)

За рідкісних обставин, що схожий відтінок срібла знаходиться за пляшкою, навіть після відсмоктування пластику, або пляшка якось заповнена тим самим відтінком сріблястої рідини, ми можемо повернутися до того, що ми можемо приблизно оцінити як форма срібла - яка, як я вже згадувала, кругла і відповідає формі банки. Але хоча мені не вистачає певних знань в обробці зображень, це звучить повільно. А ще краще, чому б не вивести це за один раз, перевіривши по сторонах логотипу, щоб переконатися, що там немає нічого такого ж сріблястого кольору? Ах, але що, якщо за банком є ​​такий же сріблястий відтінок? Тоді ми справді повинні приділяти більше уваги формам, знову дивлячись на верхню та нижню частину банки.

Залежно від того, наскільки бездоганним це все має бути, це може бути дуже повільним, але, мабуть, моя основна концепція - це спочатку перевірити найпростіші та найближчі речі. Перейдіть за кольоровими відмінностями навколо вже підібраної форми (яка все-таки здається найбільш тривіальною частиною цього), перш ніж намагатися опрацювати форму інших елементів. Щоб перерахувати його, йдеться:

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

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

Цікавими додатковими кошмарами можуть бути бляшанка, зручно сидіти за пляшкою на такій відстані, що металевий склад просто так виявляється вище та під етикеткою, що все-таки вийде з ладу, якщо ви скануєте по всій довжині червоного етикетка - що насправді є більшою проблемою, оскільки ви не виявляєте банку там, де могли бути, на відміну від того, що вважаєте, що ви насправді виявляєте пляшку, включаючи банку, випадково. Склянка наполовину порожня, в такому випадку!


Як застереження, я не маю досвіду і не замислювався над обробкою зображень поза цим питанням, але це настільки цікаво, що він змусив мене досить глибоко замислитися над цим питанням, і, прочитавши всі інші відповіді, я вважаю, що це можливо найпростіший та найефективніший спосіб зробити це. Особисто я просто радий, що насправді не треба думати над цим програмуванням!

EDIT

поганий малюнок банки в фарбі MS Додатково подивіться на цей малюнок, який я зробив у програмі MS Paint ... Це абсолютно жахливо і зовсім неповно, але, виходячи лише з форми та кольорів, ви можете здогадатися, що це, мабуть, буде. По суті, це єдині речі, для яких потрібно турбувати сканування. Якщо ви дивитесь на цю дуже виразну форму та поєднання кольорів так близько, що ще могло бути? Біт, який я не фарбував, білий фон слід вважати "чимось непослідовним". Якщо б він мав прозорий фон, він міг би перейти майже на будь-яке інше зображення, і ви все ще могли його бачити.


10
Особливий відтінок червоного є переважно суб'єктивним і сильно впливає на міркування освітлення та баланс білого. Ви можете бути здивовані тим, наскільки вони можуть змінитися. Розглянемо, наприклад, цю ілюзію шахівниці .
Восьминіг

2
Оновлення посилання, яке розмістив @Octopus
Hat

Ілюзія сприйняття не впливає на те, що бачить ваша веб-камера - тобто те, що отримує ваш код, - лише наскільки людське око допомагає (?) Дурити мозок.
barny

17

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

Але очевидно, що цей алгоритм вийде з ладу у випадках, коли вершина банки прихована, але в такому випадку навіть людина не зможе розмежовувати їх (якщо видно лише порцію кока-кола з пляшки / банки)


1
У мене була така ж думка, але я думаю, що срібляста підкладка зверху банки кардинально змінюється залежно від кута банки на малюнку. Це може бути пряма лінія або коло. Можливо, він міг би використовувати обидва в якості посилання?
Олексій Дуфреной

15

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

  1. Функції вилучення (ключові точки, дескриптори, такі як SIFT, SURF) логотипу
  2. Зіставте бали з модельним зображенням логотипу (використовуючи Matcher, такий як Brute Force)
  3. Оцініть координати жорсткого тіла (проблема PnP - SolvePnP)
  4. Оцініть положення кришки відповідно до жорсткого корпусу
  5. Зробіть задню проекцію та обчисліть позицію пікселя зображення (ROI) кришки пляшки (я припускаю, що у вас є внутрішні параметри камери)
  6. Перевірте методом, чи є кришка там чи ні. Якщо є, то це пляшка

Виявлення шапки - це ще одне питання. Це може бути як складне, так і просте. Якби я був ти, я просто перевірив би кольорову гістограму в рентабельності інвестицій для простого рішення.

Будь ласка, дайте відгуки, якщо я помиляюся. Дякую.


13

Я запізнююся на кілька років, відповідаючи на це питання. Із сучасним рівнем роботи, підключеним CNN до своїх меж протягом останніх 5 років, я б не використовував OpenCV для виконання цього завдання зараз! ( Я знаю, що ви спеціально хотіли функції OpenCv у питанні ). Я відчуваю, що такі алгоритми виявлення об'єктів, як швидше RCNN, YOLO, SSD тощо, вирішили би цю проблему зі значним запасом порівняно з функціями OpenCV. Якби я вирішив цю проблему зараз (через 6 років !!), я б точно використав Faster-RCNN .


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

11

Мені подобається ваше запитання, незалежно від того, чи це поза темою чи ні: P

Цікавий бік; Я тільки що закінчив предмет, в якому я вивчав робототехніку та комп'ютерний зір. Наш проект за семестр був неймовірно схожий на той, який ви описуєте.

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

Про наш підхід ви можете прочитати в моєму блозі на тему :)


2
Цікавий проект, але він стосується лише вашої конкретної установки.
Руй Маркес

10

Існує купа дескрипторів кольорів, які використовуються для розпізнавання об'єктів, папір нижче порівнює багато з них. Вони особливо потужні в поєднанні з SIFT або SURF. SURF або SIFT не дуже корисні для зображень кока-коли, оскільки вони не розпізнають багато цікавих точок, вам потрібна інформація про кольори. Я використовую BIC (класифікація кордону / інтер'єру пікселів) разом із SURF в проекті, і він прекрасно працював для розпізнавання об'єктів.

Кольорові дескриптори для пошуку веб-зображень: порівняльне дослідження


10

Глибоке навчання

Зберіть хоча б кілька сотень зображень, що містять банки з кола, анотуйте обмежувальне поле навколо них як позитивні класи, включіть пляшки кола та інші продукти кола, позначаючи їх негативними класами, а також випадковими об'єктами.

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


9

Вам потрібна програма, яка засвоює та покращує точність класифікації органічно з досвіду.

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

Ви можете перекваліфікувати модель v3 inception на Tensorflow:

Як відтворити остаточний шар для початкових категорій для нових категорій .

У цьому випадку ви будете тренувати конволюційну нейронну мережу, щоб класифікувати об'єкт як кока-кола, чи ні.


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

Можливо, занадто багато років спізнюється, але все-таки теорія спробувати.

Відношення обмежуючого прямокутника області червоного логотипу до загального розміру пляшки / банки є різним. У випадку з Кан може бути 1: 1, тоді як пляшка буде відрізнятися (із кришкою чи без). Це повинно полегшити розмежування обох.

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


-1

Перше, на що я хотів би звернути увагу, - це кольоровий колір, як червоний, при виявленні червоних очей на зображенні - є певна кольорова діапазон для виявлення, деякі характеристики щодо нього з урахуванням навколишньої області та такі, як відстань від іншого ока, якщо він дійсно видно на зображенні.

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

Пункт 1 є своєрідним скороченням - попередньо обробляйте, якщо цей образ соплі існує на зображенні - рухайтеся далі.

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

2: Враховуючи вищевказану ідентифікаційну область зображення в 1 - перевірте навколишні точки [краї] відповідного елемента. Відповідь: Чи є те, що здається, зверху чи знизу - з срібла? B: Пляшка може виглядати прозорою, але може бути і скляний стіл - так є скляний стіл / полиця або прозора область - якщо так, можливе декілька можливих. Пляшка може мати червоний ковпачок, він може не бути, але він повинен мати форму верхньої частини / гвинтів для нитки пляшки, або кришку. C: Навіть якщо це не вдається A і B, все одно це може бути балончик - частковий. Це складніше, коли він частковий, тому що часткова пляшка / часткова може виглядати так само, тож ще деяка обробка вимірювання краю Червоної області до краю .. маленька пляшка може бути схожою за розміром ..

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


-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");
}

3
що це робить?
user8408080
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.