Компьютерное зрение: как обучить машину «видеть» игру

Компьютерное зрение — это ключ к созданию ИИ, способного ориентироваться в визуальной среде. Если мы хотим, чтобы бот «играл» в гоночную игру (например, Disney Speedstorm), ему нужно в реальном времени распознавать трассу, соперников, бусты и препятствия на экране — так же, как это делает человек.

Как это работает

Всё начинается с захвата изображения (в нашем случае — скриншотов экрана), которые подаются в нейросеть, обученную искать определённые объекты. Этот процесс состоит из нескольких ключевых этапов:

1. Сбор и разметка данных

Мы вручную сохраняем кадры из игры и размечаем на них:

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

Для разметки используется формат YOLO: каждый объект описывается строкой с классом и координатами (нормализованными). Пример формата

3 0.497958 0.703341 0.276961 0.472041
1 0.265931 0.431009 0.082516 0.075527
0 0.374592 0.573348 0.375000 0.389252

ID класса, смещение по горизонтали и вертикале, ширина и высота объекта. Позже опишу процесс.

2. Обучение модели YOLO

YOLO (You Only Look Once) — один из самых быстрых и точных алгоритмов object detection. Мы обучаем его на размеченных кадрах, чтобы он научился предсказывать:

  • где на экране находится объект,
  • что это за объект (класс),
  • насколько уверена модель в своём предсказании.

3. Распознавание в реальном времени

После обучения модель можно подключить прямо к скрипту захвата экрана. Каждый кадр с экрана подаётся в модель, которая возвращает:

  • координаты объектов (bounding boxes),
  • названия классов (track, boost и т.д.),
  • confidence — насколько уверенно это предсказание.

Почему именно YOLO: быстро, точно, в реальном времени

Для задачи, где нужно распознавать объекты на экране и принимать решения сразу, критически важны скорость и точность. Именно поэтому я выбрал YOLO — одну из самых популярных моделей компьютерного зрения для object detection (обнаружения объектов).

Что такое YOLO

YOLO (You Only Look Once) — это однопроходная (single-shot) нейросеть, которая всего за один прогон по изображению:

  • определяет где находятся объекты (bounding boxes),
  • определяет что это за объекты (классы),
  • и делает это в реальном времени (на CPU или GPU).

YOLO — это одновременный детектор и классификатор, в отличие от старых подходов вроде R-CNN, которые сначала ищут объекты, а потом классифицируют.

Как работает YOLO — по сути

  1. Вход: модель получает изображение (например, 640×640).
  2. Она разбивает его на сетку (например, 80×80 клеток).
  3. Каждая клетка делает несколько предсказаний:
    • координаты возможного объекта,
    • класс (например: трасса, буст, соперник),
    • и confidence (уверенность).
  4. Все предсказания собираются, фильтруются по порогу уверенности и выводятся в виде прямоугольников с подписями.

Модель обучается таким образом, чтобы минимизировать ошибку в координатах и классе одновременно.

Тип архитектуры: сверточная сеть (CNN)

YOLO построена на Convolutional Neural Network (CNN), специально адаптированной для:

  • выделения признаков (features) на изображении,
  • объединения информации на разных масштабах (через FPN/Neck),
  • быстрого предсказания bounding box’ов.

В частности, YOLOv8 использует C2f-блоки и легкую “голову” (head) — всё это делает её быстрее и легче, чем многие аналоги.

Почему YOLO — лучший выбор для гейм-бота

КритерийYOLOv8
СкоростьДо 60 FPS на средних GPU или CPU
ТочностьmAP > 50–60% при хорошем датасете
ПростотаПростое API (Ultralytics)
УниверсальностьРаботает с изображениями, видео, экраном

Альтернативы (и почему не они)

  • Faster R-CNN — слишком медленно для real-time
  • EfficientDet — точная, но сложнее в запуске и медленнее
  • YOLOv5/YOLOv6 — хороши, но YOLOv8 проще, быстрее и официально поддерживается Ultralytics

Практика

Прежде всего – надо нарезать кадров игры на которых будем учить сеть. С этой целью был написан такой пайтон код

import mss
import numpy as np
import cv2

def main():
    monitor = {"top": 0, "left": 0, "width": 1920, "height": 1080}
    i=0

    with mss.mss() as sct:
        while True:
            screenshot = sct.grab(monitor)
            frame = np.array(screenshot)
            frame = cv2.cvtColor(frame, cv2.COLOR_BGRA2BGR)

            if i % 50 == 0:
                cv2.imwrite(f"data/frame_{i:04d}.jpg", frame)

            i+=1

if __name__ == "__main__":
    main()

Шаг второй – разметить кадры и сформировать датасет для обучения: я использовал этот сайт. В конце экспортировал текстовые файлы в YOLO формате.

Третий шаг – обучение сети. Для этой цели был набросан скрипт

from ultralytics import YOLO

model = YOLO("yolov8n.pt") 

model.train(
    data="config.yaml",  
    epochs=50,
    imgsz=1920,
    batch=8,
    name="track_bot_model"
)

model_path = model.ckpt_path or "runs/detect/track_bot_model/weights/best.pt"

config.yaml это файл с описанием файловой структуры датасета и имен обьектов

path: datasets
train: images/train
val: images/val

nc: 4
names: ['track', 'opponent', 'boost','me']

epochs это количество итераций в цикле обучения. Каждая эпоха составляет свою карту весов и в конце выбирается лучшая карта. imgsz размер картинки, к которому будет приведен кадр внутри сети и batch – как я понял, количество картинок, что будут объединены в один пакет для кормления сети.

Результат

при обучении мы получим файл best.pt с весами ориентируясь на который будут делаться прогнозы о нахождении той или иной фигуры на кадре. По причине недостаточно мощного железа мне пришлось сохранять кадры в папку и читать их оттуда. Скрипт для создания прогнозов получился таким

from ultralytics import YOLO
import time

model = YOLO("runs/detect/track_bot_model/weights/best.pt")

results = model.predict(
    source='data',           
    conf=0.05,
    save=True,              
    save_txt=True,          
    project="outputs",      
    name="batch_run",     
    exist_ok=True        
)

результатом будут кадры вроде

Область, имя обьекта, вероятность предсказания…