Точечные операции: яркость, контраст, инверсия, порог

Точечная операция меняет каждый пиксель независимо от соседей — это самый простой класс обработки.

Точечная операция — преобразование, где новое значение пикселя зависит только от его старого значения: new = f(old).

Яркость и обрезка

Чтобы осветлить картинку, ко всем пикселям прибавляют число; чтобы затемнить — вычитают. Но яркость обязана остаться в диапазоне 0..255, иначе будет переполнение. Поэтому результат «зажимают» функцией clamp.

def clamp(v):
    return max(0, min(255, v))

row = [10, 50, 90, 130, 170, 210, 250]

bright = [clamp(p + 40) for p in row]
dark   = [clamp(p - 40) for p in row]
invert = [255 - p for p in row]
thresh = [255 if p >= 128 else 0 for p in row]

print("исходник:  ", row)
print("яркость+40:", bright)
print("яркость-40:", dark)
print("инверсия:  ", invert)
print("порог 128: ", thresh)

Вывод:

исходник:   [10, 50, 90, 130, 170, 210, 250]
яркость+40: [50, 90, 130, 170, 210, 250, 255]
яркость-40: [0, 10, 50, 90, 130, 170, 210]
инверсия:   [245, 205, 165, 125, 85, 45, 5]
порог 128:  [0, 0, 0, 255, 255, 255, 255]

Разберём каждую операцию:

  • Яркость +40: 250 стало бы 290, но clamp обрезал до 255 — деталь в светах «выгорела».
  • Инверсия: 255 - p — негатив, светлое становится тёмным.
  • Порог (бинаризация): всё ниже 128 → 0, всё выше → 255. Получаем чёрно-белую маску.

Контраст: растяжение диапазона

Тусклая картинка использует узкий диапазон яркостей (скажем, 60..150). Контраст усиливают, растягивая этот диапазон на все 0..255. Самый тёмный пиксель станет 0, самый светлый — 255, остальные — пропорционально.

row = [60, 70, 90, 110, 130, 150]
lo, hi = min(row), max(row)
print("min, max:", lo, hi)

stretched = [round((p - lo) * 255 / (hi - lo)) for p in row]
print("растянуто:", stretched)

Вывод:

min, max: 60 150
растянуто: [0, 28, 85, 142, 198, 255]

Тусклый диапазон 60..150 превратился в полный 0..255 — картинка стала «контрастнее», переходы заметнее.

Почему точечные операции важны

Это базовая предобработка: нормализация яркости, бинаризация перед поиском контуров или распознаванием текста (OCR). Бинаризация по порогу — первый шаг во многих классических пайплайнах: сначала превращаем картинку в чёрно-белую маску, потом ищем на ней объекты. А нормализация диапазона пикселей в 0..1 — обязательный шаг перед подачей в нейросеть.

Итог

  • Точечная операция: new = f(old), соседи не участвуют.
  • Яркость — сдвиг с обязательным clamp до 0..255.
  • Инверсия — негатив 255 - p; порог — бинаризация в маску.
  • Контраст — растяжение узкого диапазона яркостей на весь.
Проверьте себя
1. Зачем при увеличении яркости нужна функция clamp (обрезка до 0..255)?
AЧтобы ускорить вычисления
BЧтобы значения не выходили за допустимый диапазон яркости и не возникло переполнения
CЧтобы перевести картинку в серый
DClamp не нужен
2. Что делает бинаризация по порогу 128?
AУвеличивает разрешение вдвое
BПревращает каждый пиксель в 0 или 255 в зависимости от того, ниже он порога или нет
CИнвертирует цвета
DРазмывает картинку
3. Как растяжение контраста улучшает тусклую картинку?
AДобавляет новые цвета
BРастягивает узкий используемый диапазон яркостей на весь 0..255, делая переходы заметнее
CУменьшает число пикселей
DПоворачивает изображение
Поддержать проект