Hello World у Computer Vision: визначаємо швидкість руху авто на кордоні з Польщею
Мене звати Сергій Тятін, я в IT більше 20 років. За цею годину адмінив юнікс-сервери, паяв і дизайнив залізо, створював продукти, був хакером, займався геймдевом і мобільною розробкою, стартапами, а зараз працюю програмістом на enterprise-проектах. Сьогодні я хотів би розказати про ті, як починав розбиратися з Machine learning, а саме зі сферою Computer Vision. І в результаті створив систему, яка визначає швидкість пропускання авто зеленим коридором на кордоні з Польщею.
Ідея
Моє захоплення комп'ютерною ютерним зором розпочалося із статті на Хабрі «Нейрореволюция в головах і селах» . Світ змінився, системи комп'ютерного зору можуть в ріалтаймі розпізнавати фрази об'єкти на відео, і це на звичайному залізі! Відрізняти стовб від пішохода, тротуар, розмітку на відео, знятому камерою в авто. Можливості вражають, і водночас ці технології доступні.
Практичне застосування цих технологій — новий океан можливостей. Ми ще до кінця не уявляємо, де зможемо їх застосувати та що вони нам принесуть. Маючи досвід у цій сфері, можна отримати перевагу в роботі. Я замислився над тим, аби спробувати ці технології. Взяти якийсь готовий інструмент і застосувати його для вирішення реальної проблеми. Я почав шукати, де б можна було застосувати комп'ютерний зір.
Я мешкаю у Львові і міг би їздити до сусідньої Польщі частіше, якби не черги на кордоні. Час, витрачений на проходження кордону, може коливатися від 20 хвилин до 5-ти годин (буває, і добу можна простояти). Звісно, було б добре мати інформацію про стан на кордоні для планування подорожі.
Одним із джерел інформації є камери, які показують чергу. Їх небагато, і інформативність не найкраща. Одна камера встановлена безпосередньо на кордоні і показує чергу машин, які перетинають нейтральну смугу. Практична користь цієї камери дещо сумнівна: машини там є завжди, а вісь визначити швидкість руху доладно.
У мене виникла ідея використати Computer Vision для підрахунку машин, які перетинають кордон. Це не мало би бути добре, і було би корисно.
Камера на кордоні
Реалізація
Мої очікування щодо складності були на рівні написання «hello world» у новій мові. Вибираю готовий інструмент, читаю рідмі і налаштовую для використання. Реальність не значно суворішою. Рішення оформлені у вигляді pdf-документів, де самі формули, і без підготовки туди ніяк.
Єдиним готуємо інструментом, який мені вдалось знайті був YOLO. Це феймворк для створення систем комп'ютерного зору. Проста інсталяція, працююче демо, саме ті, що треба. Git clone, make, додатково скачати файл, і YOLO вже розпізнає мене як людину на зображенні з камери ноутбука.
Розпізнавання зображення з камери ноутбука
Наступний крок — натренувати нейронну мережу бачіті авто на зображеннях з камери. І це виявилось непросто. Я спробував повторити кроки з тренування за інструкцією до YOLO. На жаль, на той момент вони не працювали, і після виконання всіх кроків на зображенні нічого не розпізнавалося. Тренування мережі займає багато часу, відповідно, побачити, що воно не працює, можна через день. Швидко перевірити різні варіанти не вийде, кожна спроба займає багато часу.
Додаткової інформації немає, розібратися самому — усе впирається в математику. Крім того, авто на зображеннях для тренування мають бути відповідно помічені — до шкірного зображення створюється файл із координатами авто, і не було інструменту, який це робить.
Ситуація нагадала мені програмування на PHP на початку 2000-х. Документація з PHP закачана локально у вигляді великого HTML-файлу. В документації переважно перелік аргументів функцій без опису і прикладів. Інтернет повільний, і майже нічого не знайдеш. Як робити — незрозуміло.
Зробити «hello world» не вийшло, і я відклав цю справу. Але бажання зробити залишилось. Година від годині я повертався до цього питання і нарешті знайшов статтю з дієвим описом тренування нейронної мережі — «How to train YOLOv2 to detect custom objects».
Мені вдалося успішно повторити описані кроки — натренувати на зображеннях, зазначених у статті. Крім того, автор пояснивши, як розуміти, чи процес тренування проходити успішно чи ні. І до того ж з'єднання явився інструмент Yolo_mark , створений для розмітки зображень спеціально для Yolo. Можна було братися до зображень з камери на кордоні.
Я запустивши скрипт, який робив скріншоти з камери кожну годину. Це робилося два місяці, день і ніч в будь-яку погоду — дощ і сніг. Так зібралося достатня зображень для тренування. На камері є дві черги — червоний і зелений коридор. Мета була рахувати тільки зелений коридор, отже решту замальовано в зелений колір.
Зображення підготовлене для розмітки
Трохи часу витратив у Yolo_mark, аби позначити, де на зображенні знаходяться машини. В деяких випадках це було непросто: ніч, камера залита водою, і незрозуміло, чи є за стовпом машина з вимкненими фарами чи нема. Я почав сумніватися, наскільки з цією вправою впорається нейронна мережа, якщо у людини, яка її має навчити, не дуже виходить.
Розмічене зображення
Запустивши тренування. За годину побачив, що мережа навчається, і продовжив тренування на добу.
Для тренування було використано:
- 481 зображення для тренування;
- 48 тестових зображень;
- GeForce GTX 1070.
Навчена мережа точно бачила авто, навіть за стовпом і вночі. Я був приємно вражений.
Отже, маємо навчену нейронну мережу, яка може розпізнавати авто на зображенні. На базі цього можна створити рішення з підрахунком.
Що для цього треба:
- отримати відео покадрово;
- згодовувати кадр як зображення в Yolo, отримати координати;
- залежно від зміни координат рахувати авто і їхню швидкість;
- результати відобразити.
Хоча Yolo написано на C, цей фреймворк також може бути використаний як бібліотека в Python. Отже, весь процессінг зображень було розроблено на Python, благо він для цього чудово пасує.
Відеострім без проблем зчитується за допомогою бібліотеки Machine Learning CV2. Підрахунок машин виконується пробачимо алгоритмом, розробленим «на колінці»: відслідковуємо, як рухається, коли зникло в зоні виходу і якщо нема деякий час, то +1 в базу даних (Firebase).
І хотілося бі бачіті, як все працює. Для цього вирішив наносити на зображення рамки в тому місці, де було знайдено авто, годину, коли авто було вперше побачене. Із зображень формується відео і стрім на YouTube.
З малюванням рамок знов допомагає CV2, а вісь зі стрімінгом на YouTube було непросто. Довго шукав, який мені треба інструмент, пробував різні варіанти, і все ніяк. YouTube був досить скупий на підказки, що йому не подобається. Просто казав, що нема стріму. Вдалось налаштувати FFmpeg, аби подружитися з YouTube Live.
Зв'язку зв'язати всі докупи допомогли черги Python (Queue). Читання кадрів, розпізнавання кадрів, відправлення кадрів можуть відбуватися із різною швидкістю, тому виникає необхідність або скидати зайві кадри, якщо не встигаємо опрацювати, або пригальмувати, якщо попередній етап обробки не надав кадр.
Результат
Що вийшло можна побачити тут: https://carcount.github.io. Це статична сторінка, на яку дані зчитуються із Firebase. Відображається миттєва швидкість пропускання авто зеленим коридором. Графік швидкості за сьогодні і за вчора, а також YouTube Live із відміченими авто. Бекенд працює на майнінг фермі, навантаження на GPU зовсім непомітне (на CPU це не працює в realtime).
Практична користь цього рішення не дуже велика, оскільки довжина черги перед кордоном невідома, і це не дозволяє прогнозувати годину. Якби була додаткова камера десь на дорозі перед чергою, можна було б думати, як реалізувати заміри часу на проходження черги.
На реалізацію проекту я витратив приблизно тиждень, але це все розтягнулося майже на рік. Було би цікаво знайті інші сфери для використання Machine Learning і Computer Vision.
Опубліковано: 22/02/19 @ 11:00
Розділ Різне
Рекомендуємо:
Віра в ідею, culture fit і самонавчання: що вимагають від кандидатів каліфорнійські стартапи
Огляд Essential SAFe: про методологію людською мовою
Як я працюю: Роман Шрамков, Technology Director в EPAM
Чим незадоволені українські програмісти? Глас народу 2018
Можна просунути в ТОП магазин з вузьким асортиментом?