Документация Engee
Notebook

Расчет гистограммы

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

Зачем рассчитывать гистограмму?

Гистограмма позволяет анализировать освещенность, регулировать контрастность, яркость изображения, выделять объекты, балансировать цвета и улучшать качество визуализации.

Гистограмма позволяет оценить, насколько яркое или темное изображение:

Если пиксели "скучены" слева (низкие интенсивности), изображение слишком темное.

Если пиксели "скучены" справа (высокие интенсивности), изображение пересвечено.

Подключаем необходимые пакеты для работы с изображениями

In [ ]:
import Pkg
Pkg.add("Images")
Pkg.add("StatsBase")
Pkg.add("Plots")
In [ ]:
using Images, StatsBase, Plots

Загрузка изображения

In [ ]:
path_to_img_1 = "$(@__DIR__)/Cozy_Autumn_Beverage_Moment.jpeg";
In [ ]:
Image_1 = load(path_to_img_1)
Out[0]:
No description has been provided for this image

Обработка данных

channelview преобразует изображение в массив, где каждый цветовой канал (красный, зеленый, синий) становится отдельным слоем.

In [ ]:
rgb_planes = channelview(Image_1);

Далее разбиваем цветовые каналы в отдельные переменные

In [ ]:
blue_channel = rgb_planes[3, :, :]
green_channel = rgb_planes[2, :, :]
red_channel = rgb_planes[1, :, :];

Визуализируем отдельный канал

In [ ]:
red_image = colorview(RGB, red_channel, zeros(size(red_channel)), zeros(size(red_channel)))
Out[0]:
No description has been provided for this image

Расчет гистограмм

In [ ]:
red_channel
Out[0]:
2400×1345 Array{N0f8,2} with eltype N0f8:
 0.184  0.192  0.204  0.212  0.224  …  0.102  0.098  0.082  0.071  0.063
 0.188  0.192  0.204  0.212  0.22      0.082  0.075  0.067  0.067  0.067
 0.196  0.2    0.212  0.22   0.22      0.075  0.063  0.067  0.067  0.059
 0.196  0.2    0.208  0.216  0.216     0.067  0.055  0.059  0.059  0.051
 0.192  0.2    0.208  0.212  0.22      0.059  0.055  0.047  0.043  0.051
 0.188  0.196  0.204  0.212  0.216  …  0.055  0.055  0.047  0.043  0.059
 0.188  0.196  0.204  0.212  0.216     0.055  0.051  0.055  0.055  0.059
 0.188  0.192  0.204  0.212  0.212     0.043  0.039  0.047  0.059  0.055
 0.18   0.188  0.196  0.208  0.212     0.051  0.051  0.055  0.055  0.043
 0.184  0.184  0.196  0.204  0.212     0.051  0.055  0.059  0.059  0.043
 0.184  0.188  0.196  0.196  0.204  …  0.059  0.059  0.059  0.059  0.051
 0.188  0.184  0.192  0.196  0.204     0.055  0.055  0.055  0.059  0.055
 0.184  0.188  0.196  0.2    0.208     0.051  0.051  0.051  0.051  0.051
 ⋮                                  ⋱  ⋮                           
 0.098  0.039  0.035  0.098  0.149     0.502  0.486  0.49   0.486  0.486
 0.027  0.043  0.075  0.071  0.09      0.514  0.502  0.498  0.494  0.498
 0.11   0.122  0.169  0.141  0.118  …  0.525  0.518  0.518  0.522  0.506
 0.169  0.098  0.125  0.133  0.122     0.537  0.533  0.537  0.541  0.518
 0.063  0.125  0.114  0.051  0.035     0.549  0.545  0.549  0.537  0.522
 0.157  0.165  0.133  0.059  0.024     0.553  0.553  0.549  0.545  0.549
 0.212  0.125  0.102  0.094  0.09      0.561  0.557  0.553  0.553  0.573
 0.094  0.078  0.133  0.106  0.09   …  0.573  0.561  0.565  0.561  0.576
 0.027  0.067  0.122  0.047  0.075     0.58   0.569  0.576  0.573  0.573
 0.051  0.043  0.098  0.094  0.114     0.584  0.584  0.584  0.588  0.573
 0.039  0.047  0.157  0.196  0.098     0.588  0.592  0.592  0.588  0.569
 0.09   0.082  0.122  0.129  0.059     0.588  0.596  0.596  0.588  0.569

В ячейке выше мы видим массив значений интенсивностей красного канала изображения для каждого пикселя

Сначала разбиваем интенсивности на диапазоны. Например, для нормализованных данных [0, 1], которые у нас и представлены можно использовать 256 равных интервалов. Затем подсчитываем, сколько пикселей попадает в каждый диапазон.

Установите количество ячеек - 256

In [ ]:
histSize = 256;

Установите диапазон значений (от 0 до 1)

In [ ]:
hist_range = 0:1/(histSize-1):1;

Приступим к расчету гистограмм. StatsBase.Histogram позволяет рассчитать гистограммы

In [ ]:
b_hist = fit(Histogram, blue_channel[:], hist_range)
r_hist = fit(Histogram, red_channel[:], hist_range)
g_hist = fit(Histogram, green_channel[:], hist_range);

Визуализация

Визуализируем рассчитанные гистограммы для наглядной оценки распределения интенсивностей

In [ ]:
plot(r_hist.edges[1][1:end-1], r_hist.weights, color=:red, label="Red Channel")
plot!(b_hist.edges[1][1:end-1], b_hist.weights, color=:blue, label="blue Channel")
plot!(g_hist.edges[1][1:end-1], g_hist.weights, color=:green, label="green Channel")
Out[0]:

Как видно из графика выше, большая часть пикселей по уровню интенсивности находятся в левой части графика, что говорит о затемненности изображения

Вывод

В данном примере были рассчитаны гистограммы интенсивностей пикселей для оценки яркости изображения