Гистограмма яркости: характер картинки в одном графике

Гистограмма — это «портрет» картинки: сколько в ней тёмных, средних и светлых пикселей.

Гистограмма яркости — график, показывающий, сколько пикселей приходится на каждое значение (или диапазон) яркости.

Что такое гистограмма

Возьмём все пиксели картинки и посчитаем, сколько из них имеют яркость 0, сколько 1, ... сколько 255. Получим распределение. По его форме сразу видно характер изображения, даже не глядя на саму картинку:

  • пики слева → картинка тёмная (недодержка);
  • пики справа → светлая (передержка);
  • всё прижато к центру → низкий контраст (тускло);
  • значения по всему диапазону → контрастная, «здоровая» картинка.

Строим гистограмму руками

Чтобы не печатать 256 столбцов, сгруппируем яркости в 4 корзины (бина) и нарисуем гистограмму звёздочками.

pixels = [0,0,0, 64,64, 128,128,128,128, 192, 255,255]

bins = {"0-63":0, "64-127":0, "128-191":0, "192-255":0}
for p in pixels:
    if p < 64:    bins["0-63"]    += 1
    elif p < 128: bins["64-127"]  += 1
    elif p < 192: bins["128-191"] += 1
    else:         bins["192-255"] += 1

for name, count in bins.items():
    print(f"{name:9}: {'*' * count} ({count})")

Вывод:

0-63     : *** (3)
64-127   : ** (2)
128-191  : **** (4)
192-255  : *** (3)

Это и есть гистограмма: высота столбца — число пикселей в диапазоне. Здесь значения распределены довольно равномерно — признак контрастной картинки.

Зачем это нужно

Гистограмма — рабочий инструмент:

  • Автокоррекция: увидев пики в одной части, программа сама подберёт яркость/контраст.
  • Выбор порога: если гистограмма имеет две «горы» (объект и фон), порог логично ставить во «впадину» между ними. На этом основан знаменитый метод Оцу.
  • Выравнивание гистограммы (equalization): перераспределение яркостей так, чтобы использовать весь диапазон — вытягивает детали из тёмных и пересвеченных зон.

Найдём «впадину» для порога

Простой пример: по корзинам найдём наименее заполненную — туда удобно поставить границу между объектом и фоном.

bins = {"0-63":40, "64-127":5, "128-191":3, "192-255":35}
valley = min(bins, key=bins.get)
print("Распределение:", bins)
print("Впадина (кандидат в порог):", valley)

Вывод:

Распределение: {'0-63': 40, '64-127': 5, '128-191': 3, '192-255': 35}
Впадина (кандидат в порог): 128-191

Две «горы» (тёмный фон 0-63 и светлый объект 192-255) и впадина между ними — естественное место для порога бинаризации.

Итог

  • Гистограмма — распределение пикселей по яркостям, «портрет» картинки.
  • По форме видно: тёмная, светлая, тусклая или контрастная.
  • Применяется для автокоррекции, выбора порога и выравнивания.
  • Две горы с впадиной → впадина = хороший порог (идея метода Оцу).
Проверьте себя
1. О чём говорит гистограмма с пиками только в левой части?
AКартинка очень светлая
BКартинка тёмная — большинство пикселей имеют низкую яркость
CКартинка контрастная
DВ картинке нет цвета
2. Почему впадину между двумя пиками гистограммы выбирают как порог бинаризации?
AТам меньше всего пикселей, и граница лучше всего разделяет объект и фон
BЭто самое яркое значение
CТак требует формат изображения
DВпадина — это всегда 128
3. Что делает выравнивание гистограммы (histogram equalization)?
AУдаляет цвет
BПерераспределяет яркости так, чтобы задействовать весь диапазон и вытянуть детали
CУменьшает разрешение
DДобавляет шум
Поддержать проект