Chapter 18: Images
This chapter covers the details of a digital image. In short, an image is a array that contains either gray scale or color information.
Gray Scale Images
A gray scale image is just a visual representation of a 2D array. To get started we need the following packages:
using Images, Colors, FixedPointNumbers, ImageView, TestImages
and you may need to add them. In the TestImages
package there are a number of images that we can load. For example:
man = testimage("cameraman")
should produce an image of a cameraman. If we type:
typeof(man)
then we get the following:
Images.Image{ColorTypes.Gray{FixedPointNumbers.UFixed{UInt8,8}},2,Array{ColorTypes.Gray{FixedPointNumbers.UFixed{UInt8,8}},2}}
which is a bit complicated, but in short, this is a 8-bit gray scale image, which means for each pixel, 8 bits are used to represent the scale of gray. To see the data, typing
raw(man)
shows:
512×512 Array{UInt8,2}:
and then the data. Notice that the size is 512x512, so it is a 512 by 512 image and the data type of the array is UInt8
which is 8-bit unsigned integer.
Also, notice that the first row, first column has value 0x9c
which is a way to represent a UInt8 where the last two digits are in hexadecimal.
Loading in an image from a file
We can also load an image from a file by using the load
function. For example, consider the following image:
If you download it, then
load("staab-bw.jpg")
will load in the file and show it (if you are running jupyter). You can then access the data as above.
Creating a Gray Scale image
We can also create a gray scale image. If we make an array of random UInt8
values, such as
data=rand(UInt8,200,200)
and the data will look a lot like the data in the cameraman image above. If we type:
grayim(data)
then you will get the image as well as a visualization of it. A less random image is:
data2=[(i-100)^2+(j-100)^2<50^2?UInt8(i+j-100):UInt8(125) for i=1:200, j=1:200]
and then grayim(data2)
will give a dot with a gradient inside the dot.
Color Images
We can load up a color image from the TestImages
package such as
mandrill= testimage("mandril_color")
and notice in this case that typeof(mandrill)
returns:
Images.Image{ColorTypes.RGB{FixedPointNumbers.UFixed{UInt8,8}},2,Array{ColorTypes.RGB{FixedPointNumbers.UFixed{UInt8,8}},2}}
which is a fairly complicated way to say that it is an 8-bit color (RGB) image. Entering rman=raw(mandrill)
results in the top being
3×512×512 Array{UInt8,3}:
which says that the underlying data is a 3 by 512 by 512 array. The first component is the RGB value of each pixel. For example:
rman[:,1,1]
returns
3-element Array{UInt8,1}:
0xa6
0x8b
0x3e
and the first pixel is red: “A6”, green: “8B” and blue: “3E” in hexadecimal.
An interesting thing to do is to take one of the color channels and use this as the gray scale. For example,
grayim(rman[3,:,:])
will make a gray scale image using the 3rd (blue) channel.
We can create a color image by assigning values to each channel of each pixel. For example:
colorim(rand(UInt8,3,200,200))
creates a 200 by 200 image with random colors. Assigning each pixel a particular color can be quite difficult. Instead, there is a function called ImageCmap
which produces an image using a color map (an array that maps numbers to colors). For example,
ImageCMap(data2,colormap("blues",255))
produces a color image which is a “blue” version of the gray scale above.