Обробка «відео 360», очищення зображення: алгоритм і його реалізація на C#

Останнім часом, у зв'язку з зростаючим трендом віртуальної реальності, все більш актуальними стають зйомка/монтаж/обробка відео в форматі відео 360».

У даній статті я хочу розповісти про один експеримент по обробці відео 360», який добре ілюструє деякі особливості такого формату. Забігаючи вперед скажу, що експеримент вимагав реалізації нескладного алгоритму і, звичайно, без написання програми не обійшлося.

image

Що таке «відео 360»?
В рамках проекту Університету ІТМО Video360Production.com ми не тільки знімаємо відео 360, але і попутно вирішуємо цілий «букет» супутніх завдань — спеціалізована обробка панорамного відео, розробка інтерактивних додатків для шоломів віртуальної реальності і багато іншого.

«Відео 360» (панорамне відео), створюється спеціальним чином — кілька відео камер дивляться «на всі боки», потім потоки синхронізуються і зшиваються в одну суцільну картинку. Одним із стандартів панорамного відео є сферична розгортка — зшита сфера 360*360 розгортається на кадр із співвідношенням сторін 2:1 (эквидистантная розгортка), що дозволяє кодувати панорамне відео у звичному H. 264 і зберігати в цілком смотрибельном вигляді.

При перегляді відео 360» можна крутити мишкою або пальцем (на смартфон, планшет), панорамне відео підтримує YouTube і Facebook. Особливо ефектно вона виглядає в гарнітурах віртуальної реальності — Oculus Rift, Samsung Gear VR, Google Cardboard та ін

Ось так, наприклад, виглядає концерт групи «Браво» у форматі відео 360»:



Панорамне відео може бути знято на відео камеру, але і отримано з 3D-движків, як, наприклад, трейлер «WARCRAFT: SKIES OF AZEROTH»:



Постановка завдання
Однією з типових завдань обробки відео є заміна зображення в програмах відео монтажу є відповідні інструменти, що дозволяють замінити статичне зображення або навіть динамічне. В останньому випадку використовується трекінг «за ключів», що дозволяє якісно і в (напів-)автоматично замінити заданий фрагмент зображення на деякий інший.
А як йде справа з «відео 360»? Практика показує, що все не так просто…

В якості експерименту я взяв ось таке відео, зібране з UnrealEngine у формат панорамного відео і поставив завдання, на перший погляд, нескладну — очистити всі банери, що висять вгорі над «доріжкою», по якій їде візок.

До речі, цей ролик добре знають усі, хто мав справу з Oculus Rift і атракціонами:



Завдання виявилося не з простих.

Які труднощі виникають при спробі трекінгу зображення в «відео 360»? Крім труднощів конкретного прикладу (швидкий рух вагонетки, складна текстура об'єктів) проявляється характерна особливість еквідистантно розгортки — нетипове спотворення зображення — «згинання» і розтягування по мірі наближення до нижній/верхній частині кадру. Воно і зрозуміло — верхня/нижня частина кадру, строго кажучи, відповідають полюсам сфери, розтягнутим на ширину кадру.

Ось як це виглядає:

image

Здалеку напис майже прямокутна, однак по мірі наближення починає закруглятися догори:

image

image

image

Коли вагонетка у самого банера, починається повне неподобство:

image

image

Із супутніх ускладнень, висока швидкість руху на окремих ділянках, через що зображення банера розмите:

image

Алгоритм
Використання стандартних засобів трекінгу (наприклад, в After Affects) для даних банерів не дає доброго результату — ключів виходить дуже багато, вони нестабільні, захопити зображення складно. З-за цього вставка білого тла (а точніше — фону кольору банера, він не ідеально білий) виходить неточно, в деяких випадках і зовсім повз. Вручну правити 7-15 ключів на кожному кадрі — пекельна завдання. Фактично, це покадрова реставрація ролика.

У зв'язку з цим виникла ідея оптимізувати даний процес. Дійсно, якщо подивитися на задачу очима програміста — банери повинні непогано розпізнаватися і цілком реально придумати нескладний алгоритм, який дозволив би їх «очистити». Також досить очевидно, що програму простіше зробити в інтерактивному стилі, щоб або вказувати алгоритмом стартову точку, або вказувати область пошуку.

Отже, після деяких експериментів, вийшла така послідовність дій:

  1. Переводимо відео в «пачку» зображень, у відповідності з частотою кадрів. Для даного ролика вийшов 1451 кадр JPG роздільною здатністю 4000*2000.
  2. Далі пишемо інтерактивну програму на C#/WPF, яка завантажує черговий кадр оригінального відео, у зазначеній області виконує пошук транспаранта, виділяє його межі і зафарбовує нутрощі вказаним кольором. У разі помилки у користувача повинна бути можливість поправити програму — змінивши межі робочої області, а також параметри алгоритму (потрібний колір, розмір шуканої області тощо). До того ж, програма повинна мати можливість ZOOM для роботи з дрібними деталями зображення.
  3. Якщо все добре, користувач зберігає кадр оброблений і переходить до наступного.
  4. З кадрів збирається підсумкове відео.

Зовнішній вигляд:

image

Програма містить наступні елементи:

1. У верхній частині відображається поточний кадр. На ньому, за допомогою червоної рамочки, можна позначити робочу область — де алгоритм буде виконувати пошук банера.
2. Знизу зліва — збільшений вигляд робочої області. Алгоритм починає працювати автоматично і відразу показує результат (очищений банер).

Розміри рамочки можна змінювати, що дозволяє робити збільшення і працювати навіть з дуже дрібними деталями:

image

3. Права частина — панель налаштувань, яка містить ім'я файлу, номер кадру, стрілки для переходу на наступний/попередній, опція «автозбереження при переході до наступного».

Width і Height — дозволяють регулювати ширину/висоту червоної рамочки
Delta, BlockLength — параметри алгоритму.

Алгоритм працює наступним чином:

1. В заданій рамочкою області починає шукати точки, що відрізняються від заданого «фоного» кольору банера не більше ніж на Delta. Delta можна змінювати, тим самим звужуючи або розширюючи кількість квітів.
2. Потім проводиться построковый аналіз і залишаються лише ті точки, які утворюють безперервні групи довжиною BlockLength, причому в кожному рядку по дві — початкова і кінцева (відмічені червоним):

image

Таким чином, формується межа банера потрібної товщини BlockLength, «зсередини» за фоновим точках.
3. Блоки з'єднуються прямими лініями з фоновим кольором (зафарбування банера, відзначено жовтим):

image

4. Вуаля!

З правильним налаштуванням значень за замовчуванням для Delta і BlockLength алгоритм працює просто чудово! Часто можна гортати кадри один за одним без будь-яких додаткових дій, іноді лише посуваючи рамку слідом за рухом банера по кадру. Іноді, можна уточнити параметри.

До речі, якщо їх виставити неправильно — тобто вибрати занадто великий розкид кольорів чи занадто маленьку довжину кордону, то почнуть зачіпатися зайві точки:

image

За допомогою даної програми я обробив всі банери в ролику приблизно за 1,5-2 години.

Висновки
Звичайно, дана задача є дуже приватної. Однак, на її прикладі добре видно характерні особливості «відео 360» — спотворення зображення, яке робить неможливим застосування стандартних засобів обробки відео.

Швидше за все, досить скоро з'являться плагіни, які будуть враховувати эквидистантную проекцію панорамного відео (до речі, бувають і інші проекції...) і прямо в рідному After Effects успішно справлятися з цією та іншими завданнями.

А поки що… доводиться винаходити. Сподіваюся, ця стаття буде комусь корисна і допоможе скоротити час/сили при вирішенні власних завдань.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.