Reading and Plotting Images

13.1. Reading and Plotting Images

Julia provides a large set of image processing functions in the Images package. However, here we will focus on the mathematics and the algorithm behind some of these functions, and work directly on the arrays.

We will use PyPlot to read and plot images, as shown below:

using PyPlot
A = imread("sample_photo.png")

Using standard Julia functions, we can determine that the image is represented in a 3-dimensional array of Float32, with values between 0 and 1:

println("A is of type $(typeof(A)) with dimensions $(size(A))")
println("The values of A range between $(minimum(A)) and $(maximum(A))")
A is of type Array{Float32, 3} with dimensions (684, 912, 3)
The values of A range between 0.0 and 1.0

Here, the first 2 dimensions are row and the column indices of the pixels in the image, and the 3rd dimension of length 3 correspond to the RGB (Red-Green-Blue) components of the corresponding color.

It is convenient to work with Float numbers, however, images are normally stored as UInt8 with only 256 integer values for each RGB components. This is also supported by PyPlot, but for simplicity we will use the Float32 format here.

13.1.1. RGB values, Grayscale images

To illustrate how the RGB components build up the color of each pixel, we can build and plot new images which only contain each of the components:

Ar = copy(A); Ar[:,:,[2,3]] .= 0.0;
Ag = copy(A); Ag[:,:,[1,3]] .= 0.0;
Ab = copy(A); Ab[:,:,[1,2]] .= 0.0;
subplot(2,2,1); imshow(Ar);
subplot(2,2,2); imshow(Ag);
subplot(2,2,3); imshow(Ab);
subplot(2,2,4); imshow(A);

The image algorithms we will cover here are easiest understood by considering a single component instead of the full RGB color (such as the intensity or the brightness of each pixel). Here we simply find the average of each color component, and treat the resulting array as a grayscale image:

using Statistics
B = mean(A, dims=3)[:,:,1]

function imshow_scale(A)
    # Like imshow(A) but scales the values to [0,1] and supports grayscale
    A .-= minimum(A)            # Scale and shift to [0,1]
    A ./= maximum(A)
    if ndims(A) < 3
        A = reshape(A, size(A,1), size(A,2), 1)
    if size(A,3) == 1
        A = repeat(A, 1, 1, 3)  # Set R=G=B for grayscale


We will also sometimes consider binary images, which only contains two colors for example black and white. One way to generate these is by applying a threshold on an image. Below we also show how to invert an image, by applying the transformation \(1-x\) to each gray value \(x\).

function image_threshold(A, th)
    return Float64.(A .> th)

imshow_scale(1.0 .- image_threshold(B, 0.8));