Как мы заменили спортивного скаута нейронной сетью

ztud_rxsshccb2jigzmixrjiud4.jpeg
Да, действительно, мы смогли заменить нейронной сетью спортивного скаута и стали автоматически собирать данные об игре. И теперь знаем о спортивном состязании больше присутствующего на нем зрителя, а иногда и судьи.
Мы (Constanta) специализируемся на разработке букмекерских IT-продуктов: мобильных приложений, сайтов и в последнее время развиваем проекты в области компьютерного зрения и машинного обучения. Об одном из них и пойдет речь.

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

qghdynncjpu6vpd5ghocwiifhl0.jpeg
Мне нужны координаты и скорости всех твоих шаров и твоего кия.

Заметим, что при анализе многих спортивных игр для правильного определения результата необходимо безошибочно отследить цепочку событий. Отсюда вытекают высокие требования к надежности работы компонентов, отвечающих за определение этих событий. Поясним на простом примере: если в бильярде в среднем игроки закатывают все шары в лузы за 20 ударов, то при надежности определения исхода удара 99% вероятность определить победителя в розыгрыше составляет всего около 82% (0,9920≈0,817). Матч продолжается до пяти побед одного из игроков, то есть всего происходит от 5 до 9 розыгрышей, в среднем 7. Таким образом, в среднем при такой надежности определения событий правильный результат матча получается с вероятностью всего лишь около 24% (0,8177≈0,24). А ведь изначально вероятность ошибки составляла лишь 1%!

Пул «девятка»


Из всего многообразия бильярдных игр рассмотрим Пул-9. В розыгрыше побеждает игрок, битком закативший шар с номером 9 в лузу. Изначально «девятка» располагается в центре ромба из цветных шаров. Прицельным шаром, по которому должен ударить биток, является шар с наименьшим номером из имеющихся на столе. Если игрок не смог забить в результате удара ни один цветной шар или совершил фол, например не попал по прицельному шару или забил биток в лузу, ход переходит к оппоненту. Чтобы правильно засчитать очко, необходимо определять попадания шаров в лузы и все события, приводящие к смене игрока.

Компьютерное зрение


Для начала расскажем о том, как нейронная сеть получает данные. Входной информационный поток — видеотрансляция с одной камеры, расположенной над столом и снимающей с частотой 60 кадров в секунду.

axcnl1zhzdougqtqwpznd3qxuo4.jpeg
Пример кадра видеопотока, обрабатываемого системой.

Ключевой этап обработки видеопотока нейронной сетью — семантическая сегментация. Это классическая задача компьютерного зрения, состоящая в том, что алгоритм должен отнести пиксели изображения к одному или нескольким классам. Проще говоря, на видеокадрах необходимо определить, что есть что. Нейронная сеть выдает «маски», выделяя пиксели, относящиеся, например, к шару или игроку. Пройдя через серию постпроцессинговых алгоритмов «маски» шаров превращаются в координаты. По ним после сглаживания фильтром для каждого шара определяются скорость и траектория движения. На этом этапе отслеживаются низкоуровневые, или промежуточные, события, такие как столкновения шаров между собой и с бортами стола. Полученные данные отправляются в модуль обработки правил, который реализует всю логику игры. Он в итоге и выдает конечному потребителю, т.е. букмекеру, высокоуровневые события: забивание шаров в лузы, фолы, переходы ходов и, собственно, результат игры.

magj32uxedtpgtk94cfgxvbw0rq.jpeg
Общая схема системы.

Для решения задачи в первую очередь необходимо найти местоположение стола на кадре и всех шаров на нем. Еще один важный участник действия — кий, именно он определяет направление удара и, соответственно, траекторию движения битка. Над столом наклоняются игроки, частично закрывая его от камеры. С точки зрения анализа игры они представляют собой «посторонние предметы», как и подставка для шаров, а также мобильные телефоны, перчатки, салфетки и прочие вещи, которые по воле игроков появляются на бортах стола. Таким образом, получается несколько целевых классов для семантической сегментации изображений: стол, его борта, лузы, кий, посторонние предметы и, разумеется, шары. При этом каждый шар представлен отдельным классом в зависимости от его цвета.

Для семантической сегментации используется полностью сверточная нейронная сеть с архитектурой LinkNet-34. Она относительно быстро работает и хорошо зарекомендовала себя в различных «боевых» задачах конкурсов по компьютерному зрению. Для определения перечисленного выше множества классов используется всего одна нейронная сеть, решающая все задачи компьютерного зрения.

nzqozgkrkq1mpwseqbycmzdde9g.png
Архитектура сети LinkNet-34 (см. arXiv).

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

Обучить нейронную сеть классифицировать пиксели можно на большом количестве примеров с соответствующими «масками». Для этого мы собрали множество видео, разделили на кадры, а отдел разметки вручную подготовил «маски» для них. В сложных случаях потребовались дополнительные наборы данных. Например, когда шар «ныряет» в лузу или стоит около нее рядом с бортом стола, на него падает тень, из-за которой цвета выглядят иначе. Или, когда игрок разбивает ромб, шары летят быстро по сложным траекториям, из-за чего их изображения смазываются. Если нейронная сеть «видела» немного таких примеров, корректная классификация будет затруднительна.

m0vefc1lfwo2epmmwyx7jemomsq.jpeg
Пример изображения и соответствующей ему разметки. Задача нейронной сети состоит в том, чтобы из входного изображение получать такие «маски».

Быстро, быстрее, еще быстрее…


Конечному потребителю данных информация нужна в реальном времени (а еще лучше — быстрее риал-тайм). Для ускорения работы нейронной сети применено несколько техник, таких как объединение пакетной нормализации с 2D-сверткой (BatchNorm Fusion), что позволяет получить эквивалентную сеть без нескольких слоев. Хороший результат дает также подготовка и загрузка нового кадра параллельно с обработкой предыдущего на видеокарте. Помимо этого, на gpu выполняется часть подготовительных операций с кадрами и постобработки «масок». Сократить суммарное время на обработку каждого кадра помогла даже простая идея — переносить результат работы сети с видеокарты в оперативную память после бинаризации в виде uint8 вместо получаемого из сети float32.

В результате семантическая сегментация одного кадра со всей требуемой пред- и постобработкой занимает в среднем всего 17 мс! А для работы системы достаточно лишь одной игровой видеокарты.

А было ли столкновение?


Координаты шаров мы определяем по «маскам», но предварительно нужно исключить то, что лишь напоминает шар, например круглые нашивки на футболках игроков. Тут в дело вступают эвристики: проверяется форма и размер шаров, их положение относительно прошлого, хорошо известного. Далее, если с «маской» все в порядке, для обработки берется ее центроид.

vvfosa3jtfm-6zlnedm7qva2sh4.jpeg
Игрок в бильярд в страшных снах разработчиков.

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

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

0fca2c43659097233268d665c93058a1.gif
Демонстрация сглаживания определения положения и скорости шаров фильтром Калмана.
Слева: Raw: результат прямого измерения, векторы у шаров соответствуют скорости, цифры — обозначают оценку величины скорости; UKF: результат работы фильтра.
Справа: пример сглаживания направления скорости шара фильтром Калмана. Синим цветом изображены результаты измерений, красным — результат фильтрации. Резкие скачки направления соответствуют столкновениям шара.

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

y9gtm61shyfy70r-9nhwibikhvo.jpeg

Шары во время удара перемещаются так быстро, что зачастую нет кадра, на котором видно непосредственно событие, например, столкновение шаров. Поэтому для всех типов взаимодействий (столкновение шаров между собой, с бортом или попадание в лузу) вначале строится список возможных событий. Критериев здесь два. Во-первых, критически близкое взаимное расположение шаров. При медленном перемещении возникает большая относительная погрешность в определении скорости и траектории, поэтому важно расстояние между взаимодействующими объектами. Во-вторых, при большой скорости движения шаров возможные события определяются по пересечению траекторий, полученных из динамической модели. Такой подход дает весьма приятный бонус: возможность немного заранее предсказать вероятное попадание шара в лузу.

aamnavf_fqqqxjflsw0hqwvz1-4.png
Последовательные кадры видеопотока при начальном разбитии ромба из шаров. Без модели, описывающей траектории шаров, определить, с каким шаром столкнулся биток, затруднительно.

Изменение направления и величины вектора скорости позволяет судить, что событие, а именно столкновение, произошло. В случае, когда шар закатился в лузу, он «пропадает». Но тут есть важный момент: необходимо использовать данные о его траектории и проверять, что шар был именно забит, а не исчез из поля зрения камеры из-за того, что над ним случайно оказалась рука игрока или иной предмет.

А если что-то пошло не так? Скажем, часть событий выпала из-за потери кадра или нависшей над столом фигуры игрока. Такие пропуски критичны для игровой логики. Спасает эвристическая система автокоррекции, повышающая устойчивость системы. Например, если определен удар по битку и падение прицельного шара в лузу, но при этом не зафиксировано столкновений битка и другие шары остались неподвижны, логично добавить столкновение битка с прицельным шаром.

Так мы играем или нет?


Шары катятся, сталкиваются, попадают в лузы… А идет ли на самом деле в этот момент игра? Или, напротив, все на столе кажется незыблемо… Значит игра остановилась? Правильный ответ на эти вопросы, вероятно, так же важен, как и определение столкновений. Когда игрок готовится к удару, обдумывает его, целится, движения нет. Но бывает и наоборот, в неигровые моменты жизнь на столе может идти весьма динамично: забитые шары перемещают из одной лузы в другую, биток могут катать по столу при его установке после фола, причем делают это в том числе кончиком кия (очень похоже на удар!). Если окончание текущего удара легко можно определить — после корректного удара все шары перестают двигаться, то с началом все не так однозначно. Конечно, можно обучить нейронную сеть обнаруживать события в видео, в том числе и настоящие удары кия по битку. А можно составить набор эвристик, которые анализируют положение и угол кия, траекторию и скорость его концов и траекторию битка после предполагаемого удара. Мы пошли вторым путем, и в результате получился очень быстрый и надежный алгоритм, определяющий текущее состояние игры.

72c2e27808d8e45a89cce95c6997e475.gif
Система пытается понять, началась игра или нет.

И кто в итоге выиграл?


Все данные о низкоуровневых событиях (удар по битку, положения и столкновения шаров, попадания в лузы) отправляются в модуль, который по их последовательности определяет, что произошел фол или корректное падение шара в лузу, переход хода или окончание игры. Беспристрастный модуль ведет счет и объявляет победителя. Особенность его в том, что он работает без всяких автокоррекций и эвристик, просто формально применяя правила игры. Блок с правилами можно целиком заменить, что позволяет без существенного вмешательства в систему адаптировать ее к локальным правилам турнира или использовать для обработки других видов бильярдных игр.
Как беспилотные автомобили до сих пор полностью не избавились от инженера-испытателя в салоне, который следит за безопасностью, так и наш модуль правил позволяет осуществлять внешнее ручное управление через web-интерфейс. Вмешательство может потребоваться, если автоматическая система ошибется. Кроме того, необходим ручной ввод отсутствующих в видеопотоке данных: о начинающем игроке, специальных ударах, которые объявляются по ходу игры голосом и т.п. Один человек потенциально может следить за несколькими играми одновременно.

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


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

0fc597d67de6a85ab650db9a6b64bc85.gif
В настоящее время система работает и используется букмекером. В дальнейшем планируется усовершенствовать систему, в том числе добавить автоматическую идентификацию игроков, автоматическое определение результатов розыгрыша первого удара.


Техническая визуализация того, как работает система. Шар около «Cue ball» обозначает с каким первым шаром столкнулся биток; «State» — состояние системы: может быть «wait» — пока игрок не совершил удар и «play» — пока шары находятся в двжении; «Player» — текущий игрок; цифры около шаров обозначают оценку скорости в см/с.

© Habrahabr.ru