Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Scan 01

Download as pdf or txt
Download as pdf or txt
You are on page 1of 8

CHAPTER 8

Basic Image Processing with


N.umPy and Matplotlib

In the last chapter, we have learned how to modify the default settings of
visualizations ofmatplotlib. We also have studied multiline and single-line
plots, in detail. We saw how to visualize NumPy data with matplotlib. Wc,
also, have experimented with colors, line styles, and markers.
Now, we know NumPy and Matplotlib and can comfortably work with
them. We have covered all the required topics needed to get started with
image processing. So, in this chapter, we will learn the basic image
processing concepts and implement them with NumPy and matplotlib.

8.1 Image Oatasets


As, we are going to learn the topic of image processing, we will need a
lot of test images. You can use any of the image. You can, even, capture
them with digital camera or scan the printed film photographs from your
family archives. However, the best option is to use the standard sets or
photographs, used by the worldwide community of image processing
researchers. You can find such sets at the following URLs,
hUp://sipi .usc.edu/ database/
hI tp:/ /www.imageprocessingplace.com/root_ files _ V3/i magc _databases.
hun
Also, University of Tsukuba (http://www.tsukuba.ac.jp/cn/) has got
excellent set of images for advanced image processing and computer
\ ision operations, Following is the URL 1'01' their stereo datasct,
III I p://www.cvlab.cs.tsukuba.ac.jp/da tasct/tsu kubaste reo .ph p
You can, also, find other datascts there.
102 - Python 3 Image Processing Basic Image Processing with NumPy and Matplotlib - IU \

So, download the test images from these URLs and store them in a local ply.axis ('off')
directory of your computer or Pi. We will be using them throughout the plt. title ('Tree')
chapter and the rest of the book as test images. plt. show ()

This will show a color image, as it is. However, when it comes to till
8.2 Installing Pillow grey scale images then it's a bit tricky. Greyscale images are shown. wuh
We need Python Imaging Library (PIL) for reading images that are not a default colormap. Following is an example code that reads and displllY
in PNG format, using matplotlib (we're going to see it next). However, a grayscale image,
its development appears to be discontinued and there is a newer version imgl = plt.imread('D:\\Dataset\\5.3.01.tiff')
of it known as pillow, which is under active development. We can check pl t .imshow (imgl)
more details about it, at https://pillow.readthedocs.io/en/stable/. We run plt .axis ('off')
the following command to install it on Windows, plt. show ()
pip3 install pillow
The output is as follows, (figure 8.1)
We run the following command on terminal to install it on Raspberry Pi,
sudo pip3 install pillow

8.3 Reading and saving images


Let's start with reading, displaying, and saving images with matplotlib.
First, import all the required libraries and enable matplotlib visualization
with the magic command, as follows,
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt

We can read image into a variable, as follows,


imgl = plt.imread('/home/pi/Dataset/4.1.06.tiff') Figure 8.1 A greyscale image rendered with default cotornutp

Note, that, the above code is for Linux and Raspberry Pi. For Windows As you can see that the greyscale image is tinted. We can avoid this"
OS, the code will be, as follows, applying grey colormap, as follows,
imgl = plt.imread('D:\\Dataset\\4.1.06.tiff') imgl = plt.imread('D:\\Dataset\\5.3.01.tiff')
It.imshow(imgl, cmap='gray')
I will, mostly, be using a Windows computer for the programming
plt. axis ('off')
However, the code, when we make appropriate changes for Linux platform,
plt. show ()
works well with Raspberry Pi Raspbian OS well.
We have to use pl t . imshow () function, followed by pl t . show () Run the above program and you will see the greyscale image without
to visualize the image, tinting.
plt.imshow(imgl) Wt:. can save the imuuc to a location on 1I disk, liS follows,
104 - Python 3 Image Processing Basic Image Processing with NumPy and Matplotlib - 105

plt.imsave('/home/pi/output.png', img1) The property dtype tells us how we are representing each data point
for the image. Here, we are using u i n t 8 which means unsigned integer
For windows, it will be, of 8 bits (1 byte). Finally, nbytes tell us how many bytes are required
plt.imsave('D:\\output.png', img1) to store it in memory (RAM). It is the multiplication of the size and the
memory required for the given datatype, in which, image data points are
represented. Here, u i n t 8 takes 1 byte each and the size is 196608, thus,
8.4 NumPy for Images the number of bytes required are 196608 x I = 196608.
When, we use Python programming for image processing operations, all
Let:s do the same for a greyscale image,
the images that's been used, are read and stored in memory (RAM), as
NumPy ndarrays. We have already seen ndarrays and their properties. img2 = plt.imread('D:\\Dataset\\5.3.01.tiff')
These properties have meaning when we work with ndarrays representing print(type(img2))
images. Let's see the example. Following are the properties of a color print (img2.shape)
print (img2.ndim)
image,
print(img2.size)
img1 = plt.imread('D:\\Dataset\\4.1.06.tiff')
print (img2.dtype)
print(type(img1))
print (img2.nbytes)
print (img1.shape)
print (img1.ndim) Following is, the output,
print(img1.size) <class 'numpy.ndarray'>
print (img1.dtype) (1024, 1024)
print (img1.nbytes) 2

Following is the output, 1048576


uint8
<class 'numpy.ndarray'>
1048576
(256, 256, 3)
3 The property shape will return a tuple with two numbers that refers
196608 to resolution of the image. There is only one channel in any greyscale
uint8 image that stores the intensity values of the grey color, for all the pixels,
196608 in the image. Thus, the number of dimensions, the property ndim, is 2.
The image data points are still represented with uint8. Rest of the two
Let's, analyze it, one by one. The first output confirms that the image is properties are dependent on these three properties and can be deduced,
indeed represented as a NurnPy array. The property shape returns the
once we have these three values.
shape of image. In the returned tuple, first two numbers represent width
and height, respectively, (i.e. resolution). The last number in the tuple We can access value for individual channel in a color image, as follow,
represents the number of color channels. For all the color image, it will rint(img1[10, 10, 0])
mostly be 3 or 4. The property ndim represents the number of dimensions print (img1 [10, 10, 1])
It is 3, for a color image, and 2, for a greyscale image. The property si print (img1 [10, .10, 21)
is the size of the image, which means how many data points or numbers
"he code above rcturu •• till' VIIIIll'" lurchnnncl 0, channel I, and channel
it takes to represent the image. If you multiply all tilt: numbers in till'
tuple returned by the property shape>, it is c xucllv the same numbci
It pixel 10, ,n, liS 1\111\1\\
106 - Python 3 Image Processing Basic Image Processing with NumPy and Matplotlib - 107

199 img1 = plt.imread('D:\\Dataset\\4.1.06.tiff')


216 nrows, ncols, channels = img1.shape
220 row, col = np.ogrid[:nrows, :ncols]
cnt_row, cnt_col = nrows/2, ncols/2
We can even use the slicing operation, as follows, outer_disk_mask = ((row - cnt row) ** 2 + (col - cnt
Iii print (img1 [10, 10, :]) col) ** 2 > (nrows/2) ** 2)
img1.setflags(write=1)
Output is, as follows, img1[outer_disk_mask]=0
[199 216 220] p Lt .imshow (img1)
p It. axis ('off' )
For a greyscale image, we can know the value of individual pixel, as
plt.title('Masked Image')
follows,
p I t . show()
print (img2 [10, 10])
III In the above code, initially, we are creating an outer disk mask and, then,
The output is, setting all the pixels in the mask to the value 0 (0 means black). The
71 function setflags (write=l) allows us to modify the pixels in the
image stored in memory (RAM). Following is the output, (figure 8.2)

8.5 Image Statistics Masked Image


~""""'-~

We can retrieve the image statistics with the NumPy ndarray properties,
as follows,
img1 = plt.imread('D:\\Dataset\\4.1.06.tiff')
print(img1.min())
print(img1.max())
print(img1.mean())

Run the above code and check the output. NumPy has some statistical
functions to retrieve statistics of a NumPy array. Following are those
functions,
print(np.median(img1))
print(np.average(img1))
print(np.mean(img1))
Figure 8.2 Masked image
print(np.std(img1))
print(np.var(img1))
8.7 Image Channels
Run the above code and check the output. We know that, for colored images, the information to the colors is saved
in separate channels. There are many schemes to do that. When pl t .
8.6 Image Masks i mread () reads IIcolor image, it stores the color information in NumPy
We can create the masks for the images to COVl'1 till' IIIIHgeswith pixels III array, such thu], till' 1IIIIIIIIIIItiollfor colors red, green, and blue is stored in
a particular color. Following is the code •.•
lIlllpll
Basic Image Processing with NumPy and Matplotlib - 109
108 - Python 3 Image Processing

color channels separately. It can be retrieved by slicing the NumPy array Red
that stores the color image, as follows,
img1 = plt.imread('D:\\Dataset\\4.1.04.tiff')

r img1 t .• · , 0]
Green Blue
9 img1 [:, · , 1]
b img1 l .. · , 2]

output [img1, r, g, b]

titles ['Image', 'Red', 'Green', 'Blue']

Figure 8.3 Separated color channels


for i in range (4) :
plt.subplot(2, 2, i+1)
As you can see, we are able to separate and display the color channels.
pH. axis ('off') (figure 8.3)
plt.title(titles[i] ) Also, if you have noticed, we are displaying multiple images in matplotlib
if i == 0: output. This is possible due to subplot () function. This function allows
plt.imshow(output[i] ) us to treat the output, as a grid and set the output images in that grid. The
else: first two arguments passed to subplot () to convey size of the grid. In
plt.imshow(output[i], cmap='gray') this example, it is 2 x 2. The last argument passed conveys the position of
the image in this grid. The top left position is 1, the horizontally adjacent
plt. show() position is 2, and so on. This is very useful, as we will be using the same
template of code to display multiple images in a single output, throughout
the book. We can even show multiple plots separately this way. We will
In the above code, we are retrieving the information for color channels see that too in this book.
in the separate two-dimensional ndarray for each color. So, we have 3 We can even recombine them to form original image, as follows,
different two-dimensional ndarrays with datatype uint8. We know that
output = np.dstack((r, g, b))
an unsigned integer of 8 bit can store 256 values ranging from 0 to 255.
plt.imshow(output)
Each value represents an intensity level for that particular color. A pixel
plt. show ()
is made of information related to 3 color channels. Thus, a pixel can have
anyone of the possible 256 x 256 x 256 = 16777216 color values. That is, Run the above code and verify, if the output is the original image.
around 16 and half million colors. Human eye can distinguish around 10
million colors. So, this 3-byte representation of a color pixel is adequate 8.8 Arithmetic Operations on Images
for humans. The output of the code above is as follows,
We can perform a lot of arithmetic operations on the images. For this
section, I am not showing the output, in the book. Instead, I want you to
run all the code examples below and check the outputs.
110 - Python 3 Image Processing Basic Image Processing with NumPy and Matplotlib - 111

We have seen a lot of operations on NumPy arrays, in the earlier section. plt.imshow(np.roll(img1, 2048))
We are going to see the same operations, in this section, in the context of p l t . show ()
images. Choose two images of same size resolution and dimension from
We can flip the image from left to right, as follows,
the image dataset that's been downloaded. Following is the sample code,
p l.t.imshow (rip . fliplr(img1) )
img1 = plt.imread('D:\\Dataset\\4.1.06.tiff')·
plt. show ()
img2 = plt.imread('D:\\Dataset\\4.1.04.tiff')
pl t .imshow (img1) We can even flip the image vertically,
plt. show ()
pl t .imshow (np.flipud(img1) )
pl t .imshow (img2)
plt. show()
pH. show ()
We can rotate the image, as follows,
We can add two images, as follows,
plt.imshow(np.rot90(img1) )
plt.imshow(img1 + img2)
plt. show()
p Lt .show ()

We know that the addition operation over numbers is commutative. 8.9 Bitwise Logical Operations
Changing position of operands does not change the final result. So,
following is the equivalent of the above, We can use NumPy bitwise logical operation functions on images. We
know that all the bitwise logical operations are commutative. We will use
plt.imshow(img1 + img2)
same images that we used in the earlier section for the demonstration of
plt. show()
logical operations. Following code demonstrates bitwise logical AND
We can subtract one image from the other, as follows, between images,
plt.imshow(img1 - img2) plt.imshow(np.bitwise_and(img1, img2))
pH. show() plt. show()

We, also, know that the subtraction operation is not commutative. So, the Following is the code for bitwise logical OR operation,
following code produces different output, plt.imshow(np.bitwise_or(img1, img2))
plt.imshow(img2 - img1) plt. show ()
plt. show ()
Bitwise logical XOR can be achieved, as follows,
We can flip the image, as follows, plt. imshow(np.bitwise_xor (img2, img1))
plt. imshow(np.flip (img1, 0)) plt. show ()
pH. show ()
Bitwise logical NOT is nothing but negative of an image, as follows,
We can even change the axis offlip, as follows, plt.subplot(l, 2, 1)
plt.imshow(np.flip(img1, 1)) pl t. imshow (img1)
pH. show() plt.subplot(l, 2, 2)
plt.imshow(np.bitwise_not(img1))
We can roll the image, as follows, n.. show ()
112 - Python 3 Image Processing Basic Image Processing with NumPy and Matplotlib - 113

Same way, we can compute and visualize the histograms for other channels
8.10 Image Histograms with NumPy and Matplotlib
as follows,
In the last chapter, we saw the code for computing histogram of a NumPy
hist, bins = np.histogram(g.ravel(), bins=256,
ndarray. However, we did not discuss the concept in detail. I was saving
it for this occasion when I can explain it in visual way. A histogram is a 'range=(O, 256))
visual representation of distribution of data in a dataset. In simple words, it plt.subplot(2, 2, 3)
is visualization of frequency distribution table of a dataset. A distribution plt.title('Green Histogram')
table is nothing, but a table of values in a dataset versus the number of plt.bar(bins[:-l] , hist)
occurrences of those values in that dataset. The dataset, here, is an image
hist, bins = np.histogram(b.ravel(), bins=256,
represented by NumPy ndarray. Let's create and visualize the chnnelwisc
histograms of a color image. The code is as follows, range=(O, 256))
plt.subplot(2, 2, 4)
img1 = plt.imread('D:\\Dataset\\4.1.01.tiff')
plt.title('Blue Histogram')
plt.bar(bins[:-l] , hist)
r img1 [:, · , 0]
9 img1 [:, · , 1]
plt. show ()
b img1 [:, · , 2]
The output is as follows, (figure 8.4)
In the above code, we are separating the channels, by slicing the NumPy
array, that holds the image. Let's adjust the space between the subplots original Image RedHistogram
with the following code, 0,. 2000" I

plt.subplots_adjust(hspace=O.5, wspace=O.5)
100
Now let's plot the original image, 1000
plt.subplot(2, 2, 1) 20()
plt.title('Original Image') 0
pl t .imshow (img1) 0 200 e 100 200

Now, let's compute the histogram for the red channel, Green Histogram Blue Histogram

l
hist, bins = np.histogram(r.ravel(), bins=256, 1500
range=(O, 256)) 2000] 1000
The red channel is a two dimensional NumPy ndarray. First, we arc 1000 t ,. SOO
flattening it and passing it, as an argument, to np. histogram ()
function. We are, also, mentioning the number of bins and range of the o r--" -
I I" 11 fUll \"t
,
0
values for which the histogram is to be computed. Finally, we will use {} 100 200 0 100 200
pl t .bar () to show the histogram visually,
Figure 8.4 Channelwise histograms for a color image
plt.subplot(2, 2, 2)
plt.title('Red Histogram')
We can directly use pl t.hist () function in matplotlib to compute and
plt.bar(bins[:-l] , hist)
visualize histogram, as follows,
114 - Python 3 Image Processing

plt.subplots_adjust(hspace=0.5, wspace=0.5)
plt.subplot(2, 2, 1)
plt.title('Original Image')
pl t .imshow (img1) CHAPTER 9
plt.subplot(2, 2, 2)
plt.title('Red Histogram') Advanced Image Processing
plt.hist(r.ravel(), bins=256, range=(O, 256))
plt.subplot(2, 2, 3) with NumPy and Matplotlib
plt.title('Green Histogram')
plt.hist(g.ravel(), bins=256, range=(O, 256))
plt.subplot(2, 2, 4)
plt.title('Blue Histogram') In the last chapter, we have got started with the image processing
plt.hist(b.ravel(), bins=256, range=(O, 256)) programming. We have learned how to implement basic image processing
plt. show() operations with NumPy and matplotlib. We have studied and implemented
very basic operations, without using any dedicated library for image
The output of the code, above, will exactly be the same as the output of processing.
the earlier code.
We will continue with the image processing operations with NumPy and
This is how we can compute and visualize the histogram of any image or matplotlib. We will study a bit more advanced operations and we will
NumPy ndarray. write the functions for them, ourselves. We will study the concepts like
thresholding, color to greyscale, normalization, and other operations.
8. 11 Summary
In this chapter, we have studied the image processing operations on 9. 1 Color to Greyscale Conversion
III
images with NumPy and matplotlib. We have not worked with any image We know that a color image has 3 channels and it is represented with RGB
processing library yet. NumPy itself can be used for most basic operations colorspace. We can convert a color image to a grey scale image. We need
on images. We can even implement our own functions for various image to convert values represented by 3 channels to a single channel. First, we
processing operations ..We will do the same in the next chapter. We will import all the required libraries, following is the code:
study a few advanced image processing operations and write a few
%matplotlib inline
functions, on our own, to perform those few image processing operations
import numpy as np
with NumPy and matplotlib only.
import matplotlib.pyplot as plt

Exercise The custom function to convert color image to greyscale image, as follows:

We have seen the demonstration of various image processing techniques def rgb2gray(img) :
for the color images. I want you to perform all these image processing r = i mg [:, :, 0]

operations for greyscale images. It will be an interesting exercise. 9 = img [:, :, 1]


b = img [:, :, 2]
return (0.2989 * r

You might also like