Распознавание мяча в волейболе с OpenCV и Tensorflow

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.
После первого опыта распознавания спортивных движений у меня зачесались руки сделать что-нибудь еще в этом направлении. Домашняя физкультура уже казалась слишком мелкой целью, так что я замахнулся на игровые виды спорта.

Применение искусственного интеллекта к спорту — недавняя тенденция, но уже есть интересные материалы:

  • Баскетбол
  • Теннис
  • Волейбол

Лично мне ближе всего волейбольная тема. По ссылке выше находится сайт одного австрийского института, где занимаются разбором игры местной любительской лиги. Есть несколько документов на почитать, но что более важно — опубликован видео-датасет, который можно свободно использовать.

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

Распознавание движущегося мяча (aka ball tracking) — довольно популярная тема и про нее написано немало статей. Однако, в основном это демо-информация про возможности технологий, чем про применение в реальной жизни (и в реальных игровых видах спорта).

Действительно, одно дело распознать ярко-зеленый (или красный) мяч в метре от камеры и совсем другое — пестрый, крохотный (с общепринятых ракурсов), быстро двигающийся и сливающийся с фоном мяч в игре.

Я поигрался с разными видео, но в этой статье я использовал видео из указанной выше австрийской лиги. Причина — те самые авторские права. Австрийцы выложили свои записи в открытый доступ именно для таких гиков, а вот видео с Youtube или еще откуда — как правило принадлежат какому-нибудь каналу и их использование и упоминание наверное может повлечь какие-нибудь санкции.

Австрийское видео имеет свои особенности. Главных деталей три:

  1. статичная камера за кортом
  2. Уровень игры. Уровень игры непосредственно влияет на скорость мяча, ибо у серьезных людей мяч часто можно увидеть только на замедленном повторе
  3. Цвет мяча, желто-синий не сильно контрастирует с цветом пола, что делает бессмысленными практически все подходы через цветовые фильтры

Начал я с того, что мяч — движется, а значит его надо искать среди движущихся объектов.
Такие объекты будем искать с помощью функций удаления фона OpenCV, добавив к ним размытие и преобразование в бинарную маску:

    mask = backSub.apply(frame)
    mask = cv.dilate(mask, None)
    mask = cv.GaussianBlur(mask, (15, 15),0)
    ret,mask = cv.threshold(mask,0,255,cv.THRESH_BINARY | cv.THRESH_OTSU)

Таким образом вот эта, например, картинка:



Превращается в такую маску:



В данном случае мяч наверху и обнаружить его довольно просто (человеческим взглядом). Переводя это на язык OpenCV — нам нужен контур, похожий на мяч, допустим еще, что это самый высокий контур на картинке.

Это коненчно не всегда так. Например, здесь верхний контур оказался плечом судьи:



Однако верхние контуры — хороший источник начальных данных от которых мы и будем отталкиваться. Собрав несколько сотен, я озаботился классификатором, который сможет отличить мяч от не-мяча.

Датасет верхнего контура выглядит разнопланово:



Но с точки зрения нейросетей представляет собой не более чем бинарную классификацию цветных картинок. Таким образом за основу модели я взял известную задачу Котики-против-Собак.

Вариантов реализации — миллион, самая популярная архитектура — VGG, хорошо описана в этой статье блога Keras.

Проблема в том, что картинки у меня на входе мелкие, поэтому десяток сверточных слоев тут не пойдет, поэтому пришлось выкручиться всего парой сверток и парой FC-слоев.

   model = Sequential([
        Convolution2D(32,(3,3), activation='relu', input_shape=input_shape),
        MaxPooling2D(),
        Convolution2D(64,(3,3), activation='relu'),
        MaxPooling2D(),
        Flatten(),
        Dense(64, activation='relu'),
        Dropout(0.1),
        Dense(2, activation='softmax')
      ])
    model.compile(loss="categorical_crossentropy", optimizer=SGD(lr=0.01), metrics=["accuracy"])

Как я ни крутил модель, добиться лучшег чем 20% ложно-отрицательных и 30% ложно-положительных не удалось.

Это лучше чем ничего, но конечно не достаточно.
Если применить сеть в игре, мяч как правило распознается, но появляется немало ложных мячей.



Ложные мячи бывают двух типов: они внезапно расцветают в разных частях площадки ненадолго или же нейросеть стабильно ошибается, принимая, например, за мяч голову судьи на вышке.

Но с этим надо что-то делать и на помощь приходит идея траекторий. Суть в том, что мяч в волейболе не ведет себя случайным образом, а движется по параболическим или прямым траекториям. Для простоты я использовал только прямые, но параболы очень перспективны в плане достоверности.

В общем, на коленке пришлось сделать некий фреймворк управления траекториями.

Вот записанные траектории за розыгрыш:


(cиним — кандидаты в траектории, зеленым — статические пятна, серым — случайные).

В этой картинке нас интересуют только синие траектории. По построению, они состоят не менее чем из трех точек и имеют направление. Направление дает большие возможности — оно позволяет предсказать, где будет мяч в следующий момент и если даже мы его не нашли — какое-то время можно пережить за счет предсказанной траектории.

Добавив еще несколько небольших деталей (например, длинные траектории имеют приоритет и могут быть предсказаны, если вдруг прервались без явного преемника), получаем вполне реалистичные розыгрыши:



Может быть можно еще выжать какие-то улучшения с помощью компьютерного зрения, однако более перспективным вариантом видится предсказание траекторий через баллистику, и следующим шагом — через смену состояний в розыгрыше (подача, прием, пас).

И в завершение еще несколько ссылок на подобные изыскания:

  • Фрагмент женского волейбола с треккингом мяча
  • Курсовая каких-то студентов с фрагментами видео и интервью
  • Статья в MIT про треккинг мяча в разных видах спорта
  • Репо на Гитхабе
Источник: https://habr.com/ru/post/505672/


Интересные статьи

Интересные статьи

SDR-приемник, даже самый дешёвый, является весьма высокочувствительным приборчиком. Если добавить к нему специальную антенну и OpenCV, то можно будет не только привычно слушать эфир, но и пос...
Не так давно перед нами стояла задача найти и извлечь печати с документов. Зачем? Например, для проверки наличия печатей в договорах с двух сторон (участников договора). У нас в закромах уже бы...
Приступая к животрепещущей теме резервного копирования на «Битрикс», прежде всего хотелось бы поблагодарить разработчиков, реализовавших автоматическое резервное копирование в облачное хранилище в вер...
Сиамская нейросеть — один из простейших и наиболее популярных алгоритмов однократного обучения. Методики, при которой для каждого класса берётся лишь по одному учебному примеру. Таким образом...
OpenCV — библиотека, разработанная для проектов по компьютерному зрению. Ей уже около 20 лет. Я использовал ее еще в колледже и до сих пор применяю для своих проектов на C++ и Python, поскольку...