Вторая часть: Принципы работы видеокодека




Любое растровое изображение можно представить в виде двумерной матрицы. Когда речь заходит о цветах, идею можно развить, рассматривая изображение в виде трехмерной матрицы, в которой дополнительные измерения используются для хранения данных по каждому из цветов.

Если рассматривать итоговый цвет как комбинацию т.н. основных цветов (красного, зеленого и синего), в нашей трёхмерной матрице определяем три плоскости: первая для красного цвета, вторая для зеленого и последняя для синего.
3D матрица RGB

Будем называть каждую точку в этой матрице пикселем (элементом изображения). Каждый пиксель содержит информацию об интенсивности (обычно в виде числового значение) каждого цвета. Например, красный пиксель означает, что в нём 0 зеленого цвета, 0 синего и максимум красного. Пиксель розового цвета может быть сформирован с помощью комбинации трех цветов. Используя числовой диапазон от 0 до 255, розовый пиксель определяется как Красный = 255, Зелёный = 192 и Синий = 203.
EDISON Software - web-development
Статья опубликована при поддержке компании EDISON.

Разрабатываем приложения для видеонаблюдения, потокового видео, а также занимаемся видеозаписью в хирургической комнате.

Альтернативные способы кодирования цветного изображения


Для представления цветов, из которых состоит изображение, есть немало и других моделей. Например, можно использовать индексированную палитру, в которой потребуется только один байт для представления каждого пикселя, вместо трёх, необходимых при использовании модели RGB. В такой модели можно использовать 2D-матрицу вместо 3D-матрицы для представления каждого цвета. Это экономит память, но даёт меньшую цветовую гамму.

NES палитра

RGB



Например, взгляните на эту картинку ниже. Первое лицо полностью окрашено. Другие — это красная, зеленая и синяя плоскости (интенсивность соответствующих цветов показана в градации серого).

Интенсивность каналов RGB

Видим, что оттенки красного в оригинале будут в тех же местах, в которых наблюдаются самые яркие части второго лица. В то время как вклад синего цвета в основном можно увидеть только в глазах Марио (последнее лицо) и элементах его одежды. Обратите внимание, куда все три цветовые плоскости вносят наименьший вклад (самые темные части изображений) — это в усы Марио.

Для хранения интенсивности каждого цвета требуется определенного количества битов — эта величина называется битовой глубиной. Допустим, тратится 8 бит (исходя из значения от 0 до 255) на одну цветовую плоскость. Тогда имеем глубину цвета в 24 бита (8 бит * 3 плоскости R/G/B).

Другое свойство изображения — это разрешение, представляющее из себя количество пикселей в одном измерении. Частенько обозначается как ширина ? высота, как ниже на изображение-примере 4 на 4.
Разрешение изображения

Ещё одно свойство, с которым имеем дело при работе с изображениями/видео — это соотношение сторон, описывающее обычную пропорциональную взаимосвязь между шириной и высотой изображения или пикселя.

Когда говорят, что некий фильм или картинка имеют размер 16 на 9, обычно имеется в виду соотношение сторон дисплея (DAR — от Display Aspect Ratio). Однако иногда могут быть различные формы отдельных пикселей — в этом случае речь идёт о соотношении пикселей (PAR — от Pixel Aspect Ratio).

Соотношение сторон дисплея

пропорции пикселя
Хозяюшке на заметку: DVD соответствует DAR 4 на 3

Хотя реальное разрешение DVD составляет 704x480, тем не менее оно сохраняет соотношение сторон 4:3, поскольку PAR имеет значение 10:11 (704x10 / 480x11).

Ну и, наконец, можем определить видео как последовательность из n кадров за период времени, которое можно считать дополнительным измерением. А n тогда — это частота кадров или количество кадров в секунду (FPS — от Frames per Second).

видео

Количество бит в секунду, необходимое для показа видео, является его скоростью передачибитрейтом.
битрейт = ширина * высота * бит глубина * кадров в секунду

Например, для видео с 30 кадрами в секунду, 24 битами на пиксель, разрешением 480x240 потребуется 82,944,000 бит в секунду или 82,944 Мбит/с (30x480x240x24) — но это если не используется какой-либо из методов сжатия.

Если скорость передачи почти постоянна, то она называется постоянной скоростью передачи (CBR — от constant bit rate). Но она также может и варьироваться, в этом случае называется переменной скоростью передачи (VBR — от variable bit rate).

Этот график демонстрирует ограниченный VBR, когда тратится не слишком много битов в случае полностью тёмного кадра.

Ограниченный VBR

Изначально инженеры разработали метод удвоения воспринимаемой частоты кадров видеодисплея без использования дополнительной полосы пропускания. Этот способ известен как чересстрочное видео; в основном, он отправляет половину экрана в первом «кадре», а другую половину — в следующем «кадре».

В настоящее время визуализация сцен, в основном, происходит с использованием технологии прогрессивного сканирования. Это способ отображения, хранения или передачи движущихся изображений, в котором все линии каждого кадра прорисовываются последовательно.

чересстрочный и прогрессивный

Ну что ж! Теперь мы в курсе, как изображение представляется в цифровом виде, как устроены его цвета, сколько бит в секунду мы тратим, чтобы показать видео, если скорость передачи постоянная (CBR) или переменная (VBR). Знаем про заданное разрешение с использованием заданной частоты кадров, ознакомились со многими другими терминами, такие как чересстрочное видео, PAR и некоторыми другими.

Удаление избыточности


Известно, что видео без сжатия нормально использовать невозможно. Часовое видео с разрешением 720p и частотой 30 кадров в секунду занимало бы 278 Гб. К такому значению приходим, перемножив 1280 x 720 x 24 x 30 x 3600 (ширина, высота, биты на пиксель, FPS и время в секундах).

Использование алгоритмов сжатия без потерь, вроде DEFLATE (используется в PKZIP, Gzip и PNG), не даст достаточного уменьшению необходимой полосы пропускания. Приходится искать другие способы сжатия видео.

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

Цвет, яркость и наши глаза


Наши глаза более чувствительны к яркости, чем к цвету. Вы можете убедиться в этом сами, посмотрев на эту картинку.

яркость против цвета


Если вы не видите, что в левой половине изображения цвета квадратов A и B на самом деле одинаковы, то это нормально. Наш мозг заставляет нас уделять больше внимания светотени, а не цвету. С правой стороны между означенными квадратами есть перемычка того же цвета — поэтому мы (т.е. наш мозг) легко определяем, что, на самом деле, там один и тот же цвет.
Давайте разберём (упрощенно) как работают наши глаза. Глаз — сложный орган, состоящий из многих частей. Однако нас больше всего интересуют колбочки и палочки. Глаз содержит около 120 миллионов палочек и 6 миллионов колбочек.

Рассмотрим восприятие цвета и яркости как отдельные функции определённых частей глаза (на самом деле, всё обстоит несколько сложнее, но мы упростим). Палочковые клетки, в основном, отвечают за яркость, в то время как колбочковые клетки отвечают за цвет. Колбочки подразделяются на три типа, в зависимости от содержащегося пигмента: S-колбочки (синий цвет), M-колбочки (зеленый цвет) и L-колбочки (красный цвет).

Поскольку у нас гораздо больше палочек (яркость), чем колбочек (цвет), можно сделать вывод, что мы более способны различать переходы между темнотой и светом, чем цвета.

состав глаз

Функции контрастной чувствительности


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

Цветовая модель


Мы немножко разобрались, как работать с цветными изображениями, используя RGB-схему. Есть и другие модели. Существует модель, которая отделяет яркость от цветности и она известна как YCbCr. Кстати, есть и другие модели, которые делают аналогичное разделение, но мы рассмотрим только эту.

В этой цветовой модели Y — это представление яркости, а также используются два цветовых канала: Cb (насыщенный синий) и Cr (насыщенный красный). YCbCr может быть получен из RGB, равно как возможно и обратное преобразование. Используя эту модель, мы можем создавать полноцветные изображения, как видим ниже:

пример ycbcr

Преобразование между YCbCr и RGB


Кто-то возразит: как возможно получить все цвета, если не используется зеленый?

Чтобы ответить на этот вопрос, преобразуем RGB в YCbCr. Воспользуемся коэффициентами, принятыми в стандарте BT.601, который был рекомендован подразделением МСЭ-Р. Это подразделение определяет стандарты цифровом видео. Например: что такое 4K? Каковы должны быть частота кадров, разрешающая способность, цветовая модель?

Сначала вычислим яркость. Воспользуемся константами, предложенные МСЭ, и заменим значения RGB.

Y = 0.299R + 0.587G + 0.114B

После того, как мы получили яркость, отделим синий и красный цвет:

Cb = 0.564(BY)

Cr = 0.713(RY)

И мы также можем преобразовать обратно и даже получить зеленый с помощью YCbCr:

R = Y + 1.402Cr

B = Y + 1.772Cb

G = Y — 0.344Cb — 0.714Cr

Как правило, дисплеи (мониторы, телевизоры, экраны и т. д.) используют только модель RGB. Но эта модель может быть организована по-разному:

геометрия пикселей

Цветовая субдискретизация


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

ycbcr разрешение сэмплирования


Насколько допустимо уменьшать разрешение цветности?! Оказывается, уже есть некоторые схемы, которые описывают, как обрабатывать разрешение и слияние (Итоговый цвет = Y + Cb + Cr ).

Эти схемы известны как системы субдискретизации и выражаются в виде 3-кратного соотношения — a:x:y, которое определяет число выборок яркостных и цветоразностных сигналов.

a — эталон горизонтальной выборки (как правило, равен 4)
x — количество выборок цветности в первой строке пикселей (горизонтальное разрешение по отношению к a)
y — количество изменений выборок цветности между первой и второй строками пикселей.
Исключение составляет 4:1:0, обеспечивающее одну выборку цветности в каждом блоке разрешения яркости 4 на 4.
Общие схемы, используемые в современных кодеках:

  • 4:4:4 (без субдискретизации)
  • 4:2:2
  • 4:1:1
  • 4:2:0
  • 4:1:0
  • 3:1:1

YCbCr 4: 2: 0 — пример слияния


Вот объединенный фрагмент изображения с использованием YCbCr 4:2:0. Обратите внимание, что мы тратим только 12 бит на пиксель.

YCbCr 4:2:0
Вот так выглядит одно и то же изображение, закодированное основными типами цветовой субдискретизации. Первый ряд — это окончательный YCbCr, нижний ряд показывает разрешение цветности. Весьма достойные результаты, учитывая небольшие потери в качестве.

примеры подвыборки цветности

Помните, мы насчитали 278 Гб дискового пространства для хранения часового видеофайла с разрешением 720p и 30 кадрами в секунду? Если воспользуемся YCbCr 4:2:0, то этот размер сократится наполовину — 139 Гб. Пока что всё равно далеко до приемлемого результата.

Вы можете сами получить гистограмму YCbCr с помощью FFmpeg. В этом изображении синее превалирует над красным, что хорошо видно на самой гистограмме.

Цветность, яркость, цветовая гамма — видеообзор


Рекомендуется к просмотру вот это обалденное видео. Тут объясняется, что такое яркость, да и вообще расставлены все точки над ё о яркости и цвете.

Типы кадров


Двигаемся дальше. Попробуем устранить избыточность по времени. Но сначала давайте определим некоторую базовую терминологию. Предположим, у нас есть фильм с 30 кадрами в секунду, вот его первые 4 кадра:

ball 1 ball 2 ball 3 ball 4

Мы можем видеть много повторений в кадрах: например, синий фон, не изменяющийся от кадра к кадру. Чтобы решить эту проблему, мы можем абстрактно классифицировать их как три типа кадров.

I-кадр (Intro Frame)


I-кадр (кадр-ссылка, ключевой кадр, внутренний кадр) является автономным. Вне зависимости от того, что нужно визуализировать, I-кадр является, по сути, статичной фотографией. Первый кадр обычно является I-кадром, однако будем регулярно наблюдать I-кадры и среди далеко не первых кадров.

ball 1

P-кадр (Predicted Frame)


P-кадр (прогнозируемый кадр) использует преимущество того факта, что почти всегда текущее изображение может быть воспроизведено с использованием предыдущего кадра. Например, во втором кадре единственным изменением является движущийся вперёд мяч. Мы можем получить кадр 2 просто немного видоизменив кадр 1, только используя разницу между этими кадрами. Для построения кадра 2 ссылаемся на предшествующий ему кадр 1.

ball 1 < мяч 1

B-кадр (Bi-predictive Frame)


А как насчет ссылок не только на прошлые, а заодно и на будущие кадры, чтобы обеспечить еще лучшее сжатие?! Это, в основном и есть B-кадр (двунаправленный кадр).

ball 1 < мяч 1 > ball 3

Промежуточный вывод


Эти типы кадров используются для обеспечения наилучшего сжатия. Мы разберём, как это происходит, в следующем разделе. А пока отметим, что наиболее «дорогим» по затраченной памяти является I-кадр, P-кадр обходится заметно дешевле, а вот самым выгодным вариантом для видео является B-кадр.

пример типов кадров

Временна?я избыточность (межкадровое прогнозирование)


Давайте рассмотрим какие у нас есть возможности для минимизации повторений по времени. Этот тип избыточности решим с помощью методов взаимного прогнозирования.

Постараемся потратить как можно меньше битов для кодирования последовательности кадров 0 и 1.

оригинальные кадры

Мы можем произвести вычитание, просто вычитаем кадр 1 из кадра 0. Получаем кадр 1, только используем разницу между ним и предыдущим кадром, фактически кодируем только получающийся остаток.

дельта кадры

Но что, если я вам скажу, что есть ещё более лучший метод, который использует еще меньше битов?! Сначала давайте разобьём frame 0 на чёткую сетку, состоящую из блоков. А затем попробуем сопоставить блоки из кадра 0 с кадром 1. Иными словами, оценим движение между кадрами.
Из Википедии — блочная компенсации движения

Блочная компенсация движения делит текущий кадр на непересекающиеся блоки и вектор компенсации движения сообщает, происхождение блоков (распространенное заблуждение состоит в том, что предыдущий кадр делится на непересекающиеся блоки, а векторы компенсации движения сообщают, куда переходят эти блоки. А фактически наоборот — анализируется не предыдущий кадр, а последующий, выясняется не куда перемещаются блоки, а откуда они появились). Обычно исходные блоки перекрываются в исходном кадре. Некоторые алгоритмы сжатия видео собирают текущий кадр из частей даже не одного, а сразу нескольких ранее переданных кадров.
дельта кадры

В процессе оценивания видим, что шар переместился с (x=0, y=25) на (x=6, y=26), значения x и y определяют вектор движения. Еще один шаг, который мы можем сделать, чтобы сохранить биты, — это кодировать только разность векторов движения между последней позицией блока и прогнозируемой, поэтому конечный вектор движения будет (x=6-0=6, y=26-25=1).

В реальной ситуации этот шарик был бы разделен на n блоков, но сути дела это не меняет.

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

оценка движения

Но видим, что когда применяем оценку движения, данных для кодирования заметно меньше, чем при использовании более простого метода высчитывания дельты между кадрами.

оценка движения против дельты

Как будет выглядеть реальная компенсация движения


Эта методика применяется сразу ко всем блокам. Зачастую наш условный движущийся мячик будет разбит сразу на несколько блоков.

компенсация движения в реальном мире

Вы можете сами пощупать эти концепции, используя Jupyter.

Чтобы увидеть векторы движения можно создать видео с внешним предсказанием с помощью ffmpeg.

межкадровое предсказание (векторы движения) с помощью ffmpeg

Ещё можно воспользоваться Intel Video Pro Analyzer (он платный, но есть бесплатная пробная версия, которая ограничена только первыми десятью кадрами).

межпрогнозный анализатор видео про анализатор

Пространственная избыточность (внутренний прогноз)


Если проанализировать каждый кадр в видео, то обнаружим множество взаимосвязанных областей.



Пройдемся по этому примеру. Эта сцена в основном состоит из синего и белого цветов.



Это I-кадр. Предыдущие кадры для прогнозирования взять не можем, но получится его сжать. Закодируем выделение красного блока. Если мы посмотрим на его соседей, то замечаем, что вокруг него есть кое-какие цветовые тенденции.



Предполагаем, что в кадре цвета распространяются по вертикали. Что означает, что цвет неизвестных пикселей будут содержать значения его соседей.



Такой прогноз может оказаться и неверным. Именно по этой причине нужно применить этот метод ( внутренний прогноз), а затем ещё вычесть реальные значения. Это даст нам остаточный блок, что приведёт к гораздо более сжатой матрице по сравнению с оригиналом.



Если хотите попрактиковаться с внутренними предсказаниями, то можете создать видео с макроблоками и их предсказаниями с помощью ffmpeg. Чтобы понять значение каждого цвета блока придётся ознакомиться с документацией ffmpeg.

внутреннее предсказание (макроблоки) с помощью ffmpeg

Или же можно использовать Intel Video Pro Analyzer (как я уже упоминал выше, в пробной бесплатной версии ограничение на первые 10 кадров, но вам этого на первых порах хватит).

интра-прогнозирование Intel Video Pro анализатор



Вторая часть: Принципы работы видеокодека

Комментарии (13)


  1. lampa
    23.12.2019 11:44

    Большое спасибо за статью!


  1. DistortNeo
    23.12.2019 17:24
    +2

    1. А разве в современных кодеках не используется модель ITU-R BT.709 вместо BT.601?
    2. Так много внимания уделено CRT-экранам, но ни слова про OLED — а там расположение цветовых пикселей бывает ещё более экзотическим.

    Впрочем, это несущественные замечания.


  1. agarus
    23.12.2019 19:42
    +3

    Red — Luigi — Blue? Это специальное цветовое пространство у Марио? :)


    1. rishat_edison Автор
      23.12.2019 20:01
      +3

      Похоже на шутку-пасхалку от авторов оригинальной статьи. Знатоки игры сразу понимают о чём речь.

      Младший брат Марио — Луиджи — носит зелёное.


  1. AWSVladimir
    23.12.2019 20:59
    +2

    Есть ли у вас коэффициенты для целочисленного преобразования из RGB в YCbCr и обратно?
    В инете есть упоминание на эти коэффициенты, но я так и не мог их найти.
    Если бросите ссылку или сами эти коэффициенты, буду очень признателен.


    1. rishat_edison Автор
      23.12.2019 21:17
      +3

      В статье используются на примере те коэффициенты, которые предлагает МСЭ-Р (англ. ITU-R) для преобразований в обе стороны.

      Также посмотрите внимательно англоязычный оригинал статьи. Там почти во всех абзацах по несколько ссылок (что, ИМХО, перебор), далеко не все они перенесены сюда в перевод. Возможно, там найдёте ссылки, которые Вам помогут.



  1. e_v_genius
    24.12.2019 12:51
    +1

    Отличная статья для чайников (каким я и являюсь) .


  1. Hait
    24.12.2019 13:50
    +1

    Неплохо было бы рядом с русскоязычными терминами оставлять оригинальные. Ну или и подписи под картинками тоже переводить :)


  1. masyaman
    25.12.2019 00:01
    +1

    Спасибо, интересная статья (обе).


    Цветовая субдискретизация не очень хорошо описана. А тут автор, видимо, ошибся (или опечатался):


    Исключение составляет 4:1:0, обеспечивающее одну выборку цветности в каждом блоке разрешения яркости 4 на 4.

    Если я правильно понял из вики (https://ru.wikipedia.org/wiki/%D0%A6%D0%B2%D0%B5%D1%82%D0%BE%D0%B2%D0%B0%D1%8F_%D1%81%D1%83%D0%B1%D0%B4%D0%B8%D1%81%D0%BA%D1%80%D0%B5%D1%82%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F), то описание X:a:b означает разбиение изображения на блоки X 2 пикселя. Яркостная составляющая записывается для каждого пикселя (всего X 2 пикселей), а цветовая для a усредненных пикселей в первой строке и b усредненных пикселей во второй строке (всего a + b пикселя). При этом либо b = a либо b = 0. В первом случае разрешение цветовой составляющей по вертикали соответствует оригинальному, а во втором случае оно уменьшается по вертикалив 2 раза.
    Соостетственно, 4:1:0 сохраняет одну выборку цвета на блок 4х2 пикселя. Про исключения в вики (русской и английской) вроде бы не написано.


    Во многих старых играх наблюдал огромную пикселизацию в видеороликах в сценах, где много красного. Я догадывался, что это из-за 4:2:0. Но до сих пор не очень понимаю, почему это так заметно только с красным цветом. Не помню ничего подобного с синим или зеленым. Верить в то, что разрешение красного канала меньше чем синего или зеленого пока отказываюсь. Подозреваю, что дело в том, что уменьшеное разрешение цвета записывается для красного и синего каналов, а для зеленого вычисляется из яркости, что дает большее разрешение. Если так, то большую пикселизацию можно было бы наблюдать и на синем цвете, но сцены с плавными синими переходами встречаются редко, а, например, красный огонь часто.
    Хотелось бы услышать комментарий от знающих людей.


    1. DistortNeo
      25.12.2019 19:22
      +2

      Во многих старых играх наблюдал огромную пикселизацию в видеороликах в сценах, где много красного. Я догадывался, что это из-за 4:2:0. Но до сих пор не очень понимаю, почему это так заметно только с красным цветом. Не помню ничего подобного с синим или зеленым.

      Разрешение глаза по синему цвету ниже, чем по красному, а по красному ниже, чем по зелёному. Поэтому при прочих равных условиях артефакты в синем канале будут видны слабее всего.


      А с зелёным никаких проблем, потому что большая часть информации о зелёном содержится в Y-компоненте, а она передаётся с большим разрешением.


      1. masyaman
        26.12.2019 00:45
        +2

        Сомневаюсь, что разрешение глаза тут играет какую-то ощутимую роль. Речь идет об очень низких разрешениях, гораздо ниже, чем разрешение глаза. Если правильно помню, то у первой Sony PlayStation стандартное разрешение 320x240, но в некоторых видеороликах на границе красного визуальное разрешение падает еще в 2 раза, просто огромные пиксели. Подобное наблюдал на Nintendo DS, там разрешение еще меньше, 256х192.
        Только понял, что обе системы не умеют сглаживание. Я думаю, что если бы красный/синий канал растянули до оригинального разрешения хотя бы с билинейным сглаживанием, то картинка была бы намного лучше.


  1. QtRoS
    25.12.2019 19:22
    +2

    Спасибо, было очень интересно. В целом можно было догадаться, что кадры как-то сжимаются с учётом небольших изменений между друг другом, но в деталях кроется интерес!