Image I/O and display with Python
Images are stored as files on the disk, so reading and writing images from the files are disk I/O operations. These can be done using many ways using different libraries; some of them are shown in this section. Let us first start by importing all of the required packages:
# for inline image display inside notebook # % matplotlib inline import numpy as np from PIL import Image, ImageFont, ImageDraw from PIL.ImageChops import add, subtract, multiply, difference, screen import PIL.ImageStat as stat from skimage.io import imread, imsave, imshow, show, imread_collection, imshow_collection from skimage import color, viewer, exposure, img_as_float, data from skimage.transform import SimilarityTransform, warp, swirl from skimage.util import invert, random_noise, montage import matplotlib.image as mpimg import matplotlib.pylab as plt from scipy.ndimage import affine_transform, zoom from scipy import misc
Â
Â
Â
Â
Reading, saving, and displaying an image using PIL
The PIL function, open()
, reads an image from disk in an Image
 object, as shown in the following code. The image is loaded as an object of the PIL.PngImagePlugin.PngImageFile
class, and we can use properties such as the width, height, and mode to find the size (width x height in pixels or the resolution of the image) and mode of the image:
im = Image.open("../images/parrot.png") # read the image, provide the correct path
print(im.width, im.height, im.mode, im.format, type(im))
# 453 340 RGB PNG <class 'PIL.PngImagePlugin.PngImageFile'>
im.show() # display the image
The following is the output of the previous code:
The following code block shows how to use the PIL function, convert()
, to convert the colored RGB image into a grayscale image:
im_g = im.convert('L') # convert the RGB color image to a grayscale image im_g.save('../images/parrot_gray.png') # save the image to disk Image.open("../images/parrot_gray.png").show() # read the grayscale image from disk and show
The following is the output grayscale image:
Providing the correct path to the images on the disk
We recommend creating a folder (sub-directory) to store images to be used for processing (for example, for the Python code samples, we have used the images stored inside a folder named images
) and then provide the path to the folder to access the image to avoid the file not found
exception.
Reading, saving, and displaying an image using Matplotlib
The next code block shows how to use the imread()
function frommatplotlib.image
 to read an image in a floating-point numpy ndarray
. The pixel values are represented as real values between 0 and 1:
im = mpimg.imread("../images/hill.png") # read the image from disk as a numpy ndarray print(im.shape, im.dtype, type(im)) # this image contains an α channel, hence num_channels= 4 # (960, 1280, 4) float32 <class 'numpy.ndarray'> plt.figure(figsize=(10,10)) plt.imshow(im) # display the image plt.axis('off') plt.show()
The following figure shows the output of the previous code:
The next code snippet changes the image to a darker image by first setting all of the pixel values below 0.5 to 0 and then saving the numpy ndarray
to disk. The saved image is again reloaded and displayed:
im1 = im im1[im1 < 0.5] = 0 # make the image look darker plt.imshow(im1) plt.axis('off') plt.tight_layout() plt.savefig("../images/hill_dark.png") # save the dark image im = mpimg.imread("../images/hill_dark.png") # read the dark image plt.figure(figsize=(10,10)) plt.imshow(im) plt.axis('off') # no axis ticks plt.tight_layout() plt.show()
The next figure shows the darker image saved with the preceding code:Â
Interpolating while displaying with Matplotlib imshow()
The imshow()
function from Matplotlib provides many different types of interpolation methods to plot an image. These functions can be particularly useful when the image to be plotted is small. Let us use the small 50 x 50 lena
image shown in the next figure to see the effects of plotting with different interpolation methods:
Â
The next code block demonstrates how to use different interpolation methods with imshow()
:
im = mpimg.imread("../images/lena_small.jpg") # read the image from disk as a numpy ndarray methods = ['none', 'nearest', 'bilinear', 'bicubic', 'spline16', 'lanczos'] fig, axes = plt.subplots(nrows=2, ncols=3, figsize=(15, 30), subplot_kw={'xticks': [], 'yticks': []}) fig.subplots_adjust(hspace=0.05, wspace=0.05) for ax, interp_method in zip(axes.flat, methods): ax.imshow(im, interpolation=interp_method) ax.set_title(str(interp_method), size=20) plt.tight_layout() plt.show()
The next figure shows the output of the preceding code:
Reading, saving, and displaying an image using scikit-image
The next code block uses the imread()
function fromscikit-image
 to read an image in a numpy ndarray
of type uint8
(8-bit unsigned integer). Hence, the pixel values will be in between 0 and 255. Then it converts (changes the image type or mode, which will be discussed shortly)Â the colored RGB image into an HSV image using the hsv2rgb()
function from the Image.color
module. Next, it changes the saturation (colorfulness) to a constant value for all of the pixels by keeping the hue and value channels unchanged. The image is then converted back into RGB mode with the rgb2hsv()
function to create a new image, which is then saved and displayed:
im = imread("../images/parrot.png") # read image from disk, provide the correct path print(im.shape, im.dtype, type(im)) # (362, 486, 3) uint8 <class 'numpy.ndarray'> hsv = color.rgb2hsv(im) # from RGB to HSV color space hsv[:, :, 1] = 0.5 # change the saturation im1 = color.hsv2rgb(hsv) # from HSV back to RGB imsave('../images/parrot_hsv.png', im1) # save image to disk im = imread("../images/parrot_hsv.png") plt.axis('off'), imshow(im), show()
The next figure shows the output of the previous code—a new image with changed saturation:
We can use the scikit-image viewer
module also to display an image in a pop-up window, as shown in the following code:
viewer = viewer.ImageViewer(im) viewer.show()
Using scikit-image's astronaut dataset
The following code block shows how we can load the astronaut
image from the scikit-image
library's image datasets with the data
module. The module contains a few other popular datasets, such as cameraman, which can be loaded similarly:
im = data.astronaut() imshow(im), show()
Â
Â
Â
Â
Â
Â
The next figure shows the output of the preceding code:
Reading and displaying multiple images at once
We can use the imread_collection()
 function of the scikit-image io
module to load in a folder all images that have a particular pattern in the filename and display them simultaneously with the imshow_collection()
function. The code is left as an exercise for the reader.
Reading, saving, and displaying an image using scipy misc
The misc
module of scipy
 can also be used for image I/O and display. The following sections demonstrate how to use the misc
module functions.
Using scipy.misc's face dataset
The next code block shows how to display the face
 dataset of the misc
module:
im = misc.face() # load the raccoon's face image
misc.imsave('face.png', im) # uses the Image module (PIL)
plt.imshow(im), plt.axis('off'), plt.show()
Â
Â
The next figure shows the output of the previous code, which displays the misc
module's face
image:
We can read an image from disk using misc.imread()
. The next code block shows an example:
im = misc.imread('../images/pepper.jpg') print(type(im), im.shape, im.dtype) # <class 'numpy.ndarray'> (225, 225, 3) uint8
The I/O function's imread()
 is deprecated in SciPy 1.0.0, and will be removed in 1.2.0, so the documentation recommends we use the imageio
library instead. The next code block shows how an image can be read with the imageio.imread()
function and can be displayed with Matplotlib:
import imageio im = imageio.imread('../images/pepper.jpg') print(type(im), im.shape, im.dtype) # <class 'imageio.core.util.Image'> (225, 225, 3) uint8 plt.imshow(im), plt.axis('off'), plt.show()
Â
Â
Â
Â
The next figure shows the output of the previous code block: