Фотография в телефоне и песня в плеере устроены гораздо сложнее, чем кажется на первый взгляд. За кулисами обоих форматов работает один и тот же математический приём: сигнал, будь то яркость пикселей или колебания звукового давления, переписывается на языке частот, после чего часть этих частот безжалостно урезается или выбрасывается вовсе. Человеческий глаз и ухо устроены так, что заметная доля этой информации им попросту не нужна, и математика позволяет отделить важное от лишнего с хирургической точностью. Инструмент, который делает такой пересчёт возможным, называется дискретным косинусным преобразованием, сокращённо DCT, и именно на нём держится сжатие JPEG и MP3.
Что на самом деле делает косинусное преобразование с рядом чисел
Любое изображение или звуковую дорожку можно представить как набор дискретных значений: яркость каждого пикселя или амплитуда сигнала в конкретный момент времени. DCT берёт такой набор чисел и представляет его как сумму косинусоид разной частоты и амплитуды. Формально одномерное преобразование для последовательности из N значений записывается так: коэффициент с номером k равен сумме по всем n от нуля до N минус один произведения исходного значения x(n) на косинус от выражения пи, умноженного на k, умноженного на (2n плюс один), делённого на 2N. Результат такого пересчёта, набор коэффициентов, называется спектром сигнала в частотной области, и в нём заключена вся та же информация, что и в исходных числах, просто записанная иначе.
Ключевое свойство DCT в том, что оно линейное и обратимое: применив к результату обратное преобразование, можно восстановить исходный ряд чисел без единой потери, если работать с точными дробными значениями. Но именно эта строгая обратимость и создаёт возможность для сжатия. Для большинства реальных изображений и звуковых фрагментов почти вся энергия сигнала концентрируется в первых, низкочастотных коэффициентах, а высокочастотные коэффициенты, отвечающие за резкие мелкие детали, обычно оказываются близкими к нулю или совсем незначительными. Это статистическое свойство типичного фото или мелодии, а не случайность, и именно оно делает DCT настолько удобным инструментом именно для сжатия, а не для произвольной перестановки данных.
Как JPEG режет изображение на блоки и превращает их в частотный спектр
В формате JPEG изображение сначала делится на квадратные блоки размером 8 на 8 пикселей. Если размеры картинки не делятся на восемь нацело, недостающие пиксели по краю просто дублируются или заполняются, а затем при декодировании обрезаются обратно. К каждому такому блоку применяется уже не одномерное, а двумерное DCT: сначала преобразование выполняется по строкам, затем по столбцам, в результате чего 64 исходных значения яркости превращаются в 64 частотных коэффициента, организованных в такую же таблицу 8 на 8.
В этой таблице коэффициентов есть чёткая закономерность: значение в левом верхнем углу отвечает за среднюю яркость всего блока и называется постоянной составляющей, а чем дальше коэффициент расположен от этого угла в сторону правого нижнего, тем более высокую пространственную частоту, то есть более мелкую и резкую деталь, он описывает. Для типичной фотографии подавляющее большинство коэффициентов в правом нижнем углу оказываются очень маленькими по модулю, потому что резких скачков яркости на соседних пикселях в реальных снимках относительно немного, а плавные градиенты хорошо описываются именно низкочастотными составляющими.
Почему квантование, а не само преобразование, отбрасывает невидимые частоты
Здесь важно разделить два разных этапа, которые часто путают. Само дискретное косинусное преобразование не теряет ни бита информации: применив к результату обратное DCT, можно получить исходный блок пикселей абсолютно точно, если не округлять числа. Реальные потери начинаются на следующем шаге, который называется квантованием. Каждый из 64 коэффициентов делится поэлементно на соответствующее число из специальной матрицы квантования, а результат округляется до ближайшего целого. Именно округление необратимо стирает часть информации: если до деления коэффициент был, скажем, 47, а шаг квантования в этой позиции равен 40, после деления и округления получится единица, и восстановить исходные 47 обратно уже не получится, останется лишь грубая оценка.
Матрица квантования устроена неравномерно: для низкочастотных коэффициентов в левом верхнем углу шаг деления маленький, порядка нескольких единиц, поэтому эти значения почти не искажаются. А для высокочастотных коэффициентов в правом нижнем углу шаг может доходить до девяноста и более, из-за чего большинство таких коэффициентов после округления попросту превращается в ноль. Настройка качества JPEG, тот самый ползунок от нуля до ста в настройках сохранения, масштабирует именно эту матрицу квантования целиком: чем ниже заданное качество, тем крупнее шаг деления по всей таблице и тем больше высокочастотных коэффициентов обнуляется. После квантования коэффициенты выстраивают в зигзагообразном порядке, чтобы собрать длинные последовательности нулей подряд, а затем сжимают алгоритмом RLE и кодированием Хаффмана, которые уже не теряют данные, а просто компактно упаковывают то, что осталось после квантования.
Что случится с картинкой, если обнулить слишком много высокочастотных коэффициентов
Визуальные последствия агрессивного квантования хорошо знакомы каждому, кто пересохранял фотографию с низким качеством JPEG несколько раз подряд. Обнуление высокочастотных коэффициентов означает потерю информации именно о резких переходах и мелких деталях, поэтому первыми страдают чёткие границы объектов, текст на изображении и тонкие текстуры вроде листвы или ткани. Поскольку преобразование и квантование выполняются независимо для каждого блока 8 на 8, при сильном сжатии становятся заметны границы между соседними блоками: соседние квадраты квантуются чуть по-разному, и на стыке возникает видимый перепад яркости, который глаз воспринимает как сетку из квадратов, наложенную на изображение.
Есть и более тонкий эффект, называемый эффектом Гиббса или звоном: если в блоке присутствует резкий контрастный край, например граница между текстом и белым фоном, ограниченный набор низкочастотных косинусоид не может идеально воспроизвести такой скачок, и вокруг края появляются лёгкие волнообразные артефакты. Именно поэтому формат JPEG плохо подходит для скриншотов с текстом и чёткой графикой: там резких границ гораздо больше, чем в обычной фотографии, и потери от квантования становятся заметнее при том же уровне сжатия.
Как устроено похожее преобразование в MP3 и при чём тут особенности слуха
Звуковой сигнал устроен иначе, чем изображение, но идея разложения на частоты применяется и здесь. В MP3 и родственных ему форматах используется не совсем классическое DCT, а его модифицированный вариант, MDCT, который работает с перекрывающимися блоками отсчётов сигнала. Перекрытие нужно для того, чтобы на границах соседних блоков не возникало резких щелчков и артефактов, похожих на блочность в JPEG, только уже на слух. Аудиопоток делится на короткие фрагменты по несколько миллисекунд, каждый переводится в частотный спектр, и дальше начинается самая интересная часть, специфичная именно для звука.
Вместо равномерного квантования по фиксированной таблице, как в JPEG, кодировщик MP3 использует психоакустическую модель, то есть математическое описание того, как реально устроен человеческий слух. Модель учитывает эффект маскирования: если в сигнале присутствует громкий тон определённой частоты, соседние по частоте тихие звуки становятся физически неразличимы на слух, даже если формально они присутствуют в сигнале. Учитывается и временное маскирование: сразу после громкого резкого звука ухо на некоторое время теряет чувствительность к тихим звукам, поэтому их можно закодировать грубее без слышимой потери качества. Есть и порог абсолютной слышимости, ниже которого звук не воспринимается вовсе независимо от соседних частот, и такие компоненты можно смело квантовать очень грубо или выбрасывать полностью.
Как психоакустическая модель распределяет биты между разными частотами
Практически это работает так: психоакустическая модель рассчитывает для каждой частотной полосы порог маскировки, то есть уровень шума квантования, который ещё останется неслышимым на фоне остального сигнала. Дальше кодировщик подбирает шаг квантования для каждой полосы так, чтобы шум округления по возможности не превышал этот порог, при этом уложившись в заданный битрейт. Если битрейт слишком низкий, а музыкальный материал сложный, шум квантования иногда всё же превышает порог маскировки, и тогда возникают слышимые артефакты сжатия: металлический призвук на высоких частотах, потеря объёма звучания или характерное "бульканье" на резких переходах громкости, которое опытные слушатели узнают на низкобитрейтных записях.
Важно понимать разницу в философии между JPEG и MP3, хотя оба используют идею отбрасывания частот через дискретное косинусное преобразование. JPEG ориентируется на общую статистику типичных изображений и одну и ту же матрицу квантования для всего файла с поправкой на выбранное качество. MP3 же адаптирует уровень квантования отдельно для каждой частотной полосы каждого короткого фрагмента звука, основываясь на модели восприятия именно этого конкретного участка сигнала, а не на усреднённой статистике. Поэтому один и тот же по формальному битрейту файл MP3 может звучать заметно чище на одном треке и заметно хуже на другом, в зависимости от того, насколько сложный частотный состав у конкретной записи и насколько точно модель маскирования угадала, какие частоты действительно неразличимы на слух.
Разберём условный пример на одном блоке 8 на 8, чтобы механика стала осязаемой. Допустим, после двумерного DCT в левом верхнем углу таблицы коэффициентов получилось значение 312, отвечающее за среднюю яркость блока, а где-то в середине таблицы находится коэффициент 47, описывающий среднюю по резкости деталь, и коэффициент 6 в правом нижнем углу, отвечающий за самую мелкую и резкую текстуру. В стандартной матрице квантования для яркости первому коэффициенту соответствует шаг деления 16, среднему коэффициенту, условно, шаг 40, а самому дальнему от угла, шаг около 99. После деления и округления получаем 312 разделить на 16, это 19 с округлением, для среднего коэффициента 47 разделить на 40 даёт 1, а для последнего 6 разделить на 99 даёт 0. Именно так рождается длинная цепочка нулей в правом нижнем углу таблицы: не потому что кодировщик специально удаляет мелкие детали, а потому что простое арифметическое округление при таком шаге деления неизбежно превращает малые числа в ноль. При повышении настройки качества шаги в матрице квантования становятся меньше, скажем 4 и 10 вместо 16 и 40, и тогда даже коэффициент 6 может сохраниться как единица, а не обнулиться, что и объясняет, почему увеличение качества сохранения напрямую увеличивает вес файла.
Похожий по духу расчёт происходит и в психоакустической модели MP3, только там роль шага квантования играет вычисленный порог маскировки для конкретной частотной полосы в конкретный момент времени. Если реальная амплитуда сигнала в этой полосе ниже порога, кодировщик присваивает ей минимальное число бит или обнуляет вовсе, а если выше, выделяет ровно столько бит, чтобы шум округления остался чуть ниже порога, не тратя биты впустую на точность, которую всё равно никто не услышит.
Что объединяет оба формата на уровне математики и почему это не совпадение
Оба формата используют один и тот же фундаментальный трюк: перевод данных из пространства исходных значений, пикселей или отсчётов амплитуды, в пространство частотных коэффициентов, где легко отличить существенное от несущественного. DCT выбрали для этой задачи не случайно: у него, в отличие от полного преобразования Фурье, не возникает мнимой части и связанных с ней вычислительных сложностей, а результат хорошо концентрирует энергию сигнала в небольшом числе первых коэффициентов для типичных природных сигналов, будь то фотография или звукозапись. Именно это свойство концентрации энергии, а не какая-то особая магия, лежит в основе всей идеи сжатия с потерями: чем меньше коэффициентов реально нужно хранить с высокой точностью, тем меньше места в итоге займёт файл при сохранении приемлемого качества для глаза или уха.
Понимание этой механики объясняет и практические рекомендации, с которыми сталкивается почти каждый пользователь. Пересохранение JPEG много раз подряд ухудшает качество именно потому, что при каждом новом сохранении блоки заново проходят через DCT и квантование, а ошибки округления накапливаются. Выбор битрейта MP3 выше определённого порога перестаёт заметно улучшать звучание, потому что психоакустическая модель уже и так сохраняет все различимые слухом частоты, а дальнейшее увеличение точности расходуется на компоненты, которые всё равно замаскированы. И блочность на слишком сжатых фотографиях, и характерные призвуки на низкобитрейтных треках, оба этих на первый взгляд разных явления, оказываются проявлением одной и той же математической операции, применённой к разным видам сигналов ради одной и той же цели: сохранить то, что действительно важно, и выбросить то, чего человек всё равно не заметит.
Из этой механики вытекает несколько практических выводов, которые полезно держать в голове при работе с изображениями и звуком:
- для фотографий с плавными переходами тона, портретов и пейзажей, JPEG с умеренным сжатием почти незаметен для глаза, потому что основная энергия сигнала сосредоточена в низких частотах, которые квантование почти не трогает;
- для скриншотов, чертежей и изображений с текстом лучше выбирать форматы без потерь, поскольку резкие границы плохо описываются ограниченным набором косинусоид и порождают заметный звон вокруг контуров;
- многократное пересохранение одного и того же JPEG стоит исключить там, где это возможно, потому что каждый новый проход через DCT и квантование добавляет собственную порцию округления поверх уже накопленных искажений;
- для звука рост битрейта MP3 выше значения, на котором психоакустическая модель уже прячет весь шум квантования ниже порога маскировки, почти не улучшает восприятие на слух, зато линейно увеличивает размер файла.