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

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

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

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

Возьмём все пиксели картинки и посчитаем, сколько из них имеют яркость 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Добавляет шум