Стабилизация видео с движущейся камеры, или как перевести всё в неподвижную систему координат
- суббота, 22 августа 2020 г. в 00:30:05
Сейчас возможности Computer Vision (CV) полностью перекраивают ландшафт рынка Public Safety solutions. В то время, как традиционными системами видеонаблюдения уже не просто никого не удивить, а странно не найти её в любом общественном месте, использование ИИ в данной области всё ещё вновинку.
Как R&D департамент Oxagile, мы исследуем применение CV для различных бизнес-задач в сфере Public safety. В этом посте мы предлагаем вариант перевода видео с движущейся камеры в неподвижную систему координат для последующего анализа.
Допустим у нас есть какое-то видео и мы хотим построить для него неподвижную систему координат, чтобы оценивать расположение объектов относительно друг друга.
Зачем это нужно? Очень часто в задачах public surveillance видео, которое нужно анализировать, снято на движущуюся камеру. Из-за этого возникает несколько проблем в определении положения объектов относительно друг друга:
Рисунок 1- Одинаковые объекты имеют разные координаты из-за движения камеры
Для того, чтобы построить неподвижную систему координат необходимо:
Рисунок 2-проективное преобразование
Рисунок 3-matching visualization
Гомография характеризуется своей матрицей Н:
Используя эту матрицу, можно описать изменение координат одного объекта между двумя фреймами, если это изменение вызванно движением камеры. Получить из (x,y) новые координаты (x',y') можно следующим образом:
или в матричнов виде:
Давайте рассмотрим работу алгоритма на примере обработки k-ого фрейма.
Пусть есть N последовательных фреймов — (f1,..., fN). В качестве начала координат зафиксируем левый верхний угол первого фрейма. Определим matching points как точки, которые связывают fk и fk-1.
Введем следующие обозначения:
О — начало координат;
(Xk, Yk)=((x1k, y1k),…, (xnk, ynk)) – координаты n matching points;
(X'k, Y'k) =((x'1k, y'1k),…, (x'nk, y'nk)) – координаты n matching points в неподвижной системе координат;
(X''k, Y''k) =((x''1k, y''1k),…, (x''nk, y''nk)) – k — координаты n matching points в систееме координат, где ее началом является левый верхний угол fk-1.
Hk – матрица гомографии, которая описывает движение камеры между fk-1 и fk.
Считаем, что есть набор общих точек для двух фреймов и их оригинальные координаты относительно фрейма.
Необходимо из (Xk, Yk) получить (X'k, Y'k). Найти матрицу гомографии между f1 и fk не всегда возможно, т.к. за время движения камеры сцена могла кардинально поменяться и фреймы могут не содержать общих объектов. Поэтому найдем матрицу перехода Hk.
Считаем, что уже найдена последовательность таких матриц для предыдущих фреймов (H1,…, Hk-1). Если матрица Hk будет описывать изменения между координатми (Xk-1, Yk-1) и (Xk, Yk), то мы не учтем, что взаимное расположение объектов могло сильно измениться с начала видео.
Рассмотрим рисунок 3:
Рисунок 3 — пример движения камеры, при котором произошло масштабирование объектов
Здесь показан пример такого движения камеры, при котором происходит масштабирование объектов. Если на текущем фрейме координата объекта изменилась на a пискелей:
x1k = x1k-1 — a, это не значит, что он переместился на a координат в неподвижной системе: x'1k = x1k — a, это очень хорошо видно на рисунке 3. Поэтому, при поиске преобразования между двумя фреймами нужно учесть все трансформации, которые произошли с первого кадра.
Как это сделать?
Описать передвижение камеры между всеми предыдущими парами последовательных фреймов можно с помощью известных матриц гомографии (H1,…, Hk-1). Но необходимо найти такую суперпозицию этих матриц, которая будет описывать полное движение от 1 до k-1 кадра и позволит найти координаты mathcing points на fk-1 в неподвижной системе. Если посмотреть на формулу (1), становится понятно, что такая суперпозиция — это перемножение матриц всех предыдущих переходов.
Таким образом, для того, чтобы найти матрицу гомографии, описывающую движение камеры между fk-1 и fk, необходимо: умножить оригинальные координаты (Xk-1, Yk-1) и (Xk, Yk) на суперпозицию матриц (формула (2)), и уже для полученных координат (X'k-1, Y'k-1) и (X''k, Y''k) искать матрицу Hk. В результате, получим преобразование, которое переведет координаты объекта на этом фрейме (x1k, y1k) в координаты этого объекта относительно начала координат (x'1k, y'1k).
Но есть одна проблема: дело в том, что особые точки могут цепляться за подвижные объекты (за людей, машины, и т.д. ), и из-за этого матрица гомографии может быть посчитана неточно и описывать не только движение камеры, но и движение людей. Поэтому необходимо отфильтровывать точки.
Разработан следующий вариант фильтрации:
Остались только точки, которые находятся на неподвижных объектах. Именно их и используем при подсчете матрицы гомографии Н.
Но найденная на грязных точках матрица будет описывать не только движение камеры, но и частично движение движущихся объектов. И, следовательно, координаты объектов, движение которых будет описано достаточно точно, не изменятся и попадут в группу с неподвижными объектами. Tаким образом, матрица гомографии может быть посчитана неточно. В связи с этим, в качестве улучшения фильтрации рассматривается внедрение motion video segmentation.
А теперь перейдем к реализации всего описанного выше.
Вот здесь можно взять проект, запустить его на своем видео и получить неподвижную систему координат.
Проект состоит из трех файлов
evenvizion_component.py
Реализация самого алгоритма неподвижной системы координат и всех основных результатов, происходит в файле evenvizion_component.py. На вход скрипт принимает путь к видео, на выходе возвращает json с матрицами гомографии, описывающими перемещение между fk-1 и fk. Важно, в json записаны матрицы, описывающие перемещение только между двумя фреймами. Чтобы получить координаты в неподвижной системе, необходимо сначала получить суперпозицию матриц, о которой было рассказано выше.
Если же вы хотите пересчитать координаты каких-то определенных объектов, то необходимо указать путь к json файлу в --path_to_original_coordinate с этими объектами и вы получите recalculated_coordinates.json с пересчитанными координатами, а также их визуализацию.
Формат json файла:
{"frame_no": [{"x1": x coordinate, "y1": y coordinate}, ...], ...}
Таким образом после работы evenvizion_component.py скрипта, вы получаете 3 визуализации (управлять matching and heatmap визуализациями можно с помощью аргументов --show_matches и --visualize_fixed_coordinate_system соответственно).
evenvizion_visualization.py и compare_evenvizion_with_original_video.py используются исключительно для получения визуализаций работы компонента.
Больше про аргументы и константы Вы можете прочитать в README.
Для демонстрации и проверки работы алгоритма было разработано несколько визуализаций, чуть подробнее о них.
Визуализация matching points — matching visualization:
Рисунок 5 — matching visualization
Ее описание приводилось выше.
Для демонстрации того, как работает именно неподвижная система координат была разработана следующая визуализация (heatmap visualization):
Рисунок 6 — heatmap visualization
В данной визуализации фрейм разбивается на 20 прямоугольников, и на каждом кадре координаты центра прямоугольника пересчитываются в новой системе координат, то есть можно посмотреть как неподвижные объекты сохраняют свои координаты по мере движения камеры. Здесь используется окрашивание фрейма в зависимости от того, насколько далеко от начала координат расположен объект. Цвет окрашивания определяется следующим образом: вычисляется расстояние от объекта до начала координат r =sqrt(x2+y2), нормализуется с помощью агрумента heatmap_constant и в зависимости от полученного значения окрашивается в определенный цвет, диапазон цветов: 0 — синий, 1 — красный.
Рисунок 7 — fixed_coordinate_system_visualization
Если Вы указали json с координатами объектов, которые необхомо пересчитать, вы получите fixed_coordinate_system_visualization (рисунок 7)
evenvizion_visualization.py и compare_evenvizion_with_original_video.py используются для визуализации стабилизации камеры, и покрывают только перемещение камеры (масштабирование и поворот такая визуализация не учитывает). На рисунках 8 и 9 представлены результаты работы этих скриптов соотвественно
Рисунок 8 — visualize_camera_stabilization
Рисунок 9 — original_video_with_EvenVizion
N/a координаты. Когда matching points цепляются за подвижные объекты, то есть фильтрация работает недостаточно хорошо, и когда угол поворота камеры больеш 90 градусов, координаты не могут быть определены. В качетсве решения первой проблемы в данный момент рассматривается внедрение video motion segmentation, чтобы, учитывая характер движения, отделять static points от motion points. А в качетсве решения второй — переход к цилиндрической системе координат.
Матрица Н не определена. Для поиска гомографии необходимо минимум 4 matching points, но бывают случаи, когда 4 точки невозможно найти, и матрицы гомографии Н=None. В данной версии алгоритма такие случаи обрабатываются следующим образом: если аргумент none_H_processing стоит True, то считаем что матрца предыдущего фрейма будет соответствовать матрице текущего: Hk=Hk-1. Если же False, то H — единичная матрица, то есть никакого движения на данном кадре не было. Необходимо продумать более качетсвенную обработку таких ситуаций.
Погрешность. Имеет место погрешность в координатах. Некачественно полученная матрица гомографии искажает результаты пересчета координат. Причины:
Таким образом, получаем компонент, который позволяет оценить реальное положение объектов относительно друг друга, перевести координаты объекта в неподвижную систему относительно фрейма. Т.к. в данном решении основное — оценить преобразование плоскостей, используя ключевые точки, то, как было показано выше, задача может быть решена даже в плохих условиях съемки (резкое движение камеры, сложные погодные условия, съемки в темное время суток и т.д.).