- •Глава 3
- •Общие сведения
- •Избыточность
- •3.3. Степень сжатия, качество изображения и скорость цифрового потока
- •3.4. Потери при компрессии
- •3.5. Сравнение качества аналогового и цифрового изображения
- •3.6. Особенности восприятия изображения и звука
- •3.7. Кодирование видео: основные идеи
- •3.8. Кодирование аудио: основные идеи
3.7. Кодирование видео: основные идеи
Принципы видеокомпрессии во всех кодерах примерно одинаковы и отличаются только реализацией. Каждый способ реализации имеет свои особенности. Эти особенности влияют на количество артефактов компрессии и степень сжатия, производимой разными кодерами. Поэтому кодеры одного и того же стандарта могут давать разное качество изображения или звука. Напомним, что в стандартах описаны только принципы декодирования, а не принципы кодирования. Поэтому и возникает такой простор в выборе вариантов кодирующих устройств.
В этом разделе мы рассмотрим основные идеи (рис. 3.6), которые используются в алгоритмах компрессии видео. Материал раздела предназначен для того, чтобы дать читателю самое общее представление об этой непростой сфере. За более подробными сведениями необходимо обращаться к специализированной литературе.
Изначально изображение представляет собой последовательность кадров или полей, размером 720x756 пикселов в телевидении стандартной (SD) и 1920x1080 — высокой (HD) четкости. Для простоты будем считать, что изображение имеет прогрессивную развертку, т. е. состоит только из кадров, передающихся с частотой 25 кадров/сек. Кроме того, для простоты будем считать, что яркостная и цветовая составляющие обрабатываются совместно, а не по отдельности.
Сжатие (компрессия, кодирование) делится на два больших класса:
внутрикадровое;
межкадровое.
Внутрикадровое кодирование — это компрессия изображения с использованием только информации о текущем кадре, межкадровое кодирование — с использованием информации о других кадрах видеопоследовательности. Существуют способы компрессии, в которых межкадровое кодирование не используется совсем (например, всем известный DV). Межкадровое кодирование называют иногда "временным" (temporal), чтобы подчеркнуть тот факт, что оно выполняется "вдоль" оси времени и в нем участвуют кадры как предыдущие, так и последующие по отношению к кодируемому.
Основная идея компрессии состоит в том, что передается разница изображений между двумя кадрами, а не сами эти изображения. Таким образом, один кадр видеопоследовательности является ключевым (key frame), а все остальные кадры передаются как разница между передаваемым кадром и ключевым кадром. Ключевые кадры должны время от времени обновляться, т. е. не может быть один ключевой кадр на весь фильм или видеосюжет. Обычно передается несколько десятков ключевых кадров в минуту. Ключевой кадр может быть подвергнут внутрикадровому кодированию.
Рис.
3.6.
Порядок операций при компрессировании
видеоизображений
Расстояние между соседними ключевыми кадрами называется группой изображений (GOP — group of pictures). Обычно используются размеры GOP от 25 до 100 кадров (т. е. от 1 кадра в 1 сек, до 1 кадра в 4 сек). Чем больше размер GOP, тем хуже качество компрессии. Почему так — станет ясно дальше.
Кадры между ключевыми кадрами (рис. 3.7) называются предсказываемыми кадрами (predictive frames). "Предсказываемыми" слово не очень удачное, поскольку кадры не предсказываются (подобно будущему нашей цивилизации), а вычисляются в строгом соответствии с математическими законами.
Рис.
3.7.
Ключевые кадры и предсказываемые кадры
"Предсказываемые" кадры делятся на P-кадры (previous) и В-кадры (bidirectional). P-кадры "предсказываются" на основании разницы с предыдущим по времени ключевым кадром (previous — значит "предыдущий") или предыдущим P-кадром (рис. 3.8).
Рис.
3.8.
B-кадр,
Р-кадр и опорный I-кадр
Рис.
3.9.
B-кадр
и опорный Р-кадр
Почему же вычитание одного кадра из другого так эффективно для задач компрессии изображения?
Если мы рассмотрим соседние кадры видеопоследовательности, то с удивлением обнаружим, что не так уж много на них и меняется. Если кадры соседние, то, как правило, один кадр от другого отличается незначительно. Давайте вычтем из одного кадра другой кадр. Получившийся кадр назовем остаточным кадром (residual frame).
На этом кадре почти не будет изображения (рис. 3.10) — ведь разницы между соседними кадрами почти не было: т. е. в цифровом виде этот остаточный кадр будет заполнен нулевыми значениями. Это очень хорошо, потому что такие данные легко поддаются компрессии. Например, вместо последовательности из 100 нулевых значений, можно передать последовательность из двух (0,100). Первое из чисел показывает, какое значение повторяется, а второе — количество повторяющихся значений. Ясно, что эта запись намного короче — т. е. компрессия выполнена! Конечно, в реальности все намного сложнее, но нам важно просто получить представление об основах.
Рис.
3.10.
Остаточный (residual)
кадр
Количество нулевых значений можно еще увеличить, если до вычитания произвести компенсацию движения. Компенсация движения — это последовательность действий, которая позволяет описать перемещающиеся участки изображений в двух последовательных кадрах. Идея компенсации движения проста. Предположим, что у нас есть кадр, на котором изображены бильярдные шары на столе. Один из шаров катится. При этом вид шара не меняется, меняется только его положение на экране. При вычитании этих двух кадров на тех местах, где перемещался шар, мы получим ненулевые значения, что для компрессии нехорошо. А теперь давайте представим, что мы можем передать информацию о том, куда на экране переместился шар.
Например, мы можем передать информацию, что некий участок первого кадра переместился на следующем кадре в положение на 5 точек влево. Передача такой информации по сути и есть "компенсация движения". Компенсация движения состоит из передачи информации об участке изображения, который движется, и информации о том, куда движется этот участок. Куда он движется — описывается вектором движения, смысл которого ясен из нижеследующей иллюстрации картинки (рис. 3.11) с бильярдными шарами.
Рис.
3.11.
Кодируемый и ключевой кадры
Вернемся к вычитанию одного кадра из другого. Давайте перед этим вычитанием мы выполним компенсацию движения, т. е. получим информацию о движущихся участках. При этом сами участки исключим из вычитания, посчитав, что на месте этих участков при вычитании будут нули. Собственно, зачем нам их вычитать, ведь всю информацию об этих участках мы уже имеем — зачем дублировать информацию? Чем меньше информации, тем нам лучше — в этом и суть компрессии. Таким образом, количество нулей в остаточном кадре увеличится — добавятся нули там, где мы выполнили компенсацию движения.
Таким образом, после всех ранееописанных манипуляций, мы будем иметь следующую информацию, которую для наглядности покажем графически (рис. 3.12).
Рис.
3.12.
Состав Р-кадра
Ключевой кадр передается без изменений (или подвергается внутрикадровой компрессии), а вот остаточный кадр и информацию о движении подвергают дальнейшей компрессии. Рассмотрим, как компрессируется остаточный кадр.
После получения остаточного кадра, он разбивается на прямоугольные участки (8x8 точек, 16x16 точек и т. п.). К каждому такому участку применяется дискретно-косинусное преобразование или иначе Discrete Cosine Transform сокращенно — DCT.
Давайте рассмотрим некий произвольный участок остаточного кадра размером 8x8 точек (рис. 3.13). Каждая точка этого участка в цифровом виде представляет собой число. В общем случае, точки разных яркостей и цветов могут иметь любую комбинацию, поэтому и числа тоже могут иметь любую комбинацию, поскольку мы рассматриваем произвольное придуманное изображение.
Рис.
3.13.
Блок изображения 8x8
точек
Так вот чем хорошо DCT — оно описывает любую произвольную комбинацию чисел при помощи упорядоченной комбинации чисел.
Рис.
3.14.
Получение матрицы коэффициентов DCT
Итак, из иллюстрации мы видим (рис. 3.14), что в результате DCT получилась таблица 8x8 ячеек, при этом числа, имеющие наибольшее значение, размещены в левом верхнем углу таблицы. Каких бы яркостей и цветов не были точки на исходном изображении 8x8, расположение чисел после применения DCT всегда будет примерно таким, как показано. Таким образом, числа, имеющие наибольшее значение, всегда будут иметь тенденцию к "скучива- нию" в левом верхнем углу. Соответственно, к правому нижнему углу будут группироваться нулевые значения.
Теперь произведем квантизацию данных в таблице. В нашем примере произведено квантование с шагом 3. То есть 3 = 1, 6 = 2, 9 = 3 и т. д. В реальных алгоритмах уровни квантования могут быть любыми.
Теперь считаем данные из таблицы (как показано на рис. 3.15) и запишем последовательности повторяющихся чисел парами (N, M), где N — количество повторений, а M — повторяющееся число. Такой способ записи называется групповым кодированием (run-length encoding — RLE).
Рис.
3.15.
Считывание коэффициентов DCT
и
их сокращенная запись
Получившаяся запись через пары (N, M) будет гораздо короче, чем запись исходного изображения в цифровом виде — т. е. мы продвинулись еще дальше в компрессии нашего изображения и имеем компрессированный остаточный кадр (residual frame).
В реальных алгоритмах компрессирование остаточного кадра выполняется сложнее, в частности, выбираются различные размеры ячеек, к которым применяется DCT, используются разные уровни квантования, разные "маршруты" считывания результатов DCT и т. п.
После совершения всех приведенных манипуляций, выполняется дополнительное сжатие, которое называется энтропийным кодированием. Суть энтропийного кодирования сводится к тому, что в последовательности чисел, которая подвергается компрессии, находятся закономерности вероятностного характера, которые и используются для кодирования.
Упрощенно, идея такого кодирования достаточно понятна: предположим, что у нас есть последовательность групп чисел: 111, 110, 111, 112, 111, 110, 080, 011, 111, 126, 135 и т. д. Пусть в этой последовательности 111 встречается 400 раз, 110 — 200 раз и остальные варианты — по 1 разу. Обозначим группу 111 числом 1, как самую часто встречающуюся, 110 числом — 2 и т. п. И будем группы "зашифровывать" при передаче этими числами. Первые 10 "шифров" будут однозначными числами (0...9), следующие — двузначными и т. п.
Поскольку в реальности количество разных вариантов групп может доходить до сотен, то ясно, что такое кодирование приведет к снижению потока информации при передаче. Действительно — наиболее часто будут встречаться "шифры" самых часто встречающихся групп, и эти шифры как раз и будут самыми короткими (т. е. содержать меньшее количество чисел). Подобное встречается в обычном человеческом языке — самые употребительные слова, как правило, являются самыми короткими (я, небо, река и т. п.).
Энтропийному кодированию может быть подвергнута любая цифровая информация — как компенсация движения, так и компрессированный остаточный кадр. Существует несколько алгоритмов энтропийного кодирования: кодирование Хаффмана, арифметическое кодирование и т. п.
Готовая
компрессированная последовательность
форматируется в виде элементарного
потока MPEG, о
котором мы поговорим в отдельной главе.
Рис.
3.16.
Состав Р-кадра с указанием примененных
алгоритмов
Теперь рассмотрим, что происходит в декодере. В декодер сначала приходит ключевой кадр, который декомпрессируется (если к нему применялась внут- рикадровая компрессия) и сохраняется в памяти декодера. Этот кадр будет необходим в дальнейшем, поскольку он используется для "предсказания" кадров GOP, которые идут за ним. После того как прошла вся GOP, ключевой кадр удаляется из памяти, уступая свое место ключевому кадру следующей GOP.
Рис.
3.17.
Межкадровое и внутрикадровое кодирование
После ключевого кадра начинают один за другим поступать P-кадры, которые представляют собой информацию об отличиях этих кадров от ключевого кадра (рис. 3.17). Информация эта состоит из двух частей, как мы видели: из векторов движения и участков, которые они описывают, а также остаточного кадра, обработанного DCT. И то и другое подвергнуто энтропийному кодированию.
Получив Р-кадр, декодер производит энтропийное декодирование всей информации, затем применяет обратное дискретно-косинусное преобразование, получая остаточный кадр. Этот остаточный кадр складывается с ключевым кадром. После этого выполняется компенсация движения — т. е. из ключевого кадра "выдергиваются" участки, которые переместились и складываются с полученным суммарным кадром в местах, определяемых векторами движения. В результате получается готовый кадр (рис. 3.18).
Последовательность готовых кадров передается на устройство, демонстрирующее ее зрителю (например, устройство интерфейса HDMI).
Опорный
кадр Опорный кадр + компенсация
движения
Рис.
3.18.
Порядок декомпрессирования изображения
