Найти тему

Что такое гамма кривая и зачем композерам работать в линейной гамма-кривой?

Оглавление

Блок 1: не то, чем кажется

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

Для подтверждения, вот так выглядит вейвформа изображения:

-2

Абсолютно линейный градиент от 0 до 100 нит.

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

-3

И взглянем на его левую:

-4

И правую части:

-5

Думаю большинство ответило, что в левой части изменение оттенков более заметно, чем справа. Это подводит нас к мысли, что абсолютно линейной изменение яркости наш глаз видит нелинейно: изменение яркости в темных оттенках заметно лучше, чем в светлых. Если мы попробуем выразить эту зависимость изменения яркости для глаза (ось Y) от действительных значений (ось X), то на выходе получим примерно вот такую кривую:

-6

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

-7

Эта кривая близка к функции гаммы 2.2:

y = x^(1/«gamma value»)

Да да, а вы че думали, матан в жизни не пригодится?

Поэтому там, где программа показывает 0.218, нам кажется, что там четкие 0.5.

При отображении линейной зависимости для нашего глаза в тенях на 1 стоп экспозиции будет приходиться буквально несколько единиц изменения значений rgb. Тогда как в светлых участках на 1 стоп приходится 128 единиц rgb. Все это приводит к нерациональное использование памяти

-8

Выводы на данный момент:

  • Наш глаз видит мир нелинейно
  • В тенях мы видим изменение яркости лучше, чем в светлых участках

Блок 2: И овцы целы, и волки сыты

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

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

y = x^«gamma value»

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

Сделаем выводы:

  • записывая изображение с применением гамма-кривой, мы можем эффективно сохранять детали для нашего глаза
  • для корректного отображения таких файлов в устройстве просмотра применяется обратная гамма-функция

Блок 3: про работу в линейном пространстве

Ладно, с энкодингом и декодингом разобрались, но зачем нам надо работать в линейной кривой?

И не опять, а снова, будем все познавать на примерах. Допустим, на входе имеем солид со значениями по всем 3-м каналам в 0.2.

-9

Если мы работаем в нелинейной кривой, то при увеличении значения в 2 раза мы получим… значение примерно 0,93.

-10

Согласитесь, не совсем то, что нам нужно было.

Теперь же умножим на два исходник, работая в линейной кривой:

-11

Теперь мы получили желаемое значение в 0,4.

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

Обобщаем:

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

Причина применения гамма-коррекции:

  • Эффективное хранение данных

Причина работы в линейном пространстве:

  • Корректная обработка с использованием математических операций

Источники: