Hello World у Computer Vision: визначаємо швидкість руху авто на кордоні з Польщею
Мене звати Сергій Тятін, я в IT більше 20 років. За цей час адмінив юнікс-сервери, паяв і дизайнив залізо, створював продукти, був хакером, займався геймдевом і мобільною розробкою, стартапами, а зараз працюю програмістом на enterprise-проектах. Сьогодні я хотів би розказати про те, як починав розбиратися з Machine learning, а саме зі сферою Computer Vision. І в результаті створив систему, яка визначає швидкість пропускання авто зеленим коридором на кордоні з Польщею.
Ідея
Моє захоплення комп’ютерним зором розпочалося із статті на Хабрі «Нейрореволюция в головах и сёлах». Світ змінився, системи комп’ютерного зору можуть в ріалтаймі розпізнавати об’єкти на відео, і це на звичайному залізі! Відрізняти стовп від пішохода, тротуар, розмітку на відео, знятому камерою в авто. Можливості вражають, і водночас ці технології доступні.
Практичне застосування цих технологій — новий океан можливостей. Ми ще до кінця не уявляємо, де зможемо їх застосувати та що вони нам принесуть. Маючи досвід у цій сфері, можна отримати перевагу в роботі. Я замислився над тим, аби спробувати ці технології. Взяти якийсь готовий інструмент і застосувати його для вирішення реальної проблеми. Я почав шукати, де би можна було застосувати комп’ютерний зір.
Я мешкаю у Львові і міг би їздити до сусідньої Польщі частіше, якби не черги на кордоні. Час, витрачений на проходження кордону, може коливатися від 20 хвилин до
Одним із джерел інформації є камери, які показують чергу. Їх небагато, і інформативність не найкраща. Одна камера встановлена безпосередньо на кордоні і показує чергу машин, які перетинають нейтральну смугу. Практична користь цієї камери дещо сумнівна: машини там є завжди, а ось визначити швидкість руху складно.
У мене виникла ідея використати Computer Vision для підрахунку машин, які перетинають кордон. Це не мало би бути складно, і було би корисно.
Камера на кордоні
Реалізація
Мої очікування щодо складності були на рівні написання «hello world» у новій мові. Вибираю готовий інструмент, читаю рідмі і налаштовую для використання. Реальність виявилася значно суворішою. Рішення оформлені у вигляді pdf-документів, де самі формули, і без підготовки туди ніяк.
Єдиним готовим інструментом, який мені вдалось знайти був YOLO. Це феймворк для створення систем комп’ютерного зору. Проста інсталяція, працююче демо, саме те, що треба. Git clone, make, додатково скачати файл, і YOLO вже розпізнає мене як людину на зображенні з камери ноутбука.
Розпізнавання зображення з камери ноутбука
Наступний крок — натренувати нейронну мережу бачити авто на зображеннях з камери. І це виявилось непросто. Я спробував повторити кроки з тренування за інструкцією до YOLO. На жаль, на той момент вони не працювали, і після виконання всіх кроків на зображенні нічого не розпізнавалося. Тренування мережі займає багато часу, відповідно, побачити, що воно не працює, можна через день. Швидко перевірити різні варіанти не вийде, кожна спроба займає багато часу.
Додаткової інформації немає, розібратися самому — усе впирається в математику. Крім того, авто на зображеннях для тренування мають бути відповідно помічені — до кожного зображення створюється файл із координатами авто, і не було інструменту, який це робить.
Ситуація нагадала мені програмування на PHP на початку
Зробити «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.