На IVI пользователи выбирают кино для просмотра, ориентируясь в первую очередь на постер и название фильма. Обычно правообладатель предоставляет один постер для каждого фильма и сериала, но бывают ситуации, когда могут понадобиться дополнительные/альтернативные изображения. Их создание — трудоемкая задача, потому что с помощью этих изображений нужно передать содержимое контента. Чтобы упростить её, мы прибегаем к генерации синтетических постеров. В этой статье я немного приоткрою занавес и расскажу о том, как мы удаляем визуальный мусор в процессе создания постеров.
![Мы хотим видеть на постерах лица и не видеть субтитры и логотипы. Мы хотим видеть на постерах лица и не видеть субтитры и логотипы.](https://habrastorage.org/getpro/habr/upload_files/5f4/b33/916/5f4b3391697435327d83af23a8f52a0b.png)
Проанализировав множество фильмов, мы выбрали три типа наиболее часто встречающихся объектов, которые необходимо находить и обрезать:
чёрные грани;
текст (хардсабы);
логотипы.
Черные грани
Со стороны кажется, что нет ничего проще, чем обрезка черных граней, и можно делать это на этапе кодирования. К сожалению, это не всегда так. Например, в фильме “Отель «Гранд Будапешт»” соотношение сторон основной картинки меняется от 16:9 к 4:3 и к 21:9. Этот прием используется для обозначения временного периода: 4:3 в 1932-м, 21:9 в 1968-м и 16:9 в 1985-м.
![](https://habrastorage.org/getpro/habr/upload_files/96f/31d/fe8/96f31dfe8dca93f3efc11c5d4c73cfcd.png)
Аналогичный художественный прием используется и в фильме «Мамочка», где большую часть экранного времени используется соотношение сторон 4:3, но в конце оно меняется на 16:9.
![](https://habrastorage.org/getpro/habr/upload_files/889/22b/958/88922b95894eba9c658d0f2a10a04055.png)
Детектировать чёрные грани в отдельном кадре несложно: нужно проверить по отдельности каждую из четырех его граней— верхнюю, правую, нижнюю и левую. При проверке изначально выбирается крайняя полоска пикселей кадра, суммируется яркость всех пикселей в этой полоске по всем цветовым каналам (красный, зеленый, синий) и делится на количество пикселей в полоске. Если полученное значение средней яркости ниже заданного порога, то черная грань есть и нужно сканировать следующую полоску, что ближе к центру — и так до тех пор, пока не найдётся полоска, чья яркость выше заданного порога. Это и будет конец черной грани. Проиллюстрирую:
![На изображении желтым выделены несколько тёмных полосок с яркостью 0, а голубым — первые достаточно яркие полоски, их средняя яркость 147 из 255. На изображении желтым выделены несколько тёмных полосок с яркостью 0, а голубым — первые достаточно яркие полоски, их средняя яркость 147 из 255.](https://habrastorage.org/getpro/habr/upload_files/325/a86/b00/325a86b002de7537adac9cf3bcaeef3a.png)
Таким же образом можно отсечь чрезмерно темные куски по краям кадра.
Текст: хардсабы
Если говорить про текст, мусорным для нас является только тот, который нанесен поверх кадра. Текст, являющийся частью кадра, не выделяется и потому уместен. Приведу пример:
![Зелёным прямоугольником выделен “хороший” текст, а красным — “нежелательный” Зелёным прямоугольником выделен “хороший” текст, а красным — “нежелательный”](https://habrastorage.org/getpro/habr/upload_files/e17/939/cff/e17939cffee47f2646f3e3a970abc443.png)
В случае с текстом нам нужен максимально простой детектор, так как естественный текст в кадре — например, на элементах окружения — не является визуальным мусором. Поэтому нет смысла гоняться за SoTA архитектурами, можно взять что-то простое и быстрое. Мы используем EAST (Efficient and Accurate Scene Text), он удобен еще и тем, что реализован в Open-CV и его можно быстро встроить в проект.
Пайплайн EAST состоит всего из двух этапов: полносвязной сети и Thresholding & Non-Maximum Suppression (далее NMS).
![](https://habrastorage.org/getpro/habr/upload_files/0f6/be7/113/0f6be7113823253438b0167b7793c787.png)
В Open-CV реализация EAST использует для извлечения признаков ResNet-50. Сеть обучена на датасетах детекции текста в сцене ICDAR 2013 и ICDAR 2015 — это 1229 фотографий с локализованным на них текстом. На выходе получаем тепловую карту вероятности текста в отдельных местах и набор описаний прямоугольников в формате RBOX. RBOX содержит координаты верхнего левого и нижнего правого угла прямоугольника, а также угол поворота. Далее отбрасываем прямоугольники, степень уверенности в которых ниже заданного порога, и применяем NMS для избавления от дублей. В результате получаем набор прямоугольников с текстом.
![Пример работы NMS Пример работы NMS](https://habrastorage.org/getpro/habr/upload_files/b7d/3ed/095/b7d3ed0953ef428d3fd77c5aa8bff831.png)
![Пример детекции субтитров EAST Пример детекции субтитров EAST](https://habrastorage.org/getpro/habr/upload_files/610/31c/20c/61031c20c818a48be8995fc00566d415.png)
![](https://habrastorage.org/getpro/habr/upload_files/c6e/985/5d9/c6e9855d991f3736a42f328b37e7f881.png)
Мы установили большой порог уверенности, таким образом после фильтрации большинство надписей в обстановке не детектятся.
Логотипы
Существует два вида задач детекции логотипов:
детекция логотипа на объекте в кадре;
детекция логотипа, наложенного поверх кадра.
![Примеры логотипов на объекте в кадре из LogoDet-3K Примеры логотипов на объекте в кадре из LogoDet-3K](https://habrastorage.org/getpro/habr/upload_files/418/2c7/7bb/4182c77bb50864002cc94324e477c917.png)
![Примеры логотипа, наложенного поверх кадра: непрозрачный логотип, полупрозрачный логотип, два логотипа Примеры логотипа, наложенного поверх кадра: непрозрачный логотип, полупрозрачный логотип, два логотипа](https://habrastorage.org/getpro/habr/upload_files/f42/026/d13/f42026d130fec529045747f64bd175b4.png)
Нас интересует детекция логотипов, наложенных поверх кадров. Чаще всего они встречаются в сериалах, так свой логотип оставляет правообладатель. Иногда поверх изображения также наложены иконки возрастных ограничений: «18+» и им подобные, далее их тоже будем считать логотипами.
Уточним условия нашей задачи:
логотипы не являются частью изображения, а наложены поверх;
логотип может быть полупрозрачным;
как правило, логотип не меняет положение в кадре на протяжении всего видео;
в кадре может быть от одного до 4-х логотипов в разных углах.
Можно провести аналогию логотипа с ватермаркой, как на изображениях с фотостоков, и представить, что набор кадров из одного видео — это набор изображений с одинаковой ватермаркой.
![Пример изображения с ватермаркой Пример изображения с ватермаркой](https://habrastorage.org/getpro/habr/upload_files/a10/321/6ed/a103216ed29e241a617d923b87dedf4c.png)
В On the Effectiveness of Visible Watermarks описывается метод детекции ватермарок и восстановления оригинальных изображений. Восстановление изображений нас не интересует, т.к. логотипы могут быть непрозрачными, а метод детекции будет разобран далее. Ключевой его момент — использование алгоритма выделения контуров изображений.
Возьмем в качестве алгоритма выделения контуров изображений оператор Собеля. Оператор Собеля вычисляет новое значение для каждого пикселя в зависимости от его соседей с помощью маски 3*3.
Если стало интересно, можете почитать ещё про алгоритмы выделения контуров на Хабре или на Вики.
Теперь разберем, как с помощью оператора Собеля можно детектировать логотипы. Картинки были осветлены для большей наглядности.
1. Возьмем несколько десятков равноудаленных друг от друга кадров из видео.
2. Применим к изображениям фильтр оператором Собеля раздельно по оси Х и по оси У - это позволит определить границы объектов.
![Исходное изображение Исходное изображение](https://habrastorage.org/getpro/habr/upload_files/9ea/334/ce3/9ea334ce3efed8d5f9190846f6315ecb.png)
![Изображение после применения фильтра по оси Х Изображение после применения фильтра по оси Х](https://habrastorage.org/getpro/habr/upload_files/afb/28e/059/afb28e0592cf06cb222e8c5e42c7c24b.png)
![Изображение после применения фильтра по оси У Изображение после применения фильтра по оси У](https://habrastorage.org/getpro/habr/upload_files/5db/1e7/c60/5db1e7c60fff4731d7cffa4727e9d182.png)
3. После усреднения получившихся картинок получаем заметный логотип на практически полностью чёрном фоне.
![Правые половины усредненных изображений с фильтром по Х и по У и логотипы крупным планом Правые половины усредненных изображений с фильтром по Х и по У и логотипы крупным планом](https://habrastorage.org/getpro/habr/upload_files/195/e16/31e/195e1631e5df289aaec713317ebf8d62.png)
4. Складываем градиенты по Х и по У.
![Во всех случаях получаем хорошо заметные логотипы Во всех случаях получаем хорошо заметные логотипы](https://habrastorage.org/getpro/habr/upload_files/64b/5d4/9c9/64b5d49c9ec7fb03f9e0df01b19e25bf.png)
5. Блюрим изображение, чтобы избавиться от случайных выбросов.
6. Переводим изображение в черно-белое.
![](https://habrastorage.org/getpro/habr/upload_files/ef1/876/86c/ef187686cbc6646bc38227535f325107.png)
7. Считаем, что всё белое - логотип, остальное — нет. Осталось создать описывающие прямоугольники.
8. Разбиваем изображение на 4 равные части на случай нескольких логотипов в разных углах, как тут:
![](https://habrastorage.org/getpro/habr/upload_files/00a/6a7/2d8/00a6a72d8d0ee0be4159c1d3c7e79fde.png)
9. В каждой четверти находим минимальный прямоугольник, охватывающий все белые пиксели. Если белых пикселей нет, то логотипа нет.
10. Готово, логотипы распознаны.
![](https://habrastorage.org/getpro/habr/upload_files/2c5/425/46e/2c542546e22ad1b84a805131f753bd01.png)
Финал
Теперь, когда все детекторы нежелательных объектов готовы, нам нужны ещё две вещи для обрезки кадра в постер: детектор лиц и алгоритм обрезки.
В результате работы детектора мы получаем координаты одного прямоугольника, охватывающего лицо. Кадры без лиц отбрасываем, так как считаем их плохими кандидатами на постеры.
Постеры должны иметь заранее заданное соотношение сторон, содержать целиком лицо и не содержать визуальный мусор.
![Пример построения постера из изображения с черными гранями Пример построения постера из изображения с черными гранями](https://habrastorage.org/getpro/habr/upload_files/f9b/01d/a4d/f9b01da4d5fa03ef8144658ed291eac6.gif)
Постер получается путём сужения прямоугольника, описывающего лицо, до прямоугольника с целевым соотношением сторон и его последующим расширением до тех пор, пока не упремся в нежелательные объекты или границы кадра.
Далее приведу несколько примеров преобразований «исходный кадр → детекция → постер без названия/логотипа».
![](https://habrastorage.org/getpro/habr/upload_files/8ea/b8d/98f/8eab8d98f0b4c7bccfc849cfc3c7e86d.png)
![](https://habrastorage.org/getpro/habr/upload_files/3fa/e2c/e41/3fae2ce41d8677cb7149153c58e92e1c.png)
![](https://habrastorage.org/getpro/habr/upload_files/ba8/80f/fad/ba880ffad99da3118014ced1b5cee931.png)
После того, как кадры были избавлены от визуального мусора, начинается следующий этап пайплайна, но это уже совсем другая история… о которой мы обязательно расскажем, но уже в другой раз.