Engee documentation
Notebook

Histogram calculation

An image histogram is a graphical representation of the distribution of pixel intensities in an image. It shows how many pixels in the image have a certain intensity (colour or brightness) value.

Why calculate a histogram?

A histogram allows you to analyse illumination, adjust contrast, brightness of the image, highlight objects, balance colours and improve visual quality.

The histogram allows you to evaluate how bright or dark an image is:

If the pixels are "crowded together" on the left (low intensities), the image is too dark.

If pixels are crowded together on the right (high intensities), the image is over-lit.

Connect the necessary packages for working with images

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

Uploading an image

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

Data processing

channelview converts the image into an array where each colour channel (red, green, blue) becomes a separate layer.

In [ ]:
rgb_planes = channelview(Image_1);

Next, split the colour channels into separate variables

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

Visualise the individual channel

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

Calculating histograms

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

In the cell above, we see an array of red channel intensities for each pixel in the image

First, we break the intensities into ranges. For example, for normalised data [0, 1], which is what we have here. we can use 256 equal intervals. Then we calculate how many pixels fall into each range.

Set the number of cells to 256

In [ ]:
histSize = 256;

Set the range of values (0 to 1)

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

Let's start calculating histograms. StatsBase.Histogram allows to calculate histograms

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);

Visualisation

We visualise the calculated histograms to clearly assess the distribution of intensities

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]:

As can be seen from the graph above, most of the pixels by intensity level are in the left part of the graph, which indicates that the image is darkened

Conclusion

In this example, pixel intensity histograms were calculated to estimate the brightness of the image