Reading image as matrix, accessing individual pixels

Import the necessary python packages.

In [1]:
import numpy as np # math package for N-dimensional arrays and other stuff
import matplotlib.pyplot as plt # image input/output and graph drawing 

Read an image as a 2D HxW (grayscale) or a 3D HxWx3 numpy array. Note that pixel intensities are scaled to the [0, 1] interval.

In [2]:
img = plt.imread( 'data/cd_box.png' )

Display the image. Note that the image coordinate system has its origin in the upper left corner and it is left-handed.

In [3]:
plt.imshow( img )
plt.gca().set_xlabel( 'x' ) # set the x-label of the current Axes (returned by the gca)
plt.gca().set_ylabel( 'y' ) # set the y-label of the current Axes
Out[3]:
Text(0, 0.5, 'y')

Convert to gray-scale. Note the [:,:,?] numpy indexing that produces sub-matrix of the 3D array.

In [4]:
img_gray = img[:,:,0] * 0.2989 + img[:,:,1] * 0.5870 + img[:,:,2] * 0.1140  # result is 2D array (matrix) 

Show the gray-scale image with the default colormap and with the grayscale one.

In [5]:
plt.imshow( img_gray )
Out[5]:
<matplotlib.image.AxesImage at 0x9be6b48>
In [6]:
plt.imshow( img_gray, cmap='gray' )
Out[6]:
<matplotlib.image.AxesImage at 0x9e76408>

Some toy manipulation of the pixel color intensities. Note that [row, column] indices of a matrix correspond to [y,x] coordinates of the left-handed image coordinate system.

In [7]:
img_new = np.empty( img.shape ) # preallocate new (uninitialized) array of the same size as img
for y in range(0, img.shape[0] ): # for all rows
    for x in range(0, img.shape[1] ): # for all columns
        a = x / img.shape[1] # gradient going from left to right
        r = img[y,x,0] * ( 0.2 + a )
        b = img[y,x,2] * ( 0.2 + (1-a) )
        img_new[y,x,0] = r if r < 1 else 1 # red channel
        img_new[y,x,1] = img[y,x,1] # greem channel unchanged
        img_new[y,x,2] = b if b < 1 else 1 # blue channel
               
In [8]:
plt.imshow( img_new )
Out[8]:
<matplotlib.image.AxesImage at 0x9ed2648>

Do some manipulation on the pixel positions (transpose the grayscale image)

In [9]:
img_new2 = np.zeros( ( img_gray.shape[1], img_gray.shape[0] ) ) # preallocate transposed image, filled with zeros
In [10]:
for i in range(0, img_gray.shape[0] ):
    for j in range(0, img_gray.shape[1] ):
        img_new2[j,i] = img_gray[i,j]
In [11]:
plt.imshow( img_new2, cmap='gray' )
Out[11]:
<matplotlib.image.AxesImage at 0x9f35ac8>