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 – це та сама операція, застосована постфактум.