Обработка изображений 7. Гистограмма

от
Работа с графикой    image processing, обработка изображений, javascript, js, histogram, гистограмма

logo.pngСегодняшняя статья будет о гистограммах. О том, что с помощью них можно сказать о фотографии, как их построить и как влияет корректировка изображения на вид гистограммы.

Содержание:
  1. Введение
  2. Изображения. Простая трансформация
  3. Негатив, извлечение и инверсия каналов
  4. Обесцвечивание
  5. Цветовые модели
  6. Яркость, насыщенность, контрастность, гамма-коррекция
  7. Гистограмма
  8. Масштабирование изображения
  9. Размытие
  10. Свёртка

В RGB-представлении изображения 256 значений яркости для каждого канала. Что, если подсчитать количество пикселей для каждого такого значения? Мы получим некоторую статистику распределения яркости, сможем узнать, какая яркость преобладает в изображении, а какой, напротив, мало. Вот это и есть гистограмма изображения.

Если подсчитывать значения каждого цветового канала как будто это один канал, либо преобразовывать цвет в оттенки серого, а потом подсчитывать статистику, то получится гистограмма яркости. По ней можно определить, что фотография недостаточно яркая и её нужно осветлить (повысить яркость при пост-обработке, либо увеличить экспозицию при съёмке), либо она, напротив, засвечена.

Если строить график для каждой RGB компоненты, то получится RGB-гистограмма. Такая гистограмма позволяет узнать, какой цветовой канал преобладает на изображении и принять соответствующие меры. Если гистограмма построена фотокамерой в момент фокусировки, то по ней можно определить, что на фотографии, допустим, преобладает красный цвет и возможно стоит настроить баланс белого на более холодные тона. Если же гистограмма построена на этапе пост-обработки, то можно попытаться скомпенсировать засвет соответствующим цветовым фильтром.
Для желающих больше узнать о цветовой температуре и балансе белого, рекомендую ознакомиться со статьёй Баланс белого.Но, хватит теории, перейдём к практике.


Построение гистограммыГистограмму будем рисовать на канвасе. Сначала создадим массив из 256 элементов и заполним его нулями. Затем подсчитаем количество вхождений каждого значения яркости.
  1. let histBrightness = (new Array(256)).fill(0);
  2. for (let i = 0; i < src.length; i++) {
  3.   let r = src[i] & 0xFF;
  4.   let g = (src[i] >> 8) & 0xFF;
  5.   let b = (src[i] >> 16) & 0xFF;
  6.   histBrightness[r]++;
  7.   histBrightness[g]++;
  8.   histBrightness[b]++;
  9. }
Вот и всё. Остаётся только найти максимальное значение, чтобы правильно вписать график по высоте канваса, и, собственно, отрисовать линии:
  1. let maxBrightness = 0;
  2. for (let i = 1; i < 256; i++) {
  3.   if (maxBrightness < histBrightness[i]) {
  4.     maxBrightness = histBrightness[i]
  5.   }
  6. }
  7.  
  8. const canvas = document.getElementById('canvasHistogram');
  9. const ctx = canvas.getContext('2d');
  10. let dx = canvas.width / 256;
  11. let dy = canvas.height / maxBrightness;
  12. ctx.lineWidth = dx;
  13. ctx.fillStyle = "#fff";
  14. ctx.fillRect(0, 0, canvas.width, canvas.height);
  15. for (let i = 0; i < 256; i++) {
  16.   let x = i * dx;
  17.   ctx.strokeStyle = "#000000";
  18.   ctx.beginPath();
  19.   ctx.moveTo(x, canvas.height);
  20.   ctx.lineTo(x, canvas.height - histBrightness[i] * dy);
  21.   ctx.closePath();
  22.   ctx.stroke();
  23. }

See the Pen Image processing 7.1. Histogram by aNNiMON (@aNNiMON) on CodePen.


Возьмём обычную фотографию:
sample_0m.jpg hist_ev0.png
По этой гистограмме видно, что изображение достаточно контрастное, в нём присутствуют и тёмные, и светлые тона.

А вот фотография того же места с экспозицией -2.0:
sample_-2m.jpg hist_ev-2.png
По гистограмме видно, что светлых участков здесь практически нет, а большой пик в левой части говорит, что фотография затемнена.
hist_ev-2b.png

Наконец, фотография с экспозицией +2.0:
sample_+2m.jpg hist_ev2.png
Здесь настолько много пересвета, что средние тона на гистограмме практически не видны – всё ушло в правый край.
hist_ev2b.png

Пора исправлять! Для этого добавим корректировку яркости и контрастности из предыдущей статьи и будем смотреть, как изменяется гистограмма.

See the Pen Image processing 7.2. Histogram + Corrections by aNNiMON (@aNNiMON) on CodePen.



Как видно, яркость перемещает гистограмму влево/вправо, а контрастность сужает/расширяет диапазон.

Если настроить параметры так, чтобы слева и справа не было пустого пространства и при этом не было большого затемнения и пересвета, то мы получим чуть более приемлемую картинку:

hist_fixed_js.jpg

Именно по такому принципу работает коррекция Автоконтраст в Photoshop:

hist_fixed_ps.jpg

Получился почти такой же результат, что и при ручном выравнивании в js.
  • +5
  • views 8163