Як я прикручував спідометр до танків

image
 
Якось давно побачив відео, де людина грав у якийсь автосимулятор і у нього на столі стояли 2 великих стрілочних індикатора (вольтметри, якщо я не помиляюся), які виконували роль спідометра і тахометра. Cпустя кілька років я вирішив повторити щось схоже.
 
Грав я тільки в World of Tanks (і то давно закинув, так і не докачати до 10 рівня) з цього і вирішив все провернути саме з танками. Відразу скажу, вся розробка, за винятком налагодження проводилася на linux, код що виконується на ПК написаний на Пітоні. Та він повільний і код показувати мені соромно, з цього обійдемося без нього.
 
 

Спідометр

В якості спідометра теж вирішив використовувати що-небудь зі стрілкою, ця роль випала старому, дешевому, китайському мультиметру зі стрілочної індикацією.
 
Було вирішено, що керувати спідометром буде ATMEGA16, оскільки була отладочная плата з усією необхідною обв'язкою на борту. Спілкування ПК -> МК організовано через послідовний порт.
 
 Показометр і МК
 
 
 
Прошивка примітивна, алгоритм приблизно такий:
 
     
  1. У нескінченному циклі слухаємо USART.
  2.  
  3. При отриманні даних швидкості, вони перевірялися на валідність і за допомогою ШІМ'а встановлювався необхідний рівень напруги.
  4.  
 
Це була найпростіша частина, далі необхідно було отримати значення швидкості. Відразу виникло 2 ідеї: Отримати дані у процесу гри (шерстити пам'ять в надії знайти жаданий адреса) або сканувати значення безпосередньо з самого інтерфейсу і розпізнати його. Останнє для мене було зовсім темний ліс і звучало цікаво.
 
 

Отримання заповітної швидкості

Спочатку отримуємо скріншот гри, я наївно вважав, що з цим проблем не буде, але, як виявилося, захопити екран в режимі DirectX річ не найпростіша, але вирішуване звичайно. Замість інтерфейсу гри виходили прямокутники Малевича, тобто даремні зображення, я недовго думаючи перейшов у віконний режим і розгорнув вікно гри на весь екран, різниця в інформативності з повноекранним режимом мінімальна, але екран став чудово захоплюватися.
 
Захоплював я не весь екран, а невелика ділянка в 200х200 приблизно пікселів, з ним уже і працював.
 
 Скріншот ігрового інтерфейсу і панель ушкоджень
 
 
 
Потім я прочинив для себе таку чудову річ як OpenCV, з її допомогою знебарвив картинку і інвертуватися кольору (спочатку фон темний, а цифри світлі).
 
Швидкість у нас представляє максимум двухразрядное число, причому моношірним шрифтом, що теж радувало, тому як розряди займали строго певне місце і не зміщувалися при зміні значення швидкості. Залишалося тільки виділити ці 2 позиції і розпізнавати їх.
 
 
 
 
Розпізнавання
Розпізнавання значення я звів до порівняння з еталоном. Порівняння відбувалося за різницею хешів зображень: чим менше різниця, тим вище ймовірність, що це саме те число. Наробив дуже багато еталонів всіх цифр (наприклад 50 шт цифри 3 з першого і другого розряду), захоплював наші позиції, нумерував, потім вручну сортував по папках згідно номіналу. І потім порівнював хеш в зсередини одного номінінала (тобто одиниці з одиницями і т.д.), щоб дізнатися, наскільки сильно несхожі один на одного однакові значення. Потім підмішували схожі по накресленням (наприклад, до 3 — 8) і знову вважав різницю. Це інформація була ключовою в точності визначення. Але як виявилося, були прикордонні значення, тобто іноді все-таки 3 і 8 і 9 плуталися хоч і не часто, але не приємно. Причиною цьому виявився напівпрозорий фон і дуже маленькі розміри самих цифр.
 
Довелося лізти в клієнт і змінювати стандартну панель пошкоджень на кастомний, на якій я в 2 рази збільшив шрифт, змінив колір фону, а так само повністю відключив прозорість. Провів тести з новою панеллю і, як слід було очікувати, точність розпізнавання зросла на порядок. Так само відмовився від інверсії кольору.
 
 Нова панель і числа
 
 
 
Зібрав весь код разом загорнув у цикл і поїхав, на відео в принципі те, що вийшло. Сам клієнт WoT після останнього оновлення став сильно гальмувати, при цьому під час лагів спідометр (в інтерфейсі) показує іноді зовсім неадекватні значення. Робота не ідеальна, але я результатом задоволений.
 
  
Для захоплення використовував Python Imaging Library (PIL) .
Для роботи з зображенням: OpenCV .
 
 Прошу вибачення за нерівний почерк, це моя перша стаття на Хабрі.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.