Одним із найцікавіших проектів, над якими я працював за останні кілька років, був проект з обробки зображень . Метою було розробити систему, яка б змогла розпізнати Coca-Cola "консерви" (зауважте, що я наголошую на слові "консерви", ви побачите чому через хвилину). Ви можете побачити зразок нижче, при цьому балончик розпізнається в зеленому прямокутнику за масштабом і обертанням.
Деякі обмеження щодо проекту:
- Фон може бути дуже галасливим.
- Банка може мати будь-який масштаб або обертання або навіть орієнтацію (в розумних межах).
- Зображення може мати певний ступінь нечіткості (контури можуть бути не зовсім прямими).
- Там може бути Coca-Cola пляшки в зображенні, і алгоритм повинен виявити тільки баночку !
- Яскравість зображення може сильно відрізнятися (тому ви не можете покладатися "надто" на виявлення кольорів).
- Може , може бути частково приховані з боків або в середині і , можливо , частково приховані за пляшкою.
- На зображенні взагалі не може бути жодної канди, в цьому випадку вам нічого не потрібно було знайти і написати повідомлення про це.
Таким чином, ви можете закінчити такі складні речі (які в цьому випадку мій алгоритм повністю вийшов з ладу):
Я робив цей проект деякий час тому, і мені було дуже весело робити його, і я отримав гідну реалізацію. Ось кілька деталей щодо моєї реалізації:
Мова : Зроблено на C ++ за допомогою бібліотеки OpenCV .
Попередня обробка : Для попередньої обробки зображення, тобто перетворення зображення в більш необроблену форму для надання алгоритму, я використав 2 способи:
- Зміна кольорового домену з RGB на HSV та фільтрація на основі "червоного" відтінку, насичення вище певного порогу, щоб уникнути кольорів, що нагадують помаранчевий, та фільтрація низького значення, щоб уникнути темних тонів. Кінцевим результатом було двійкове чорно-біле зображення, де всі білі пікселі представляли б пікселі, що відповідають цьому порогу. Очевидно, що в зображенні все ще багато лайна, але це зменшує кількість вимірів, з якими вам доведеться працювати.
- Шум фільтрація за допомогою медіанної фільтрації (приймаючи середнє значення пікселів усіх сусідів і замінюючи піксель на це значення), щоб зменшити шум.
- Використовуючи фільтр Canni Edge Detection, щоб отримати контури всіх елементів після 2 попередніх кроків.
Алгоритм : Сам алгоритм, який я вибрав для цього завдання, взятий із цієї дивовижної книги про вилучення функцій і назвав Генералізована трансформація Hough (сильно відрізняється від звичайної Hough Transform). В основному це говорить кілька речей:
- Ви можете описати об'єкт у просторі, не знаючи його аналітичного рівняння (що тут справа).
- Він стійкий до деформацій зображення, таких як масштабування та обертання, оскільки в основному він перевірить ваше зображення на кожну комбінацію коефіцієнта масштабу та коефіцієнта обертання.
- Він використовує базову модель (шаблон), яку алгоритм "вивчить".
- Кожен піксель, що залишився на контурному зображенні, буде голосувати за інший піксель, який нібито буде центром (з точки зору тяжкості) вашого об'єкта, виходячи з того, що він дізнався з моделі.
Зрештою, ви закінчуєте теплову карту голосів, наприклад, тут усі пікселі контуру банки можуть проголосувати за її гравітаційний центр, тож у вас буде багато голосів у тому ж пікселі, що відповідає центр, і буде показано пік на тепловій карті, як показано нижче:
Коли ви це зробите, простий евристичний на основі порогових значень може дати вам розташування центрального пікселя, з якого ви можете отримати масштаб та обертання, а потім побудувати навколо себе маленький прямокутник (остаточний масштаб та коефіцієнт обертання, очевидно, будуть відповідні вашим оригінальний шаблон). Теоретично принаймні ...
Результати : Хоча цей підхід працював у основних випадках, у деяких сферах його сильно бракувало:
- Це надзвичайно повільно ! Я недостатньо наголошую на цьому. На обробку 30 тестових зображень знадобився майже повний день, очевидно, тому що у мене дуже високий коефіцієнт масштабування для обертання та перекладу, оскільки деякі банки були дуже маленькими.
- Це було повністю втрачено, коли пляшки були на зображенні, і чомусь майже завжди знаходили пляшку замість банки (можливо, тому, що пляшки були більшими, таким чином, було більше пікселів, таким чином більше голосів)
- Нечіткі зображення також не принесли користі, оскільки голоси опинилися в пікселях у випадкових місцях по центру, таким чином закінчившись дуже галасливою тепловою картою.
- Було досягнуто різницю в перекладі та обертанні, але не в орієнтації, що означає, що бляшанка, яка не була безпосередньо стоїть перед ціллю камери, не була розпізнана.
Чи можете ви допомогти мені вдосконалити свій конкретний алгоритм, використовуючи виключно функції OpenCV , щоб вирішити чотири конкретні проблеми?
Я сподіваюсь, що деякі люди також навчиться чомусь із цього, адже я думаю, що не тільки люди, які задають питання, повинні вчитися. :)