Какой алгоритм сжатия использует jpeg. Алгоритм JPEG является алгоритмом сжатия данных с потерями. Кодирование методом Хаффмана

  • Tutorial

UPD. Был вынужден убрать моноширинное форматирование. В один прекрасный день хабрапарсер перестал воспринимать форматирование внутри тегов pre и code. Весь текст превратился в кашу. Администрация хабра не смогла мне помочь. Теперь неровно, но хотя бы читабельно.

Вам когда-нибудь хотелось узнать как устроен jpg-файл? Сейчас разберемся! Прогревайте ваш любимый компилятор и hex-редактор, будем декодировать это:

Специально взял рисунок поменьше. Это знакомый, но сильно пережатый favicon Гугла:

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

Даже не зная, как происходит кодирование, мы уже можем кое-что извлечь из файла.
- маркер начала. Он всегда находится в начале всех jpg-файлов.
Следом идут байты . Это маркер, означающий начало секции с комментарием. Следующие 2 байта - длина секции (включая эти 2 байта). Значит в следующих двух - сам комментарий. Это коды символов ":" и ")", т.е. обычного смайлика. Вы можете увидеть его в первой строке правой части hex-редактора.

Немного теории

Очень кратко по шагам:
Давайте подумаем, в каком порядке могут быть закодированы эти данные. Допустим, сначала полностью, для всего изображения, закодирован канал Y, затем Cb, потом Cr. Все помнят загрузку картинок на диал-апе. Если бы они кодировались именно так, нам бы пришлось ждать загрузки всего изображения, прежде чем оно появится на экране. Так же будет неприятно, если потерятся конец файла. Вероятно, существуют и другие весомые причины. Поэтому закодированные данные располагаются поочередно, небольшими частями.

Напоминаю, что каждый блок Y ij , Cb ij , Cr ij - это матрица коэффициентов ДКП, закодированная кодами Хаффмана. В файле они располагаются в таком порядке: Y 00 Y 10 Y 01 Y 11 Cb 00 Cr 00 Y 20

Чтение файла

После того, как мы извлекли комментарий, будет легко понять, что:
  • Файл поделен на секторы, предваряемые маркерами.
  • Маркеры имеют длину 2 байта, причем первый байт .
  • Почти все секторы хранят свою длину в следующих 2 байта после маркера.
Для удобства подсветим маркеры:
FF D8 FF FE 00 04 3A 29 FF DB 00 43 00 A0 6E 78



FF FF FF FF FF FF FF FF FF FF FF FF FF FF DB 00
43 01 AA B4 B4 F0 D2 F0 FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF C0 00 11 08 00 10 00 10 03 01 22 00 02
11 01 03 11 01 FF C4 00 15 00 01 01 00 00 00 00
00 00 00 00 00 00 00 00 00 00 03 02 FF C4 00 1A
10 01 00 02 03 01 00 00 00 00 00 00 00 00 00 00
00 01 00 12 02 11 31 21 FF C4 00 15 01 01 01 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 FF
C4 00 16 11 01 01 01 00 00 00 00 00 00 00 00 00
00 00 00 00 11 00 01 FF DA 00 0C 03 01 00 02 11
03 11 00 3F 00 AE E7 61 F2 1B D5 22 85 5D 04 3C
82 C8 48 B1 DC BF FF D9

Маркер : DQT - таблица квантования.

FF DB 00 43 00 A0 6E 78
8C 78 64 A0 8C 82 8C B4 AA A0 BE F0 FF FF F0 DC
DC F0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF

Заголовок секции всегда занимает 3 байта. В нашем случае это . Заголовок состоит из:
Длина: 0x43 = 67 байт
Длина значений в таблице: 0 (0 - 1 байт, 1 - 2 байта)
[_0] Идентификатор таблицы: 0
Оставшимися 64-мя байтами нужно заполнить таблицу 8x8.



Приглядитесь, в каком порядке заполнены значения таблицы. Этот порядок называется zigzag order:

Маркер : SOF0 - Baseline DCT

Этот маркер называется SOF0, и означает, что изображение закодировано базовым методом. Он очень распространен. Но в интернете не менее популярен знакомый вам progressive-метод, когда сначала загружается изображение с низким разрешением, а потом и нормальная картинка. Это позволяет понять что там изображено, не дожидаясь полной загрузки. Спецификация определяет еще несколько, как мне кажется, не очень распространенных методов.

FF C0 00 11 08 00 10 00 10 03 01 22 00 02
11 01 03 11 01

Длина: 17 байт.
Precision: 8 бит. В базовом методе всегда 8. Как я понял, это разрядность значений каналов.
Высота рисунка: 0x10 = 16
Ширина рисунка: 0x10 = 16
Количество компонентов: 3. Чаще всего это Y, Cb, Cr.

1-й компонент:
Идентификатор: 1
Горизонтальное прореживание (H 1): 2
[_2] Вертикальное прореживание (V 1): 2
Идентификатор таблицы квантования: 0

2-й компонент:
Идентификатор: 2
Горизонтальное прореживание (H 2): 1
[_1] Вертикальное прореживание (V 2): 1

3-й компонент:
Идентификатор: 3
Горизонтальное прореживание (H 3): 1
[_1] Вертикальное прореживание (V 3): 1
Идентификатор таблицы квантования: 1

Теперь посмотрите, как определить насколько прорежено изображение. Находим H max =2 и V max =2 . Канал i будет прорежен в H max /H i раз по горизонтали и V max /V i раз по вертикали.

Маркер : DHT (таблица Хаффмана)

Эта секция хранит коды и значения полученные кодированием Хаффмана .

FF C4 00 15 00 01 01 00 00 00 00
00 00 00 00 00 00 00 00 00 00 03 02

длина: 21 байт.
класс: 0 (0 - таблица DC коэффициэнтов, 1 - таблица AC коэффициэнтов).
[_0] идентификатор таблицы: 0
Длина кода Хаффмана: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
Количество кодов:
Количество кодов означает количество кодов такой длины. Обратите внимание, что секция хранит только длины кодов, а не сами коды. Мы должны найти коды сами. Итак, у нас есть один код длины 1 и один - длины 2. Итого 2 кода, больше кодов в этой таблице нет.
С каждым кодом сопоставлено значение, в файле они перечислены следом. Значения однобайтовые, поэтому читаем 2 байта.
- значение 1-го кода.
- значение 2-го кода.

Построение дерева кодов Хаффмана

Мы должны построить бинарное дерево по таблице, которую мы получили в секции DHT. А уже по этому дереву мы узнаем каждый код. Значения добавляем в том порядке, в каком указаны в таблице. Алгоритм прост: в каком бы узле мы ни находились, всегда пытаемся добавить значение в левую ветвь. А если она занята, то в правую. А если и там нет места, то возвращаемся на уровень выше, и пробуем оттуда. Остановиться нужно на уровне равном длине кода. Левым ветвям соответствует значение 0 , правым - 1 .
Замечание:
Не нужно каждый раз начинать с вершины. Добавили значение - вернитесь на уровень выше. Правая ветвь существует? Если да, идите опять вверх. Если нет - создайте правую ветвь и перейдите туда. Затем, с этого места, начинайте поиск для добавления следующего значения.

Деревья для всех таблиц этого примера:


UPD (спасибо ): В узлах первого дерева (DC, id =0) должны быть значения 0x03 и 0x02

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

Маркер : SOS (Start of Scan)

Байт в маркере означает - «ДА! Наконец-то то мы перешли непосредственно к разбору секции закодированного изображения!». Однако секция символично называется SOS.

  FF DA 00 0C 03 01 00 02 11
03 11 00 3F 00

Длина заголовочной части (а не всей секции): 12 байт.
Количество компонентов сканирования. У нас 3, по одному на Y, Cb, Cr.

1-й компонент:
Номер компонента изображения: 1 (Y)
Идентификатор таблицы Хаффмана для DC коэффициэнтов: 0
[_0] Идентификатор таблицы Хаффмана для AC коэффициэнтов: 0

2-й компонент:
Номер компонента изображения: 2 (Cb)

[_1]

3-й компонент:
Номер компонента изображения: 3 (Cr)
Идентификатор таблицы Хаффмана для DC коэффициэнтов: 1
[_1] Идентификатор таблицы Хаффмана для AC коэффициэнтов: 1

Данные компоненты циклически чередуются.

На этом заголовочная часть заканчивается, отсюда и до конца (маркера ) закодированные данные.


0

Нахождение DC-коэффициента.
1. Читаем последовательность битов (если встретим 2 байта , то это не маркер, а просто байт ) . После каждого бита сдвигаемся по дереву Хаффмана (с соответствующим идентификатором) по ветви 0 или 1, в зависимости от прочитанного бита. Останавливаемся, если оказались в конечном узле.
10 1011101110011101100001111100100

2. Берем значение узла. Если оно равно 0, то коэффициент равен 0, записываем в таблицу и переходим к чтению других коэффициентов. В нашем случае - 02. Это значение - длина коэффициента в битах. Т. е. читаем следующие 2 бита, это и будет коэффициент.
10 10 11101110011101100001111100100

3. Если первая цифра значения в двоичном представлении - 1, то оставляем как есть: DC_coef = значение. Иначе преобразуем: DC_coef = значение-2 длина значения +1 . Записываем коэффициент в таблицу в начало зигзага - левый верхний угол.

Нахождение AC-коэффициентов.
1. Аналогичен п. 1, нахождения DC коэффициента. Продолжаем читать последовательность:
10 10 1110 1110011101100001111100100

2. Берем значение узла. Если оно равно 0, это означает, что оставшиеся значения матрицы нужно заполнить нулями. Дальше закодирована уже следующая матрица. Первые несколько дочитавших до этого места и написавших об этом мне в личку, получат плюс в карму. В нашем случае значение узла: 0x31.
Первый полубайт: 0x3 - именно столько нулей мы должны добавить в матрицу. Это 3 нулевых коэффициэнта.
Второй полубайт: 0x1 - длина коэффициэнта в битах. Читаем следующий бит.
10 10 1110 1 110011101100001111100100

3. Аналогичен п. 3 нахождения DC-коэффициента.

Как вы уже поняли, читать AC-коэффициенты нужно пока не наткнемся на нулевое значение кода, либо пока не заполнится матрица.
В нашем случае мы получим:
10 10 1110 1 1100 11 101 10 0 0 0 1 11110 0 100
и матрицу:





Вы заметили, что значения заполнены в том же зигзагообразном порядке?
Причина использования такого порядка простая - так как чем больше значения v и u, тем меньшей значимостью обладает коэффициент S vu в дискретно-косинусном преобразовании. Поэтому, при высоких степенях сжатия малозначащие коэффициенты обнуляют, тем самым уменьшая размер файла.

[-4 1 1 1 0 0 0 0] [ 5 -1 1 0 0 0 0 0]
[ 0 0 1 0 0 0 0 0] [-1 -2 -1 0 0 0 0 0]
[ 0 -1 0 0 0 0 0 0] [ 0 -1 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [-1 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]

[-4 2 2 1 0 0 0 0]
[-1 0 -1 0 0 0 0 0]
[-1 -1 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]

Ой, я забыл сказать, что закодированные DC-коэффициенты - это не сами DC-коэффициенты, а их разности между коэффициентами предыдущей таблицы (того же канала)! Нужно поправить матрицы:
DC для 2-ой: 2 + (-4) = -2
DC для 3-ой: -2 + 5 = 3
DC для 4-ой: 3 + (-4) = -1

[-2 1 1 1 0 0 0 0] [ 3 -1 1 0 0 0 0 0] [-1 2 2 1 0 0 0 0]
………

Теперь порядок. Это правило действует до конца файла.

… и по матрице для Cb и Cr:

[-1 0 0 0 0 0 0 0]
[ 1 1 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]

Так как тут только по одной матрице, DC-коэфициенты можно не трогать.

Вычисления

Квантование

Вы помните, что матрица проходит этап квантования? Элементы матрицы нужно почленно перемножить с элементами матрицы квантования. Осталось выбрать нужную. Сначала мы просканировали первый компонент, его компонента изображения = 1. Компонент изображения с таким идентификатором использует матрицу квантования 0 (у нас она первая из двух). Итак, после перемножения:


[ 0 120 280 0 0 0 0 0]
[ 0 -130 -160 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]

Аналогично получаем еще 3 матрицы Y-канала…

[-320 110 100 160 0 0 0 0] [ 480 -110 100 0 0 0 0 0]
[ 0 0 140 0 0 0 0 0] [-120 -240 -140 0 0 0 0 0]
[ 0 -130 0 0 0 0 0 0] [ 0 -130 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [-140 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]

[-160 220 200 160 0 0 0 0]
[-120 0 -140 0 0 0 0 0]
[-140 -130 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]

… и по матрице для Cb и Cr.

[-170 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 180 210 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 0 0 0]

Обратное дискретно-косинусное преобразование

Формула не должна доставить сложностей*. S vu - наша полученная матрица коэффициентов. u - столбец, v - строка. s yx - непосредственно значения каналов.

*Вообще говоря, это не совсем правда. Когда я смог декодировать и отобразить на экране рисунок 16x16, я взял изображение размером 600x600 (кстати, это была обложка любимого альбома Mind.In.A.Box - Lost Alone). Получилось не сразу - всплыли различные баги. Вскоре я мог любоваться корректно загруженной картинкой. Только очень огорчала скорость загрузки. До сих пор помню, она занимала 7 секунд. Но это и неудивительно, если бездумно пользоваться приведенной формулой, то для вычисления одного канала одного пикселя потребуется нахождения 128 косинусов, 768 умножений, и сколько-то там сложений. Только вдумайтесь - почти тысяча непростых операций только на один канал одного пиксела! К счастью, тут есть простор для отимизации (после долгих экспериментов уменьшил время загрузки до предела точности таймера 15мс, и после этого сменил изображение на фотографию в 25 раз большей площадью. Возможно, напишу об этом отдельной статьей).

Напишу результат вычисления только первой матрицы канала Y (значения округлены):


[ 87 72 50 36 37 55 79 95]
[-10 5 31 56 71 73 68 62]
[-87 -50 6 56 79 72 48 29]

И 2-х оставшихся:
Cb Cr
[ 60 52 38 20 0 -18 -32 -40] [ 19 27 41 60 80 99 113 120]
[ 48 41 29 13 -3 -19 -31 -37] [ 0 6 18 34 51 66 78 85]
[ 25 20 12 2 -9 -19 -27 -32] [-27 -22 -14 -4 7 17 25 30]
[ -4 -6 -9 -13 -17 -20 -23 -25] [-43 -41 -38 -34 -30 -27 -24 -22]
[ -37 -35 -33 -29 -25 -21 -18 -17] [-35 -36 -39 -43 -47 -51 -53 -55]
[ -67 -63 -55 -44 -33 -22 -14 -10] [ -5 -9 -17 -28 -39 -50 -58 -62]
[ -90 -84 -71 -56 -39 -23 -11 -4] [ 32 26 14 -1 -18 -34 -46 -53]
[-102 -95 -81 -62 -42 -23 -9 -1] [ 58 50 36 18 -2 -20 -34 -42]

  1. О, пойду-ка поем!
  2. Да я вообще не въезжаю, о чем речь.
  3. Раз значение цветов YCbCr получены, осталось преобразовать в RGB, типа так: YCbCrToRGB(Y ij , Cb ij , Cr ij) , Y ij , Cb ij , Cr ij - наши полученные матрицы.
  4. 4 матрицы Y, и по одной Cb и Cr, так как мы прореживали каналы и 4 пикселям Y соответствует по одному Cb и Cr. Поэтому вычислять так: YCbCrToRGB(Y ij , Cb , Cr )
Если вы выбрали 1 и 4, то я рад за вас. Либо вы все правильно поняли, либо скоро будете получать удовольствие от еды.

YCbCr в RGB

R = Y + 1.402 * Cr
G = Y - 0.34414 * Cb - 0.71414 * Cr
B = Y + 1.772 * Cb
Не забудьте прибавить по 128. Если значения выйдут за пределы интервала , то присвоить граничные значения. Формула простая, но тоже отжирает долю процессорного времени.

Вот полученные таблицы для каналов R, G, B для левого верхнего квадрата 8x8 нашего примера:
255 248 194 148 169 215 255 255
255 238 172 115 130 178 255 255
255 208 127 59 64 112 208 255
255 223 143 74 77 120 211 255
237 192 133 83 85 118 184 222
177 161 146 132 145 162 201 217
56 73 101 126 144 147 147 141
0 17 76 126 153 146 127 108

231 185 117 72 67 113 171 217
229 175 95 39 28 76 139 189
254 192 100 31 15 63 131 185
255 207 115 46 28 71 134 185
255 241 175 125 112 145 193 230
226 210 187 173 172 189 209 225
149 166 191 216 229 232 225 220
72 110 166 216 238 231 206 186

255 255 249 203 178 224 255 255
255 255 226 170 140 187 224 255
255 255 192 123 91 138 184 238
255 255 208 139 103 146 188 239
255 255 202 152 128 161 194 232
255 244 215 200 188 205 210 227
108 125 148 172 182 184 172 167
31 69 122 172 191 183 153 134

Конец

Вообще я не специалист по JPEG, поэтому вряд ли смогу ответить на все вопросы. Просто когда я писал свой декодер, мне часто приходилось сталкиваться с различными непонятными проблемами. И когда изображение выводилось некорректно, я не знал где допустил ошибку. Может неправильно проинтерпретировал биты, а может неправильно использовал ДКП. Очень не хватало пошагового примера, поэтому, надеюсь, эта статья поможет при написании декодера. Думаю, она покрывает описание базового метода, но все-равно нельзя обойтись только ей. Предлагаю вам ссылки, которые помогли мне:
Старый добрый JPEG, несмотря на массу неоспоримых достоинств, все же имеет и существенные ограничения. Снять их был призван новый метод сжатия изображений, разработки которого велись уже давно. Теперь, когда JPEG2000 стал официально признанным форматом, это должно послужить началу его активной поддержки различными производителями ПО.

Наверняка многих работающих с графикой на компьютере интересует вопрос: а как удается изображение, занимающее весьма впечатляющий объем в памяти ПК, втиснуть в гораздо меньший размер на диске? Помнится, на заре своей издательской деятельности слово «компрессия» для меня было таким загадочным и удивительным… В самом деле, каким образом происходит сжатие изображений — ведь без него сейчас немыслимо представить ни Сеть, ни цифровую фотографию, ни цветную полиграфию?

Итак, сжатие. Оно может как приводить к потере качества, так и не приводить. Последний случай — это такие методы, как RLE (Run Length Encoding, кодирование длин серий, в результате которого образуются пары типа (skip , value , где skip — это число подряд идущих нулей, а value — следующее за ними значение) и LZW (компрессия методом Lempel-Ziff-Welch), реализованные в форматах PSD, GIF и TIFF. Широко используются они и архиваторами типа RAR и ZIP. Средняя степень компрессии сжатия без потерь — 2-3 раза.

Если нужно сжать изображение сильнее, без потери качества не обойтись. Каковы принципы? Во-первых, любое изображение содержит определенную избыточность, удаление которой не приведет к заметному изменению качества картинки. Во-вторых, человеческий глаз более восприимчив к изменениям яркости, нежели цвета. Поэтому для разных каналов изображения применяются различные степени сжатия — информация теряется, но визуально это не заметно. Кроме того, чувствительность глаза к мелким элементам изображения невелика, что позволяет без ущерба для качества их удалить. Так можно сжимать изображение (даже если ухудшение качества становится уже заметным) вплоть до приемлемого порога. Степень деградации качества определяется для каждого конкретного случая. Для полиграфии допустимы лишь минимальные искажения, а для размещения в Интернете (в зависимости от предназначения) — гораздо большие.

Наибольшую популярность среди методов компрессии с потерями получил JPEG, который даже при тридцатикратном сжатии сохраняет достаточное качество картинки. Кстати, в большинстве современных методов сжатия данных (например, Layer-4, известный как mp3, а также MPEG) реализованы механизмы, аналогичные JPEG. Давайте познакомимся поближе с этим форматом, тем более что не так давно была окончательно утверждена его новейшая реализация JPEG2000, в которую вошли все дополнения, внесенные в JPEG/MPEG за десять лет его развития.

JPEG

Название алгоритма компрессии — аббревиатура от Joint Photographic Expert Group, инициативной группы, образованной из экспертов ITU (International Telecommunication Union) и ISO (International Organization for Standartization). Именно поэтому в ее названии присутствует приставка Joint. В 1992 г. JPEG был объявлен международным стандартом в области графических изображений.

При компрессии методом JPEG качество теряется всегда. При этом всегда есть выбор: отдать предпочтение качеству в ущерб объему (размер файла сожмется приблизительно в три раза) или же наоборот, добиться минимального размера изображения, при котором оно еще останется узнаваемым (степень компрессии может достигать 100). Сжатие, при котором различие в качестве между получающимся изображением и оригиналом еще остается незаметным, дает 10-20-кратное сокращение размера файла.

Область применения

JPEG лучше всего компрессирует полноцветные и монохромные изображения фотографического качества. Если же требуется сохранить картинку с индексной палитрой, то сначала она конвертируется в полноцветную. При компрессии методом JPEG нужно иметь в виду, что все зависит от характера изображений: гораздо меньший объем будут занимать те, где изменения цвета незначительны и нет резких цветовых переходов. JPEG применяется всюду, где нужно хранить фотоизображения: в цифровых фотоаппаратах, полиграфии (EPS DCS 2.0), немыслим без него и Интернет.

Существует несколько разновидностей JPEG-компрессии, мы же рассмотрим только две из них, использующиеся в стандартном пакете для работы с растровыми изображениями Adobe Photoshop, — baseline и progressive . Два других способа — ariphmetic и loseless — экзотика, в силу ряда причин не получившая широкого распространения.

Как происходит сжатие

1. Первый этап заключается в конвертировании цветовой модели изображения (обычно RGB) в модель, где яркостная и цветовая составляющие разнесены (например, YCbCr или YUV), что позволяет оптимально подойти к выбору степеней компрессии для каждого канала (с учетом особенностей восприятия глазом). Преобразование происходит следующим образом:

Y = 0,299xR+0,587*G+0,114xB Cb = (B-Y)/0,866/2+128 Cr = (R-Y)/0,701/2+128

2. На следующем этапе происходит т. н. префильтрация , при которой соседние пиксели отдельно в каждом из каналов Cb и Cr группируются попарно в горизонтальном и вертикальном направлениях, а яркостный канал Y оставляется без изменений. После этого вся группа из четырех пикселов получает усредненное значение соответствующих компонент Cb и Cr. Для краткости такую схему можно обозначить как 4:1:1 (такая же форма представления принята в DRAW — окно экспорта в jpeg). С учетом того, что каждый пиксел кодируется 3 байтами (по 256 уровней для каждого из трех каналов), в результате объем данных автоматически сокращается в 2 раза (вместо 12 байт для передачи 4 пикселов достаточно передать всего 4+1+1 = 6 байт). С точки зрения математики такое преобразование приводит к существенной потере информации, но человеческий глаз потери не воспринимает, поскольку в обычных фотографических изображениях присутствует существенная избыточность.

3. Полученная информация, прошедшая стадию первичной «очистки», отдельно в каждом канале снова группируется в блоки, но уже размером 8x8, после чего для них применяется основное сжатие — т. н. дискретное косинусное преобразование , для краткости — DCT (discrete cosine transform). В результате информация о распределении яркости пикселов преобразуется в другой вид, где она описывается распределением, основанном на частоте появления той или иной яркости пикселов. DCT имеет ряд преимуществ перед другими преобразованиями (например, перед преобразованием Фурье), обеспечивая лучшее восстановление информации.

Вместо массива из 64 значений (8x8 пикселов) для каждого блока, из которых состоит изображение, мы получаем массив из 64 частот. Рассмотрим работу DCT на примере. Допустим, яркость пикселов в одном блоке нашего изображения имеет вид, представленный на рис. 1 слева, тогда результат преобразования будет таким, как показано справа.

1

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

4. Следующий этап — удаление малозаметной глазу информации из блока, или квантование (quantization). Все составляющие делятся на различные коэффициенты, определяющие значимость каждой из них для качественного восстановления исходного изображения, и результат округляется до целого значения. Именно эта процедура вносит наибольшие потери качества, снижая конечный объем изображения. Высокочастотные составляющие квантуются грубо, а низкочастотные — точнее, поскольку наиболее заметны. Дабы несколько сгладить понижение качества, в канале яркости используются меньшие коэффициенты деления, чем в каналах цветности. Но чаще (это делается для ускорения расчетов) вместо специально подобранных значений берется всего одно — то, которое вводит пользователь при выборе степени компрессии.

Вот, например, как выглядит окно Photoshop при сохранении изображения c помощью операции Save for web, где параметр Quality (вернее, производная от него) — тот самый коэффициент округления (рис. 2).

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

4

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

5. После выполнения основной работы по сжатию изображения дальнейшие преобразования сводятся к второстепенным задачам: оставшиеся составляющие собираются в последовательность таким образом, чтобы сначала располагались отвечающие за крупные детали, а потом — за все более мелкие. Если посмотреть на рисунок, то движение кодировщика похоже на зигзагообразную линию. Этап так и называется — ZigZag (рис. 5).

5

Затем получившаяся последовательность сжимается: сначала обычным RLE, затем методом Хаффмана.

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

Вот, в общем, и все преобразования. А теперь давайте подсчитаем, какая компрессия была достигнута в нашем примере. Мы получили 7 значений, по которым восстановится первоначальное изображение размером 8x8. Итак, компрессия от применения DCT-преобразования в обоих каналах цветности составила 8x8/7 ≈ 9 раз. Отведем на канал яркости не семь, а 11 коэффициентов, что даст 8x8/11 ≈ 6. Для всех трех каналов получится (9+9+6)/3=8 раз. Снижение качества при «прореживании» изображения, произошедшего на второй стадии, дает дополнительно двойной прирост (схема 4-1-1, учитывающая особенности кодирования яркостной составляющей), что даст итоговый результат — 16 раз. Это грубый подсчет, не учитывающий некоторых аспектов, но отражающий реальную картину. Чтобы получить тридцатикратное сокращение размера файла, нужно оставить всего 3-4 составляющие.

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

Недостатки JPEG

  1. Невозможность достичь высоких степеней сжатия за счет ограничения на размер блока (только 8x8).
  2. Блочность структуры на высоких степенях компрессии.
  3. Закругление острых углов и размывание тонких элементов в изображении.
  4. Поддерживаются только RGB-изображения (использовать JPEG для CMYK-изображений можно только в формате EPS через DCS).
  5. Изображение нельзя отобразить до тех пор, пока оно не загрузится полностью.

С тех пор, как JPEG был утвержден в качестве стандарта, прошло уже десять лет. За это время группы исследователей предложили ряд существенных дополнений в первоначальный вариант, которые вылились в конце прошлого года в появление нового стандарта.

JPEG2000

С 1997 г. были начаты работы, направленные на создание универсальной системы кодирования, которая снимала бы все ограничения, накладываемые JPEG, и могла эффективно работать со всеми типами изображений: черно-белыми, в градациях серого, полноцветными и многокомпонентными, причем независимо от содержания (будут ли это фотографии, достаточно мелкий текст или даже чертежи). В его разработке принимали участие наряду с международными стандартизирующими организациями такие гранды промышленности, как Agfa, Canon, Fujifilm, Hewlett-Packard, Kodak, LuraTech, Motorola, Ricoh, Sony и др.

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

Основные требования, предъявляемые к формату JPEG2000:

  1. Достижение повышенной по сравнению с JPEG степени компрессии.
  2. Поддержка монохромных изображений, что позволит применять его для компрессии изображений с текстом.
  3. Возможность сжатия вообще без потерь.
  4. Вывод изображений с постепенным улучшением детализации (как в progressive GIF).
  5. Использование в изображении приоритетных областей, для которых качество может устанавливаться выше, чем в остальной части изображения.
  6. Декодирование в реальном режиме времени (без задержек).

Принцип сжатия

В качестве основного механизма компрессии в JPEG2000, в отличие от JPEG, используется волновое (wavelet) преобразование — система фильтров, применяемых ко всему изображению. Не вдаваясь в детали компрессии, отметим лишь основные моменты.

6
Сначала точно так же, как и для JPEG, происходит конвертирование изображения в систему YCrCb, после чего — первичное удаление избыточной информации (путем уже известного объединения соседних пикселей в блоки 2x2). Затем все изображение делится на части одинакового размера (tile), над каждой из которых независимо от других и будут происходить дальнейшие преобразования (это снижает требования к объему памяти и вычислительным ресурсам). Далее каждый канал проходит фильтрацию низкочастотным и высокочастотным фильтрами отдельно по строкам и по рядам, в результате чего после первого прохода в каждой части формируются четыре более мелких изображения (subband). Все они несут информацию об исходном изображении, но их информативность сильно отличается (рис. 6).

Например, изображение, полученное после низкочастотной фильтрации по строкам и рядам (вверху слева), несет наибольшее количество информации, а полученное после высокочастотной — минимальное. Информативность у изображений, полученных после НЧ-фильтрации строк и ВЧ для столбцов (и наоборот), средняя. Наиболее информативное изображение опять подвергается фильтрации, а полученные составляющие, как и при jpeg-компрессии, квантуются. Так происходит несколько раз: для сжатия без потерь цикл обычно повторяется 3 раза, с потерями — разумным компромиссом между размером, качеством и скоростью декомпрессии считается 10 итераций. В результате получается одно маленькое изображение и набор картинок с мелкими деталями, последовательно и с определенной точностью восстанавливающих его до нормального размера. Очевидно, что наибольшая степень компрессии получается на крупных изображениях, поскольку можно установить большее количество циклов.

Практическая реализация

С тех пор, как были заложены основы компрессии методом JPEG2000, ряд компаний разработал достаточно эффективные алгоритмы ее реализации.

Среди крупных разработчиков ПО можно отметить Corel (кстати, она одна из первых внедрила в свои пакеты поддержку формата wi, основанного на волновых преобразованиях, за что ей честь и хвала) — все изображения, поставляемые на компакт-дисках с пакетом CorelDRAW вплоть до девятой версии, сжимались именно таким способом.

Позже к ней подтянулась и Adobe. Часть идей, заложенных в JPEG2000, была применена разработчиками Photoshop 6 в виде продвинутых опций при сохранении изображения в формате JPEG (обычном, основанном на косинусном преобразовании). Среди них — прогрессивный JPEG (параметр Progressive в окне Save for Web). Этот алгоритм предназначен, главным образом, для систем реального времени и работает точно так же, как и прогрессивный GIF. Сначала появляется грубая копия изображения, состоящая всего из нескольких блоков большого размера, а со временем, когда подгружаются остальные данные, структура начинает просматриваться все четче, пока, наконец, конечное изображение не восстановится полностью. В отличие от GIF, такой алгоритм создает большую нагрузку на просмотрщик, поскольку ему придется полностью выполнять весь цикл преобразований для каждой передаваемой версии.

Из других дополнений отметим включение в файл нескольких JPEG-сжатых изображений с разной степенью компрессии, разрешением и даже цветовыми моделями. Соответственно, в Photoshop 6 появилась возможность выделять в изображении отдельные области и применять для них другие установки компрессии (Region-Of-Interest , впервые такой механизм был предложен еще в 1995 г.), используя более низкие значения в таблице квантования. Для этого задается требуемая область (например, в виде нового канала в изображении) и нажимается пиктограмма маски возле пункта Quality (Качество). В появившемся окне можно экспериментировать с изображением, передвигая ползунки, — готовый результат отображается на экране, позволяя быстро находить необходимый компромисс между качеством и размером.

Специализированные конверторы и просмотрщики

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

Специализированные решения от других компаний доступны в виде коммерческих разработок. Одни реализованы в виде отдельных программ (JPEG 2000 разработки Aware), другие — в виде дополнительных модулей для наиболее распространенных растровых редакторов (ImagePress JPEG2000 разработки Pegasus Imaging и модуль LEAD JPEG2000 от LEAD Technologies). На их фоне выделяется компания LuraTech, давно занимающаяся этим вопросом. Она продвигает свою технологию LuraWave в самодостаточном продукте LuraWave SmartCompress (доступна уже третья версия) и предлагает модули для Photoshop, Paintshop, Photopaint. Отличительная особенность — более высокая скорость работы (практически мгновенное преобразование) даже с картинками размером в несколько мегабайт. Соответственно и цена этого модуля самая высокая — 79 долл.

Чтобы просматривать JPEG2000-изображения браузерами, необходимо установить специальный модуль-просмотрщик (все разработчики предлагают его бесплатно). Вставка изображения в html-документ, как и любого plug-in, сводится к использованию конструкции EMBED (с дополнительными параметрами). Например, означает, что будет использоваться прогрессивный метод переда- чи изображения. То есть в нашем примере (файл размером 139 Кбайт) сначала передаются только 250 байт, на основании которых будет построено грубое изображение, затем, после дозагрузки 500 байт, изображение обновляется (так продолжается до достижения значения LIMIT).

Если вы захотите получить более качественное изображение, нужно выбрать пункт Improve из меню, всплывающего по правой кнопке (рис. 9). За четыре докачки все изображение будет загружено полностью.

9

Выводы

Итак, JPEG2000 объективно показывает лучшие результаты, чем JPEG только на высоких степенях сжатия. При компрессии в 10-20 раз особой разницы не заметно. Сможет ли он вытеснить или просто составить конкуренцию широко распространенному формату? В ближайшее время — вряд ли, в большинстве случаев соотношение качество/размер, обеспечиваемое JPEG, вполне приемлемо. А те 10-20% дополнительной компрессии, которые дает JPEG2000 при визуально одинаковом качестве, вряд ли приведут к росту его популярности.

Зато к новому формату проявляют пристальный интерес компании-производители цифро- вых камер, поскольку размеры светочувствительных матриц с каждым годом неуклонно увеличиваются, и помещать изображения в память становится все труднее. И вот тогда новый формат получит большее распространение, и кто знает, возможно, через какое-то время JPEG2000 сравняется с JPEG. Во всяком случае, Analog Micro Devices недавно выпустила специализированный чип, в котором компрессия/декомпрессия по новой технологии реализованы на аппаратном уровне, а министерство обороны США уже сейчас активно использует новый формат для записи фотоснимков, полученных со спутников-шпионов.

Факты и домыслы

1. JPEG теряет качество при открытии и повторном сохранении файла.

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

2. JPEG теряет качество при редактировании файла.

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

3. Результат компрессии с одинаковыми параметрами в разных программах будет одинаков.

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

4. При установке максимального качества изображение сохраняется без каких-либо потерь качества.

Неправда. JPEG сжимает с потерями всегда. Но установка, например, 90% качества вместо 100% дает сокращение размера файла большее, чем воспринимаемое глазом ухудшение качества.

5. Любой файл JPEG можно открыть в любом редакторе, понимающем формат JPEG.

Неправда. Такую разновидность JPEG, как прогрессивный (progressive JPEG), некоторые редакторы не понимают.

6. JPEG не поддерживает прозрачность.

Правда. Иногда может казаться, что какая-то часть изображения прозрачна, но на самом деле ее цвет просто подобран так, чтобы он совпадал с цветом фона в html-странице.

7. JPEG сжимает лучше, чем GIF.

Неправда. У них разная область применения. В общем случае, типичная «гифовская» картинка после конвертирования в JPEG будет иметь больший объем.

JPEG2000 против JPEG

7
1. При двадцати-тридцатикратном сжатии JPEG2000 и JPEG дают приблизительно одинаковое качество (кстати говоря, Photoshop не может сжать обычную фотографию больше этого предела).

2. При большем сжатии качество JPEG2000 существенно выше, чем у JPEG, что позволяет без особых потерь сжимать до 50 раз, а с некоторыми потерями (речь идет об изображениях для Интернет) — до 100 и даже до 200.

3. При больших степенях компрессии в тех областях, где происходит плавное изменение цвета, изображение не приобретает характерную для простого JPEG блочную структуру. JPEG2000 также несколько размазывает и закругляет острые контуры — см. фотографии (рис. 7 и 8).

На нем представлены результаты компрессии тестового файла с разными степенями компрессии (слева — сохраненные в Photoshop в формате JPG, справа — в формате JPEG2000). Для изображения на рис. 7 были выбраны степени компрессии 20, 40, 70 и 145 (их можно явно указывать при сохранении в JPEG2000), степень сжатия JPG выбиралась из того расчета, чтобы размер файла был таким же, как после сжатия по JPEG2000. Как говорится, результаты налицо. Для чистоты был проведен второй эксперимент на изображении с более четкими деталями (со степенями компрессии 10, 20, 40 и 80). Преимущество опять же на стороне JPEG2000 (рис. 8).

8

4. Поскольку, по сути, в одном JPEG2000-файле хранятся копии с разным разрешени

ем, для тех, кто делает галереи изображений в Интернете, отпадает необходимость создавать для них thumbnails.

5. Особый интерес представляет компрессия без искажений (режим loseless). Так, тестовый файл при LZW-сжатии из Photoshop занял 827 Кбайт, а сжатый JPEG2000 — 473 Кбайт.

6. По сравнению с JPEG его более продвинутый тезка потребляет значительно больше системных ресурсов. Но существенно возросшая за последние пару лет мощь компьютеров позволяет успешно решать задачи сжатия изображений новым методом.

7. Отсутствие поддержки JPEG2000 в браузерах. Чтобы просматривать такие изображения, нужно скачать довольно большой дополнительный модуль (1,2 Мбайта).

8. Отсутствие бесплатного ПО для сохранения изображений в новом формате.

Журналов в свободном доступе.

На ту же тему:


Адаптивная генерация матриц квантования в JPEG-подобных схемах

Лужков Юрий Валерьевич,

аспирант Санкт-Петербургского государственного университета информационных технологий, механики и оптики.

Научный руководитель – доктор технических наук, профессор

Тропченко Александр Ювенальевич .

Введение

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

Широкая распространенность формата JPEG (Joint Photographic Experts Group ) [Wallace G. K.] ставит перед исследователями следующий вопрос: возможно ли модифицировать существующую схему компрессии таким образом, чтобы увеличить качество сжатия, не меняя при этом алгоритм декомпрессии? Решение этой задачи позволит внедрять модификации в существующие компрессоры, не заботясь о наличии у пользователей специального (модифицированного) программного обеспечения для декомпрессии изображений.

Под JPEG-подобной схемой будем понимать вариант схемы сжатия с разбиением изображения на прямоугольные фрагменты, обязательными элементами которой являются: ортогональное преобразование, квантование преобразованных данных и их последующее статистическое кодирование.

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

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

Адаптивное квантование сигнала

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

Так, пусть дано множество интервалов и множество точек , тогда функция квантования определяется как для . В случае равномерного скалярного квантования множество интервалов можно представить в виде:

где – параметр, или шаг квантования , – базовое смещение интервалов, , – номер интервала, который и является кодируемым объектом. Тогда операция квантования может быть сведена к простому делению с округлением:

.(1)

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

Адаптивное скалярное квантование на основе весового критерия

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

Так, пусть дана последовательность величин, разбитая на M одинаковых блоков по N значений в каждом, причем – индекс элемента в данном блоке, то есть каждый элемент имеет свой аналог в любом другом блоке. Суть предлагаемого подхода заключается в следующем: для каждого n –го элемента вычисляется значение специального весового критерия, и шаг квантования данного элемента спектра устанавливается тем больше, чем меньше соответствующее ему значение весового критерия.

Таким образом, процедура квантования выполняется с учетом некоторой статистической информации о сигнале, заданном как , собранной от M блоков и уникальной для элементов каждого индекса n . Функция квантования (1) в этом случае будет обозначаться как , а функция параметра квантования – .

Введём критерий , назвав его весом коэффициента спектра . Величина будет отражать степень значимости соответствующей спектральной позиции n коэффициентов .

Одним из способов вычисления базируется на средних амплитудах:

.(2)

Как показали эксперименты, расчет по (2) для коэффициентов ДКП ведет непропорциональному распределению значений критерия для высоко- и низкочастотных коэффициентов спектра. Исправить ситуацию можно, используя корректирующую функцию (см. ниже), либо вычисляя значения на основе максимальных амплитуд:

.(3)

Обратимся к вопросу определения функции . Пусть её значения должны быть ограничены диапазоном . Введём линейную функцию от :

,

где и – минимальное и максимальное значение соответственно (случай рассматривается отдельно).

На практике бывает выгодно использовать нелинейную функцию от , что достигается за счет использования корректирующей функции :

.(4)

Поскольку любой в общем случае зависит от всех элементов исходного спектрального вектора , функция E также зависит от . Фактически, это есть функция шага квантования сигнала . Введем обозначение . Тогда формула (4) окончательно принимает вид:

.(5)

Таким образом, функция шага квантования локализована в диапазоне от a 1 до a 2 .Варьируя её форму, можно в большей или меньшей степени подавлять определённые группы коэффициентов.

Применим теперь предложенный подход для адаптивной генерации матриц квантования в схеме JPEG . В (5) будем использовать линейную корректирующую функцию и критерий максимальных амплитуд (3).

Графики функций по умолчанию шага квантования JPEG приведены на рис. 1, слева. Графики Δ, адаптивно сгенерированные для изображения « Oldman », показаны на рис. 1, справа. В обоих случаях значения упорядочены по возрастанию. Как видно, для первой трети значений аргумента наблюдается резкий рост Δ, что особенно характерно для сгенерированных функций. На этом участке сгенерированные Δ местами значительно превосходят по величине стандартные, что ведет к большему подавлению соответствующих частот.


Рис. 1. Стандартные и сгенерированные функции параметра квантования с упорядоченными

по возрастанию значениями.

График для изображения « Oldman » приведен на рис. 2, слева. Справа показаны результаты компрессии с применением матриц по умолчанию и матриц, сгенерированных в рамках эксперимента. Как видно из результатов, разница в степени сжатия составляет до 20 % в пользу адаптивного подхода при одинаковых значениях PSNR .


Рис. 2. Генерация адаптивных матриц квантования для схемы JPEG .

Заключение

Нами предложен способ адаптивного скалярного квантования коэффициентов спектра, основанный на вычислении критерия значимости спектральных компонент. Как показали эксперименты, использование рассмотренного подхода в схеме JPEG позволяет получить выигрыш по степени сжатия до 20 % по сравнению с использованием стандартных матиц квантования.

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

Литература

1. Fung H. T., Parker K. J. Design of image-adaptive quantization tables for JPEG // Journal of Electronic Imaging. – 1996. – Vol. 4, N. 2. – P. 144 – 150.

2. Gray R.M., Neuhoff D.L. Quantization // IEEE Transactions on Information Theory. – 1998. – Vol. 44, N. 6. – P. 2325 – 2383.

3. Ratnakar V., Livny M. Extending RD -OPT with global thresholding for JPEG optimization // Data Compression Conference. – 1996.

4. Wallace G. K. The JPEG still picture compression standard // IEEE Trans. Consumer Electronics. – 1992. – Vol. 38, N. 1. – P. 18 – 34.

Область применения

Формат является форматом сжатия с потерями, поэтому некорректно считать что JPEG хранит данные как 8 бит на канал (24 бит на пиксел). С другой стороны, так как данные, подвергающиеся компрессии по формату JPEG и декомпрессированые данные обычно представляются в формате 8 бит на канал, иногда используется эта терминология. Поддерживается также сжатие чёрно-белых полутоновых изображений.

При сохранении JPEG-файла можно указать степень качества, а значит и степень сжатия, которую обычно задают в некоторых условных единицах, например, от 1 до 100 или от 1 до 10. Большее число соответствует лучшему качеству, но при этом увеличивается размер файла. Обыкновенно, разница в качестве между 90 и 100 на глаз уже практически не воспринимается. Следует помнить, что восстановленное из формата JPEG изображение не является точной копией оригинала. Распространённым заблуждением является мнение о том, что качество JPEG тождественно доле сохраняемой информации.

Широкая поддержка формата JPEG разнообразным ПО нередко приводит к кодированию в JPEG изображений, для того не предназначенных - безо всякого выигрыша по степени сжатия в сравнении с правильно сделанными PNG или GIF, но с прискорбными последствиями для качества. Например, попытка записать в JPEG изображение, содержащее мелкие контрастные детали (особенно, цветные) приведёт к появлению характерных хорошо заметных артефактов даже при высокой «степени качества».

Сжатие

При сжатии изображение преобразуется из цветового пространства RGB в YCbCr (YUV). Следует отметить, что стандарт JPEG (ISO/IEC 10918-1) никак не регламентирует выбор именно YCbCr, допуская и другие виды преобразования (например, с числом компонентов, отличным от трёх), и сжатие без преобразования (непосредственно в RGB), однако спецификация JFIF (JPEG File Interchange Format, предложенная в 1991 году специалистами компании C-Cube Microsystems, и ставшая в настоящее время стандартом де-факто) предполагает использование преобразования RGB->YCbCr.

После преобразования RGB->YCbCr для каналов изображения Cb и Cr, отвечающих за цвет, может выполняться "прореживание" (subsampling, которое заключается в том, что каждому блоку из 4 пикселов (2х2) яркостного канала Y ставятся в соответствие усреднённые значения Cb и Cr (схема прореживания "4:2:0". При этом для каждого блока 2х2 вместо 12 значений (4 Y, 4 Cb и 4 Cr) используется всего 6 (4 Y и по одному усреднённому Cb и Cr). Если к качеству восстановленного после сжатия изображения предъявляются повышенные требования, прореживание может выполняться лишь в каком-то одном направлении — по вертикали (схема "4:4:0") или по горизонтали ("4:2:2"), или не выполняться вовсе ("4:4:4").

Стандарт допускает также прореживание с усреднением Cb и Cr не для блока 2х2, а для четырёх расположенных последовательно (по вертикали или по горизонтали) пикселов, то есть для блоков 1х4 или 4х1 (схема "4:1:1"). Допускается также использование различных типов прореживания для Cb и Cr, но на практике такие схемы встречаются исключительно редко.

Далее, яркостный компонент Y и отвечающие за цвет компоненты Cb и Cr разбиваются на блоки 8х8 пикселов. Каждый такой блок подвергается дискретному косинусному преобразованию (ДКП). Полученные коэффициенты ДКП квантуются (для Y, Cb и Cr в общем случае используются разные матрицы квантования) и пакуются с использованием кодов Хаффмана. Стандарт JPEG допускает также использование значительно более эффективного арифметического кодирования, однако, из-за патентных ограничений (патент на описанный в стандарте JPEG арифметический QM-кодер принадлежит IBM) на практике оно не используется.

Матрицы, используемые для квантования коэффициентов ДКП, хранятся в заголовочной части JPEG-файла. Обычно они строятся так, что высокочастотные коэффициенты подвергаются более сильному квантованию, чем низкочастотные. Это приводит к огрублению мелких деталей на изображении. Чем выше степень сжатия, тем более сильному квантованию подвергаются все коэффициенты.

Разновидности схем сжатия JPEG

Стандарт JPEG предусматривает два основных способа представления кодируемых данных.

Наиболее распространённым, поддерживаемым большинством доступных кодеков, является последовательное (sequential JPEG) представление данных, предполагающее последовательный обход кодируемого изображения поблочно слева направо, сверху вниз. Над каждым кодируемым блоком изображения осуществляются описанные выше операции, а результаты кодирования последовательно помещаются в выходной поток в виде единственного «скана» (массива кодированных данных). Основной или «базовый» (baseline) режим кодирования допускает только такое представление. Расширенный (extended) режим наряду с последовательным допускает также прогрессивное (progressive JPEG) представление данных.

В случае progressive JPEG сжатые данные записываются в выходной поток в виде набора сканов, каждый из которых описывает изображение полностью с всё большей степенью детализации. Это достигается либо путём записи в каждый скан не полного набора коэффициентов ДКП, а лишь какой-то их части: сначала — низкочастотных, в следующих сканах — высокочастотных (метод «spectral selection» т.е. спектральных выборок), либо путём последовательного, от скана к скану, уточнения коэффициентов ДКП (метод «successive approximation», т.е. последовательных приближений). Такое прогрессивное представление данных оказывается особенно полезным при передаче сжатых изображений с использованием низкоскоростных каналов связи, поскольку позволяет получить представление обо всём изображении уже после передачи незначительной части JPEG-файла.

Обе описанные схемы (и sequential, и progressive JPEG) базируются на ДКП и принципиально не позволяют получить восстановленное изображение абсолютно идентичным исходному. Однако, стандарт допускает также сжатие, не использующее ДКП, а построенное на основе линейного предсказателя (lossless, т.е. «без потерь», JPEG), гарантирующее полное, бит-в-бит, совпадение исходного и восстановленного изображений. При этом коэффициент сжатия для фотографических изображений редко достигает 2, но гарантированное отсутствие искажений в некоторых случаях оказывается востребованным. Заметно большие степени сжатия могут быть получены при использовании не имеющего, несмотря на сходство в названиях, непосредственного отношения к стандарту JPEG ISO/IEC 10918-1 (ITU T.81 Recommendation) метода сжатия JPEG-LS, описываемого стандартом ISO/IEC 14495-1 (ITU T.87 Recommendation).

Синтаксис и структура

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

Основные маркеры JPEG
Маркер Байты Длина Назначение

После вычисления всех коэффициентов DCT их необходимо проквантовать. На этом шаге происходит отбрасывание части информации (небольшие потери происходят и на предыдущем шаге из-за конечной точности вычислений на компьютере). Каждое число из матриц коэффициентов DCT делится на специальное число из «таблицы квантования», а результат округляется до ближайшего целого. Как уже отмечалось, необходимо иметь три такие таблицы для каждой цветовой компоненты. Стандарт JPEG допускает использование четырех таблиц, и пользователь может выбрать любую из этих таблиц для квантования компонентов цвета. Все 64 числа из таблицы квантования являются параметрами JPEG. В принципе, пользователь может поменять любой коэффициент для достижения большей степени сжатия. На практике весьма сложно экспериментировать с таким большим числом параметров, поэтому программное обеспечение JPEG использует два подхода:

1. Таблица квантования, принятая по умолчанию. Две такие таблицы, одна для компоненты светимости (и для градации серого цвета), а другая для хроматических компонент, являются результатом продолжительного исследования со множеством экспериментов, проделанных комитетом JPEG. Они являются частью стандарта JPEG и воспроизведены в табл. 3.50. Видно, как коэффициенты QC таблиц растут при движении из левого верхнего угла в правый нижний угол. В этом отражается сокращение коэффициентов DCT, соответствующих высоким пространственным частотам.

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

Светимость

Если квантование сделано правильно, то в блоке коэффициентов DCT останется всего несколько ненулевых коэффициентов, которые будут сконцентрированы в левом верхнем углу матрицы. Эти числа являются выходом алгоритма JPEG, но их следует еще сжать перед записью в выходной файл. В литературе по JPEG это сжатие называется «энтропийным кодированием», детали которого будут разбираться в § 3.7.5. Три технических приема используется при энтропийном кодировании для сжатия целочисленных матриц 8x8.

3. 64 числа выстраиваются одно за другим как при сканировании зигзагом (см. рис. 3.5а). В начале стоят ненулевые числа, за которыми обычно следует длинный хвост из одних нулей. В файл выводятся только ненулевые числа (после надлежащего кодирования) за которыми следует специальный код ЕОВ (end-of-block, конец блока). Нет необходимости записывать весь хвост нулей (можно также сказать, что ЕОВ кодирует длинную серию нулей).

Пример : В табл. 3.51 приведен список гипотетических коэффициентов DCT, из которых только 4 не равны нулю. При зигзагообразном упорядочении этих чисел получается последовательность коэффициентов:

Табл. 3.51. Квантованные коэффициенты.

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

Если компоненты структуры zz обозначить zz.r и zz.с, то путь по зигзагу можно совершить с помощью следующего цикла

4. Ненулевые коэффициенты преобразования сжимаются по методу Хаффмана (см. § 3.7.5).

5. Первое из этих чисел (коэффициент DC, см. стр. 145) обрабатывается отдельно от других чисел (коэффициентов АС).

Рис. 3.52. Координаты зигзагообразного пути.