feat: подробнее описан JPEG
This commit is contained in:
@ -102,5 +102,50 @@ JPEG - формат хранения изображения с потерями.
|
|||||||
|
|
||||||
Процесс сжатия в этом формате довольно длинный. Подробно все шаги пояснять не буду, потому что это ну прям совсем хана
|
Процесс сжатия в этом формате довольно длинный. Подробно все шаги пояснять не буду, потому что это ну прям совсем хана
|
||||||
|
|
||||||
|
1. Для того, чтобы применить знание о том, что наш глаз лучше воспринимает перепады яркости, чем цвета, нам нужно как-то отделить цвета от яркости. Эта задача была решена еще во времена появления цветных телевизоров. Так как переход с ч/б на цветные был постепенный, надо было научиться как-то транслировать изображение, чтобы его могли читать и те и другие модели.
|
||||||
|
|
||||||
|
Тогда же были получены формулы перевода из RGB в другой формат - цветоразностное кодирование^[Далее в эфир 3 полученных числа кодировались по 3 раздельным каналам. ЧБ телевизоры воспринимали только один - $Y$, а цветные - все 3 канала] (яркость, коэф синего, коэф красного). $Y$ - яркость: $Y = 0.299R + 0587G + 0.144B$. $Cb$ - коэффициент синего: $Cb= 0.1687R -0.3313G +0.500B$. И $Cr$ - коэффициент красного: $Cr= 0.500R -0.4187G +0.0813B$.
|
||||||
|
Теперь именно при помощи этих чисел мы будем записывать все пиксели исходного изображения
|
||||||
|
|
||||||
|
2. На втором шаге мы уже сделаем сжатие - отбросим часть цветовых данных, но сохраним яркость. Глаз не очень чувствителен к такому изменению
|
||||||
|
|
||||||
|
Для этого изменим немного кодирование данных: возьмем квадрат 2х2 пикселя и будем считать, что он весь закрашен одним цветом, но при этом сохраним все значения яркостей. То есть вместо кодирования всех трех компонент для каждого отдельного пикселя, для каждого пикселя мы кодируем только яркость, а цвет кодируем для всего квадрата сразу. Таким образом из 12 значений (по 3 компоненты на каждый пиксель) мы получаем всего 6 (4 значения на яркости отдельных пикселей и 2 значения на цвет квадрата). Уже на этом этапе мы уменьшили размер изображения в 2 раза, а качество для нашего глаза еще не пострадало
|
||||||
|
|
||||||
|
3. Следующий шаг самый сложный как для реализации, так и для понимания. Упирается он в следующее размышление - у нас может быть разная детализация изображения. В какой-то области находится много мелких деталей, а в какой-то меньше. Это очень легко увидеть на картинах художников. Наша задача определить места, где мало деталей и закодировать их меньшим количеством информации. *Наша задача понять, что же с технической точки зрения означает "количество деталей"*
|
||||||
|
|
||||||
|
Размышления над этим привели к страшной математике: [дискретному косинусному преобразованию](https://ru.wikipedia.org/wiki/Дискретное_косинусное_преобразование). *Про его устройство Молодяков не пишет и надеюсь не спрашивает*.
|
||||||
|
|
||||||
|
Изображение разбивается на блоки 8х8^[Сейчас размеры блока яркости удваиваются и яркость кодируется блоками по 16 на 16]. Внутри этих блоков мы берем отдельно 3 компоненты (те самые яркость и 2 цвета) и отдельно над каждой проводим одни и те же манипуляции: берем их значения и из интервала 0-255 переводим в -128 -127. Было доказано, что любые значения в получившейся матрице можно получить сложением 64-х отдельных элементарных (и не очень) матриц. Все они получены были косинусным преобразованием и выглядят так:
|
||||||
|
|
||||||
|
![[Pasted image 20241109173751.png]]
|
||||||
|
|
||||||
|
Дальше идет не очень понятный мне этап преобразования исходной матрицы 8 на 8 к матрице по примерно следующей формуле:
|
||||||
|
|
||||||
|
$$
|
||||||
|
G_{ij} = \frac{1}{4} C_{i}C_{j}\sum_{x=0}^{7} \sum_{x=1}^{7} p_{xy}\cos\left( \frac{(2y+1)j\pi}{16} \right)\cos\left( \frac{(2x+1)i\pi}{16} \right)
|
||||||
|
$$
|
||||||
|
|
||||||
|
Тут боюсь я и сам не в курсе, откуда она взялась.
|
||||||
|
|
||||||
|
В общем на выходе получается примерно следующая матрица
|
||||||
|
|
||||||
|
![[Pasted image 20241109180727.png]]
|
||||||
|
|
||||||
|
Для нас самое важное сейчас то, что чем ближе к правому нижнему углу, тем числа ниже. При этом эта матрица кодирует "значимость элементов для нашего глаза"^[Не спрашивайте как до этого додумались. Разработка формата по некоторым источникам велась 6 лет. Я не смогу ужать 6 лет страданий ученых в 3 абзаца] %%Может быть дополню когда-нибудь маленькой заметкой откуда взялось уравнение и в чем его основная идея. По крайней мере полезно будет для моего ящика для заметок%%.
|
||||||
|
4. Далее из-за пазухи достаем уже заранее за нас составленную матрицу квантования и делим попарно элементы матрицы после преобразования на матрицу квантования^[Замечу, что для яркости одна матрица кватнования, а для цвета другая. Все матрицы квантования подбирались опытным путем (и существенное время). Отрегулировать степень сжатия можно умножением этих матриц на константу] и округляем значения
|
||||||
|
|
||||||
|
![[Pasted image 20241109181231.png]]
|
||||||
|
|
||||||
|
После этого процесса получилось очень много ноликов - этого мы и добивались - выжили только существенные детали, а остальные съело делением. Вот эту-то матрицу мы и будем хранить.
|
||||||
|
|
||||||
|
Для того, чтобы компактнее сохранить эту матрицу, но не выбросить все числа из нее, мы снова будем сжимать ее без потерь. Собственно для этого мы и добивались, чтобы было как можно больше нулей. Нам нужно сохранить матрицу так, чтобы как можно большее количество нулей шло подряд. Как я уже говорил, наиболее трудноразличимые детали располагаются в нижнем правом углу, то есть вероятность того, что в ячейке матрицы не ноль уменьшается по мере продвижения по диагонали вправо вниз
|
||||||
|
|
||||||
|
Поэтому решили записывать числа зигзагом по этому направлению:
|
||||||
|
|
||||||
|
![[Pasted image 20241109181855.png]]
|
||||||
|
|
||||||
|
5. После того, как мы писали этот ужас мы сжимаем его страшной помесью Хаффмана и RLE. Описывать я это дело пожалуй не буду, просто скажу, что таблицы для алгоритма Хаффмана построены заранее.
|
||||||
|
|
||||||
|
В целом этот алгоритм позволяет сжимать изображения в десятки раз. (вплоть до 50-кратного уменьшения размера)
|
||||||
|
|
||||||
|
|
||||||
BIN
Приложения/Pasted image 20241109173751.png
Normal file
BIN
Приложения/Pasted image 20241109173751.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 176 KiB |
BIN
Приложения/Pasted image 20241109180727.png
Normal file
BIN
Приложения/Pasted image 20241109180727.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 170 KiB |
BIN
Приложения/Pasted image 20241109181231.png
Normal file
BIN
Приложения/Pasted image 20241109181231.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 230 KiB |
BIN
Приложения/Pasted image 20241109181855.png
Normal file
BIN
Приложения/Pasted image 20241109181855.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 198 KiB |
Reference in New Issue
Block a user