В прошлом году я развлекался треккингом волейбольного мяча, используя удаление фона OpenCV с анализом траекторий и даже сделал сервис, который на основе этой информации вырезает скучные моменты из игры.
Основным фидбеком было - что за каменный век использовать олдскульные технологии, обучаешь нейросеть и погнали. Я пробовал, но не взлетело - очень часто мяч настолько размыт, что его даже человеческим глазом не отличить от случайной кляксы, и даже простой бинарный классификатор не дает стабильных результатов, чего уже говорить о детекторах и прочих YOLO.
В общем, я это дело подзабросил, но вот весной завел себе дрон и конечно же первым делом приспособил его для волейбольных съемок. Если поднять его на нужную высоту (12-15 метров), в кадр влезает вся площадка, что дает прямо неограниченные возможности для анализа.
Камера дрона держится на гимбале, который гасит колебания аппарата и на выходе получается стабильная картинка. На эту картинку я и направил свой алгоритм распознавания, но ...все оказалось не так то просто.
Стационарнось картинки с дрона на самом деле обманчива - тряска аппарата не проходит бесследно и хотя гимбал отлично делает свою работу, результат способен обмануть человека, но не бездушную машину - тряска вызывает небольшие колебания в цвете пикселей, и этих колебаний достаточно чтобы сбить с толку алгоритмы распознавания фона.
Для сравнения - похожая подача при старом подходе выглядит вот так:
Делать нечего, придется искать другие подходы. У нас есть OpenCV, так что далеко идти все равно не придется. Вместо фона выделяем границы помощью фильтра Канни - и у нас есть черно-белый скетч для дальнейшего разбора.
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
gray = cv.GaussianBlur(gray, (5, 5),0)
mask = cv.Canny(gray, 50, 100)
Если натравить на него детектор контуров - все прекрасно работает, мяч удается зацепить. Дальше подключается детектор траекторий и процесс идет как и в основном алгоритме.
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)
И опять же для сравнения - тот же фрагмент с неподвижной камеры с границами:
Как видно, палка имеет два конца - на трясущемся дроне Канни-фильтр дает лучшие результаты, а на статичной камере - генерит лишний фон, на котором теряется мяч.
Но что будет, если эти два подхода совместить? Для видео с дрона Канни сначала оставит только нужные фигуры, а затем, можно удалить фон.
Получается картинка не без шума, но его можно уже фильтровать, и мяч уже видно.
Результат - гораздо лучше, шума меньше (но есть еще) и траектория мяча распознается достаточно четко.
Aspos
Доверьтесь магии и подавайте в нейросетку N последних кадров + M последних распознанных позиций мяча.
Тогда сможете определять мяч с любого ракурса на (практически) любом фоне и в разных условиях освещения.
Stantin Автор
Можно поподробнее? Я пробовал обучать классификатор, но он работал крайне ненадежно
Aspos
Две нейросетки: одна предсказывает где может оказаться мяч на следующем кадре и другая собственно ищет мяч на кадре.
Первой сетке на вход подаёте M пар двумерных координат где мяч был ранее разпознан.
На выходе ждёте плоский массив типа 100x100 где мяч должен быть. Типа тепловой карты вероятностей.
Эту сетку можно тренировать на синтетических данных.
Вторую сетку делаете как YOLO4 только на вход подаёте N последних кадров и отдельно ту 100x100 картинку. Как вариант можно в каждый кадр добавить четвёртый цвет — 100x100 карту.
На выходе получаете координаты мяча.
Эту сетку придётся тренировать на кастомном датасете. Придётся делать видео людей разной степени волосатости играющих на разных площадках и вручную размечать летящий мяч.
Как вы глазами ищете самолёт в небе: сначала шарите по всей картинге пока не найдёте его, потом мозг начинает предсказывать где самолёт должен быть и даже если он скроется на секунду за листвой всё равно сразу распознаете его как только появится.
Предсказание будущей координаты мяча резко упрощает задачу распознавания картинки.
Stantin Автор
>>Первой сетке на вход подаёте M пар двумерных координат где мяч был ранее разпознан
У меня уже есть параболическая траектория, это все считается без нейросети, но на порядки быстрее.
>>Вторую сетку делаете как YOLO4
В основе YOLO все равно лежит бинарный классификатор, если он не работает, то про детектор нет смысла говорить
>>Как вы глазами ищете самолёт в небе…
Воот, мозг знает какой то контекст, на основании которого он может распознать самолет. Нейросеть контекста не знает и любой кусок серого цвета может быть принят за самолет (и человек тоже не отличит, если не знает контекста)
Aspos
Может оказаться так, что нейросетка может понять из контекста, скажем, поля и сетки поле вероятностей где мяч может оказаться.
Подсвечивая кадр этой тепловой картой вероятностей можно резко улучшить результативность YOLO.
Некоторые не весь HD кадр в YOLO пихают, а вырезанную область вокруг предполагаемых координат летящего объекта.
Stantin Автор
А не подскажете готовые эксперименты с кодом на подобную тему? На словах оно гладко, а когда я начинал копать примеры, так все время чего-то не хватало
Aspos
С открытым кодом работ очень не много. Навскидку так вспомню только работу греков одних которые камерами комаров детектили. Там целый каскад нейросеток был: одна нейросетка искала движение, другая предсказывала координаты уже ведомой цели, потом YOLO и в конце клафицикация урезаной картинки.
Stantin Автор
Ссылкой не поделитесь?
Aspos
Вот такие есть ссылки в закладках:
sci-hub.hkvisa.net/10.3390/s19122785
sci-hub.hkvisa.net/10.3390/s18051489
Мне они помогли в свое время.
pbatanov
Помимо нейросеток я бы предложил и более «дубовые» подходы, но идея все та же — зная положение мяча на N предыдущих кадрах, можно не пытаться искать его на всем изображении, а искать его в достаточно «ограниченном подходе. Можно почитать на эту тему например вот en.wikipedia.org/wiki/Particle_filter
С учетом того, что у вас в примере очень хорошо отслеживается большая часть положений это поможет избежать откровенных выбросов, которые проскакивают в промежутке.
Stantin Автор
Спасибо, изучу.
Про ваш диплом — есть статья и код в открытом доступе?
pbatanov
Не уверен что найду сходу исходники, статью можно найти здесь
DanilinS
Главное в таких системах — отсутствие лысых игроков в поле зрения камеры. https://habr.com/ru/news/t/526228/
Stantin Автор
Есть такая проблема, причем не обязательно с лысыми
mSnus
А вы не пробовали сначала подавить шумы?
Stantin Автор
Тут такая штука — нельзя 100% подавить шумы и оставить только мяч. Он неминуемо давится вместе в шумами и в более жестком режиме короткие траектории идут под острел. Приходится искать баланс.
mSnus
![image]()
Stantin Автор
Тень отсекается, если выбрасывать вогнутые параболы.
Вообще в шумоподавлении есть несколько уровней:
— геометрия, где отсекаются кандидаты нестандартных форм и размеров
— движение, где отсекаются случайные и статические кандидаты
— траектории, где отсекаются непараболические или неправильно ориентированные траектории
— семантика собственно волейбола (TBD) где отсекаются траектории, невозможные в игре
mSnus
мне кажется, с тенью можно просто отбрасывать тот из двух объектов, что ниже, нет?
с шумодавом — очень помогает ресайз вниз вдвое(и обратно, если надо) — дёшево и неплохо
Stantin Автор
Отдельной логики обработки тени сейчас нет, может быть удастся обойтись без этого.
Ресайз вдвое — легко режет и мяч, особенно когда он на дальнем плане и фон не сильно контрастный.