5.19. Тональна корекція

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

Корекції поділяються на дві групи: регулювання яскравості та контрасту, що перерозподіляють яскравість, та корекції кольору, що змінюють, яким кольором читається кожен піксель. Обидві мають аналоги в ISP датчика, який коригує кожен кадр під час надходження; методи, описані тут, застосовуються до вже захопленого Image – після факту – у випадках, коли кадр потребує більшої корекції, ніж забезпечив ISP.

5.19.1. Вирівнювання гістограми

Найпростіша операція розтягування контрасту – вирівнювання гістограми. Ідея полягає в перетворенні значень пікселів так, щоб гістограма вихідного зображення була якомога більш рівномірною – кожне значення зустрічається приблизно однакову кількість разів. Візуальний ефект: зображення з низьким контрастом (з гістограмою, зосередженою у вузькому діапазоні) перетворюється на зображення з високим контрастом, пікселі якого охоплюють весь діапазон від 0 до 255.

histeq() виконує вирівнювання:

img.histeq()

Механізм прямолінійний. Обчислюється функція кумулятивного розподілу (CDF) гістограми джерела; кожне вхідне значення пікселя відображається на відповідну позицію у CDF, масштабовану до вихідного діапазону. Там, де пікселі вже рівномірно розподілені, відображення близьке до тотожного; там, де пікселі скупчились на певній яскравості, відображення розподіляє їх, розтягуючи цю яскравість на більший діапазон вихідних значень.

Результат вражає на сценах із низьким контрастом – різниця між тьмяною кімнатною фотографією та тією ж фотографією після histeq часто є різницею між «нечитабельним» і «цілком розбірливим». Компроміс у тому, що операція підсилює все, включно з шумом датчика. На сцені з реальними деталями низького контрасту, які потрібно відновити, histeq – правильний вибір; на чистій, добре експонованій сцені, яка цього не потребує, histeq вносить видимий шум.

5.19.2. CLAHE: адаптивне вирівнювання

Вирівнювання гістограми є глобальним: воно використовує одну CDF, обчислену для всього зображення, і застосовує її скрізь. Це працює на зображеннях із приблизно рівномірним діапазоном яскравості, але дає збій на сценах із локалізованими темними та яскравими ділянками – CDF зміщується в бік ділянки з більшою кількістю пікселів, а протилежна ділянка отримує надмірну корекцію.

Адаптивний варіант – Контрастно-обмежене адаптивне вирівнювання гістограми, яке зазвичай називають CLAHE. Замість однієї глобальної CDF, CLAHE обчислює окрему CDF для кожної малої плитки зображення, вирівнює кожну плитку за власною CDF і плавно зводить межі плиток. В результаті регулювання яскравості відбувається локально – затінений кут отримує своє вирівнювання, і яскравий кут не тягне його у неправильний бік.

Прапор adaptive=True перемикає histeq() в режим CLAHE:

img.histeq(adaptive=True, clip_limit=10)

Параметр clip_limit – це та частина CLAHE, на яку вказує слово «контрастно-обмежений» у назві. Локальне вирівнювання може надмірно підсилювати шум у плоских ділянках, де CDF має дуже мало різних значень; ліміт відсічення обмежує агресивність перерозподілу окремих бінів, що запобігає підсиленню шуму, водночас зберігаючи розтягування контрасту там, де це важливо. Значення близько 10 є розумною відправною точкою; більші значення дозволяють CLAHE працювати інтенсивніше ціною більш видимого шуму, менші – роблять його м’якшим.

CLAHE дорожче, ніж глобальний histeq, але дає чистіші результати на сценах із нерівномірно розподіленою яскравістю – а це більшість реальних сцен.

5.19.3. Гамма, контраст і яскравість

Вирівнювання гістограми – це спосіб перетворення яскравості на основі даних. Незалежний від даних спосіб – застосування вибраної кривої, параметризованої кількома зручними регуляторами. gamma() надає три:

img.gamma(gamma=1.0, contrast=1.0, brightness=0.0)

Кожен параметр застосовує одне конкретне перетворення до кожного пікселя:

gamma пропускає значення кожного пікселя через степеневу функцію output = input ** (1 / gamma). Стандартний зміст: значення більше 1.0 освітлюють зображення та підіймають середні тони (класична корекція «гами монітора»); значення менше 1.0 затемнюють його. Параметр нелінійний – він зберігає чорну та білу точки і лише перерозподіляє значення між ними, що є правильною поведінкою, коли мета – відновити деталі в тінях або яскравих ділянках без втрати наявних крайніх значень.

contrast пропускає кожен піксель через пряме множення відносно точки середньо-сірого. Значення більше 1.0 збільшують контраст (темне стає темнішим, світле – світлішим, середньо-сіре залишається незмінним); значення менше 1.0 зменшують контраст.

brightness додає константу до кожного значення пікселя. Позитивні значення освітлюють, від’ємні – затемнюють. Зсув рівномірний – нічого не зберігається – що рідко є самодостатнім для програми, але добре поєднується з проходом контрасту для центрування результату.

Три параметри компонуються: один виклик gamma() може застосувати гамма-криву, потім множення на контраст, потім зсув яскравості – все за один прохід. Порядок: спочатку гамма, потім контраст, потім яскравість, що відповідає порядку, який дає найбільш інтуїтивні результати, коли всі три відрізняються від значень за замовчуванням.

5.19.4. Автоматичний баланс білого

Сімейство тональних корекцій кольору починається з автоматичного балансу білого. Той самий механізм, який ISP датчика виконує в процесі формування зображення – регулювання відносних підсилень червоного, зеленого та синього каналів, щоб середньо-сіра ділянка читалась як справжній сірий – також доступний як операція після захоплення на готовому Image:

img.awb()

За замовчуванням використовується алгоритм сірого світу: середній колір усього зображення вважається нейтрально-сірим, і підсилення каналів регулюються відповідно. Альтернативна форма max=True використовує алгоритм білої плями: найяскравіші пікселі вважаються нейтрально-білими, і підсилення регулюються так. Обидва варіанти працюють із RGB565 та сирим Bayer; жоден не працює з відтінками сірого (де немає кольору для балансу) або YUV (де представлення кольору не відповідає тому, з чим оперують ці алгоритми).

Коли варто звертатися до форми після захоплення замість автобалансу білого ISP: коли вибір ISP не підходить для конкретної сцени, коли програма завантажує еталонні кадри з диска, захоплені в інших умовах, або коли оцінка кольору є настільки важливою, що програма хоче повторити її зі своїм вибором алгоритму.

5.19.5. Матриця колірної корекції

Коли необхідна колірна корекція зображення не є масштабуванням окремих каналів, яке дає баланс білого, а більш загальним змішуванням каналів, слід звернутися до матриці колірної корекції. Метод ccm() застосовує матрицю 3×3 (або 3×4 зі зміщенням), яка множить вектор (r, g, b) кожного пікселя для отримання нового вектора (r, g, b):

img.ccm([[1.1, -0.05, -0.05],
        [-0.05, 1.1, -0.05],
        [-0.05, -0.05, 1.1]])

Матриця дозволяє програмі коригувати перехресні спотворення між колірними каналами – наприклад, якщо відгук червоного датчика містить частину зеленого світла, матриця може відняти частку зеленого каналу від червоного виходу для компенсації. Поєднавши з посмуговим зміщенням, форма 3×4 дозволяє програмі також обнуляти кожен канал.

У матеріалі ISP pipeline пояснюється чому використовуються матриці колірної корекції. Форма після захоплення для Image – це та сама операція, застосована постфактум.