# We will be looking at the following techniques to begin with
from skimage.morphology import erosion, dilation, opening, closing, white_tophat, black_tophat, skeletonize, convex_hull, convex_hull_image
# Importing 'square' and 'disk' modules for creating BINARY structuring elements
from skimage.morphology import square as sq
from skimage.morphology import disk
# Skimage supports NumPy data types and takes in images as type 'ndarray'. matplotlib.pyplot is a python library for providing MATLAB-like functionality, hence the same function names. E.g: imshow
import matplotlib.pyplot as plt
import numpy as np
# Importing the '_io' module for reading, writing and showing images. Note thatin skimage, all files having the same name as the folder have been renamed with an '_'. Hence '_io'
import skimage.io._io as io
from skimage.data import load
from skimage.util import img_as_ubyte
There are essentially 2 ways for importing images for use with skimage. They are as follows :
Note that plt.imread() will read the image, a grey-scale image as a 3D array, whereas with io.imread() there is a parameter 'as_grey=True' for reading it as a 2D array and using 'img_as_ubyte()', can be converted to type : numpy.ndarray with uint8 element. This is the input array for the morphological functions.
The following checks should be made for running the morphological functions :
Image :
Structuring Element :
i_f = plt.imread('/Users/chintak/Repositories/scikit-image/skimage/data/bw_text.png')
# Type : numpy.ndarray, dtype : float32, dimensions : 3
#type(i_f)
#i_f
#ndim(i_f)
# Slicing
i_f2 = i_f[:,:,0]
# To convert to uint8 data type
i = img_as_ubyte(i_f2)
# To display this image
plt.imshow(i, cmap=plt.cm.gray) # For showing gray-scale images
#ndim(i)
plt.show()
skimage.dtype_converter: WARNING: Possible precision loss when converting from float32 to uint8
phantom = img_as_ubyte(io.imread('/Users/chintak/Repositories/scikit-image/skimage/data/phantom.png', as_grey=True))
# 'as_grey=True' ensures that the image is taken as a 2D rather than a 3D array with equal R,G,B values for a point
io.imshow(phantom)
plt.show()
skimage.dtype_converter: WARNING: Possible precision loss when converting from float64 to uint8
# We will be working with phantom.png for this function.
# First defining the structuring element as a disk using disk()
#selem = disk(3);
selem = disk(6);
#selem = disk(10);
eroded = erosion(phantom, selem)
# Displaying the original and eroded image
# 'plt.figure() can be used for showing multiple images together
plt.figure(1)
io.imshow(phantom)
plt.figure(2)
io.imshow(eroded)
plt.show()
Comments :
See how the white boundary of the image disappers or gets eroded as we increse the size of the disk. Also notice the increase in size of the two black ellipses in the center and the disappearance of the 3-4 light grey patches in the lower part of the image.
# We will be working with phantom.png to show difference between erosion and dilation.
# First defining the structuring element as a disk using disk()
#selem = disk(3);
selem = disk(6);
#selem = disk(10);
dilate = dilation(phantom, selem)
# Displaying the original and eroded image
# 'plt.figure() can be used for showing multiple images together
plt.figure(1)
io.imshow(phantom)
plt.figure(2)
io.imshow(dilate)
plt.show()
Comments :
See how the white boundary of the image thickens or gets dialted as we increse the size of the disk. Also notice the decrease in size of the two black ellipses in the centre, with the thickening of the light grey circle in the center and the 3-4 patches in the lower part of the image.
# We will be working with phantom.png for this function.
# First defining the structuring element as a disk using disk()
#selem = disk(3);
selem = disk(6);
#selem = disk(10);
opened = opening(phantom, selem)
# Displaying the original and eroded image
# 'plt.figure() can be used for showing multiple images together
plt.figure(1)
io.imshow(phantom)
plt.figure(2)
io.imshow(opened)
plt.show()
Comments :
Since 'opening' an image is equivalent to erosion followed by dilation, white or lighter portions in the image which are smaller than the structuring element tend to be removed, just as in erosion along with the increase in thickness of black portions and thinning of larger (than structing elements) white portions. But dilation reverses this effect and hence as we can see in the image, the central 2 dark ellipses and the circular lighter portion retain their thickness but the lighter patchs in the bottom get completely eroded.
# We will be working with phantom.png for this function.
# First defining the structuring element as a disk using disk()
#selem = disk(3);
selem = disk(6);
#selem = disk(10);
phantom1 = phantom
phantom[300:310, 200:210] = 0
closed = closing(phantom1, selem)
# Displaying the original and eroded image
# 'plt.figure() can be used for showing multiple images together
plt.figure(1)
io.imshow(phantom1)
plt.figure(2)
io.imshow(closed)
plt.show()
Comments :
Since 'closing' an image is equivalent to dilation followed by erosion, the small black 10X10 pixel wide square introduced has been removed and the -34 white ellipses at the bottom get connected, just as is expected after dilation along with the thinning of larger (than structing elements) black portions. But erosion reverses this effect and hence as we can see in the image, the central 2 dark ellipses and the circular lighter portion retain their thickness but the all black square is completely removed. But note that the white patches at the bottom remain connected even after erosion.
# We will be working with phantom.png for this function.
# First defining the structuring element as a disk using disk()
#selem = disk(3);
selem = disk(5);
#selem = disk(10);
phantom[150:160, 200:210] = 255
w_tophat = white_tophat(phantom, selem)
# Displaying the original and eroded image
# 'plt.figure() can be used for showing multiple images together
plt.figure(1)
io.imshow(phantom)
plt.figure(2)
io.imshow(w_tophat)
#plt.figure(3)
#io.imshow(opening(phantom, selem))
plt.show()
Comments :
This technique is used to locate the bright spots in an image which are smaller than the size of the structuring element. As can be seen, the 10X10 pixel wide white square and a part of the white boundary are highlighted since they are smaller in size as compared to the disk which is of radius 5, i.e. 10 pixels wide. If the radius is decreased to 4, we can see that a center of the square is removed and only the corners are visible, since diagonals are longer than sides.
# We will be working with phantom.png for this function.
# First defining the structuring element as a disk using disk()
#selem = disk(3);
selem = disk(5);
#selem = disk(10);
phantom[150:160, 200:210] = 255
b_tophat = black_tophat(phantom, selem)
# Displaying the original and eroded image
# 'plt.figure() can be used for showing multiple images together
plt.figure(1)
io.imshow(phantom)
plt.figure(2)
io.imshow(b_tophat)
#plt.figure(3)
#io.imshow(opening(phantom, selem))
plt.show()
Comments :
This technique is used to locate the dark spots in an image which are smaller than the size of the structuring element. As can be seen, the 10X10 pixel wide black square is highlighted since it is smaller or equal in size as compared to the disk which is of radius 5, i.e. 10 pixels wide. If the radius is decreased to 4, we can see that a center of the square is removed and only the corners are visible, since diagonals are longer than sides.
# For this we will use ip_text.gif
text = img_as_ubyte(io.imread('/Users/chintak/Repositories/scikit-image/skimage/data/ip_text.gif', as_grey=True)).astype(bool)
skeleton = skeletonize(text)
# Displaying the original image and the skeletonized image
plt.figure(1)
io.imshow(text)
plt.figure(2)
io.imshow(skeleton)
plt.show()
Comments :
As the name suggests, this technique is used to thin the image to 1-pixel wide skeleton by applying thinning successively.
# For this we will use chicken.png
rooster = img_as_ubyte(io.imread('/Users/chintak/Repositories/scikit-image/skimage/data/rooster.png', as_grey=True)).astype(bool)
hull1 = convex_hull_image(rooster)
rooster1 = np.copy(rooster)
rooster1[350:355, 90:95] = 1
hull2 = convex_hull_image(rooster1)
# Displaying the original image and the skeletonized image
plt.figure(1)
io.imshow(rooster)
plt.figure(2)
io.imshow(rooster1)
plt.figure(3)
io.imshow(hull1)
plt.figure(4)
io.imshow(hull2)
plt.show()
Comments :
As the figure illustrates, convex_hull_image() gives the smallestpolygon which covers the white or True completely in the image.