Image Processing with NumPy

NumPy Arrays

  • https://numpy.org/doc/stable/user/whatisnumpy.html
  • NumPy is a Python library used for working with arrays.
  • The main features of NumPy are: (1) N-dimensional array object ndarray; (2) vectorized operations and functions which broadcast across arrays for fast computation.
In [1]:
pip install -U pip
Requirement already satisfied: pip in /usr/local/lib/python3.7/dist-packages (21.0.1)
In [2]:
pip install -U numpy
Requirement already satisfied: numpy in /usr/local/lib/python3.7/dist-packages (1.20.1)
In [3]:
import numpy as np
np.__version__
Out[3]:
'1.20.1'
In [4]:
%matplotlib inline
In [5]:
import PIL
PIL.__version__
Out[5]:
'8.1.0'
In [6]:
pip install --upgrade Pillow
Requirement already satisfied: Pillow in /usr/local/lib/python3.7/dist-packages (8.1.0)
In [7]:
import PIL
PIL.__version__
Out[7]:
'8.1.0'
In [8]:
from google.colab import drive
drive.mount('/content/drive')
Drive already mounted at /content/drive; to attempt to forcibly remount, call drive.mount("/content/drive", force_remount=True).

Creating NumPy Arrays

  • The fundamental object provided by NumPy is the ndarray.
  • 1D(1-dimensional) ndarray: a list
  • 2D ndarray: a matrix
  • 3D ndarray: 3-tensor or a cube of numbers
  • A 1D NumPy array looks like a Python list. The entries in a 1D NumPy array are seperated by spaces between entires. The entries in a Pyhton list is seperated by commas.
  • array(object, dtype) creates an array of tye dtype.
  • linspace(start,stop,num) returns num equally spaced points, including endpoints.
  • arange returns an array of evenly spaced values within a given interval.
  • zeros(shape) returns an array of shape filled with zeros - the default type is float.
  • The numer of dimensions and size of each dimension can be changed using reshape.
  • The dtype can be changed using astype.
  • random.randint returns an array of a given size filled with randomly selected integers from a given range.
  • axis argument finds each minimum along a given axis.
In [9]:
#Create an array from a Python list:
a = np.array([1,2,3])
print(a)
type(a)
[1 2 3]
Out[9]:
numpy.ndarray
In [10]:
a.shape # a is a 1-dimensional array with 3 elements in the first axis.
Out[10]:
(3,)
In [11]:
list_1 = [1,2,3]
print(list_1)
type(list_1)
[1, 2, 3]
Out[11]:
list
In [12]:
a
Out[12]:
array([1, 2, 3])
In [13]:
list_1
Out[13]:
[1, 2, 3]
In [14]:
x = np.array([1,2,3], dtype=float)
print(x)
[1. 2. 3.]
In [15]:
y = np.linspace(0,1,6) # create a 1D array with 6 equally spaced values from 0 to 1.
print(y)
[0.  0.2 0.4 0.6 0.8 1. ]
In [16]:
z = np.arange(6) # Create a 1D array with values from 0 to 6 (exclusively) incremented by step
print(z)
[0 1 2 3 4 5]
In [17]:
x3 = np.arange(3, dtype=float)
print(x3)
[0. 1. 2.]
In [18]:
# Create a 2D NumPy array from a Python list of lists
M = np.array([[1,3,5],[2,4,6]])
print(M)
type(M)
[[1 3 5]
 [2 4 6]]
Out[18]:
numpy.ndarray
In [19]:
x1 = np.zeros((2,3))
print(x1)
[[0. 0. 0.]
 [0. 0. 0.]]
In [20]:
x2 = np.zeros((2,3), dtype=int)
print(x2)
[[0 0 0]
 [0 0 0]]
In [21]:
ones = np.ones((2,3), dtype=int)
print(ones)
[[1 1 1]
 [1 1 1]]
In [22]:
M = np.array([[1,2,3,4],[5,6,7,8]])
print(M)
type(M)
[[1 2 3 4]
 [5 6 7 8]]
Out[22]:
numpy.ndarray
In [23]:
M
Out[23]:
array([[1, 2, 3, 4],
       [5, 6, 7, 8]])
In [24]:
M1 = M.astype(float)
print(M1)
[[1. 2. 3. 4.]
 [5. 6. 7. 8.]]
In [25]:
# Creat a n-dimensional NumPy array from nested Python lists.
N = np.array([[[1,2],[3,4]], [[5,6],[7,8]], [[9,10],[11,12]]])
print(N)
type(N)
[[[ 1  2]
  [ 3  4]]

 [[ 5  6]
  [ 7  8]]

 [[ 9 10]
  [11 12]]]
Out[25]:
numpy.ndarray

Array Operations

In [26]:
x = np.arange(4)
print(x)
[0 1 2 3]
In [27]:
x+1
Out[27]:
array([1, 2, 3, 4])
In [28]:
print(x+1) # 1 is added to every element of the array x.
[1 2 3 4]
In [29]:
print(x**2)
[0 1 4 9]
In [30]:
x = np.array([1,2,3,4])
y = np.array([5,6,7,8])
print(x+y)
[ 6  8 10 12]
In [31]:
print(x*y)
[ 5 12 21 32]
In [32]:
print(y**x) # Exponentiation is done using corresponding elements of the arrays x and y.
[   5   36  343 4096]
In [33]:
x = np.arange(6) # Each element is evaluated seperately resulting in an array of booleans.
print(x)
print(x % 2 == 0)
[0 1 2 3 4 5]
[ True False  True False  True False]
In [34]:
x = np.random.randint(5, size=(2,3))
print(x)
[[4 2 2]
 [1 3 2]]
In [35]:
print(x.min(), x.max()) # minimum and maximum values across the entire array.
1 4
In [36]:
print(x.min(axis=0))
print(x.min(axis=1))
[1 2 2]
[2 1]
In [37]:
print(x.sum())
14
In [38]:
print(x.sum(axis=0))
[5 5 4]

Array Indexing and Slicing

In [39]:
x = np.arange(20).reshape((4,5))
print(x)
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]
 [15 16 17 18 19]]
In [40]:
print(x[1,2]) # row 1, column 2
7
In [41]:
print(x[1]) # row 1
[5 6 7 8 9]
In [42]:
print(x[:, 1]) # the first element of every axis (i.e. column 1)
[ 1  6 11 16]
In [43]:
print(x[1:3, 1:4]) # Slice row 1 and 2, then slice columns 1, 2, and 3.
[[ 6  7  8]
 [11 12 13]]
In [44]:
a = np.array([2,4,6,8], float)
print(a)
type(a)
[2. 4. 6. 8.]
Out[44]:
numpy.ndarray
In [45]:
a[:2]
Out[45]:
array([2., 4.])
In [46]:
a[3]
Out[46]:
8.0
In [47]:
a[0]
Out[47]:
2.0
In [48]:
a
Out[48]:
array([2., 4., 6., 8.])
In [49]:
a = np.array([[1,2,3], [4,5,6]], float)
a
Out[49]:
array([[1., 2., 3.],
       [4., 5., 6.]])
In [50]:
a[0,0]
Out[50]:
1.0
In [51]:
a[0,1]
Out[51]:
2.0
In [52]:
a[1, :]
Out[52]:
array([4., 5., 6.])
In [53]:
a[:, 2]
Out[53]:
array([3., 6.])
In [54]:
a[-1:, -2:]
Out[54]:
array([[5., 6.]])
In [55]:
a.shape
Out[55]:
(2, 3)
In [56]:
a.dtype
Out[56]:
dtype('float64')
In [57]:
len(a) # the length of the first axis
Out[57]:
2
In [58]:
2 in a
Out[58]:
True
In [59]:
7 in a
Out[59]:
False
In [60]:
a = np.array(range(10), float)
a
Out[60]:
array([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
In [61]:
a = a.reshape((5,2))
a
Out[61]:
array([[0., 1.],
       [2., 3.],
       [4., 5.],
       [6., 7.],
       [8., 9.]])
In [62]:
a.shape
Out[62]:
(5, 2)
In [63]:
x = np.array([1,2,3], float)
y = x
z = x.copy()
x[0] = 0
x
Out[63]:
array([0., 2., 3.])
In [64]:
y
Out[64]:
array([0., 2., 3.])
In [65]:
z
Out[65]:
array([1., 2., 3.])

Creating RGB Images and RGBA images

  • By reading the image as NumPy array ndarray, image processing can be performed using NumPy functions.
  • Passing ndarray to Image.fromarray() returns PIL.Image.
In [66]:
# Create RGB images
import numpy as np
from PIL import Image

array = np.zeros([100, 200, 3],dtype=np.uint8)
array[:, :100] = [255, 33, 0]
array[:, 100:] = [0, 0, 255]

im = Image.fromarray(array)
im.save('/content/drive/My Drive/testrgb.png')
In [67]:
testrgb = Image.open('/content/drive/My Drive/testrgb.png')
testrgb
Out[67]:
In [68]:
# Creating RGBA images
import numpy as np
from PIL import Image

array_a = np.zeros([100, 200, 4], dtype=np.uint8)
array_a[:,:100] = [255, 33, 0, 255]
array_a[:,100:] = [0, 0, 255, 255]

for x in range(200):
    for y in range(100):
        array_a[y, x, 3] = x

img = Image.fromarray(array_a)
img.save('/content/drive/My Drive/test_rgba.png')
In [69]:
test_rgba = Image.open('/content/drive/My Drive/test_rgba.png')
test_rgba
Out[69]:

Reading an Image as ndarray

In [70]:
# How to read an image as ndarray
from PIL import Image
import numpy as np

im = Image.open('/content/drive/My Drive/br.JPG')
im
Out[70]:
In [71]:
im_a = np.array(Image.open('/content/drive/My Drive/br.JPG'))
print(type(im_a))
print(im_a.dtype)
print(im_a.shape) #3D ndarray whose shape is (row(height), column(width),color(channel))
<class 'numpy.ndarray'>
uint8
(290, 435, 3)
In [72]:
%matplotlib inline
from matplotlib import pyplot as plt
plt.imshow(im_a)
Out[72]:
<matplotlib.image.AxesImage at 0x7f218c66e950>

Saving ndarray as Image File

In [73]:
# Convert the image to grayscale whose shape is (row(height) and column(width))
br_gray = np.array(Image.open('/content/drive/My Drive/br.JPG').convert('L'))
print(br_gray.shape)
(290, 435)
In [74]:
br_gray_pil = Image.fromarray(br_gray)
print(br_gray_pil.mode)
L
In [75]:
br_gray_pil.save('/content/drive/My Drive/br_gray.jpg')
In [76]:
br_gray = Image.open('/content/drive/My Drive/br_gray.jpg')
br_gray
Out[76]:
In [77]:
from PIL import Image
im = Image.open('/content/drive/My Drive/monnig.jpg')
im
Out[77]: