Introduction to Image Processing

Images as NumPy Arrays


In [ ]:
import numpy as np
import matplotlib.pyplot as plt
from skimage import io
from skimage import data
plt.style.use('ggplot')
%matplotlib inline

A very simple "image"


In [ ]:
X = np.zeros((9, 9))
X[::2, 1::2] = 1
X[1::2, ::2] = 1
plt.imshow(X, cmap=plt.cm.gray, interpolation="nearest")

In [ ]:
camera = data.camera()
print(type(camera))
plt.imshow(camera, cmap=plt.cm.gray)

In [ ]:
print(camera.shape)

In [ ]:
print(camera.dtype)

Histogram Equalization

Q: What is the histogram of an image?


In [ ]:
print(camera.min(), camera.max())

In [ ]:
from scipy.stats import uniform
bins = np.linspace(0, 256, 20)
hist = np.histogram(camera.ravel(), bins, normed=True)[0]
bins = 0.5*(bins[1:] + bins[:-1])
plt.plot(bins, hist, label="original")
estimate = uniform.pdf(bins)
plt.plot(bins, estimate, label="uniform estimate")

Q: What is wrong with the figure above?

Q: What does it mean to improve the contrast of an image?


In [ ]:
from skimage import exposure
camera_eq = exposure.equalize_hist(camera)

In [ ]:
print(camera_eq.min(), camera_eq.max())

In [ ]:
bins = np.linspace(0, 1, 20)
hist = np.histogram(camera_eq.ravel(), bins, normed=True)[0]
bins = 0.5*(bins[1:] + bins[:-1])
plt.plot(bins, hist, label="Original")
estimate_uni = uniform.pdf(bins)
plt.plot(bins, estimate_uni, label="Uniform")
plt.legend(loc="best")

In [ ]:
fig, ax = plt.subplots(2, 2)

ax[0, 0].imshow(camera, cmap=plt.cm.gray)
ax[0, 0].set_xticks([])
ax[0, 0].set_yticks([])
ax[0, 0].grid(False)
ax[0, 0].set_title("Original")

# compute bins and histogram for original image
bins = np.linspace(0, 256, 20)
hist = np.histogram(camera.ravel(), bins, normed=True)[0]
bins = 0.5*(bins[1:] + bins[:-1])
ax[0, 1].plot(bins, hist)

ax[1, 0].imshow(camera_eq, cmap=plt.cm.gray)
ax[1, 0].set_xticks([])
ax[1, 0].set_yticks([])
ax[1, 0].grid(False)
ax[1, 0].set_title("High Contrast")

# compute bins and histogram for high contrast image
bins = np.linspace(0, 1, 20)
hist = np.histogram(camera_eq.ravel(), bins, normed=True)[0]
bins = 0.5*(bins[1:] + bins[:-1])
ax[1, 1].plot(bins, hist)

fig.tight_layout()

Exercise: Image filtering by thresholding

Convert the background in the following image to zero-valued pixels


In [ ]:
coins = data.coins()
plt.imshow(coins, cmap=plt.cm.gray)
plt.xticks([])
plt.yticks([])
plt.grid()

Hint: Use histogram to pick the right threshold


In [ ]:
# enter code here

Q: What was the problem with this approach of thresholding?

Adaptive Thresholding


In [ ]:
from skimage import filters
threshold = filters.threshold_otsu(coins)
coins_low = coins.copy()
coins_low[coins_low < threshold] = 0
plt.imshow(coins_low, cmap=plt.cm.gray)
plt.xticks([])
plt.yticks([])
plt.grid()

In [ ]:
bins = np.linspace(0, 256, 50)
hist = np.histogram(coins.ravel(), bins, normed=True)[0]
bins = 0.5*(bins[1:] + bins[:-1])
plt.plot(bins, hist, label="Histogram")
plt.vlines(threshold, 0, hist.max(), label="Threshold")
plt.legend()

Independent labeling of objects

Segmentation with boolean masks


In [ ]:
plt.imshow(coins_low > 0, cmap=plt.cm.gray)
plt.grid()

Filling in smaller regions


In [ ]:
from skimage.morphology import closing, square
bw = closing(coins_low > 0, square(3))
plt.imshow(bw, cmap=plt.cm.gray)
plt.grid()

In [ ]:
from skimage.segmentation import clear_border
from skimage.color import label2rgb
from skimage.measure import label
# remove artifacts connected to image border
cleared = clear_border(bw)

# label image regions
label_image = label(cleared)
image_label_overlay = label2rgb(label_image, image=coins_low)
plt.imshow(image_label_overlay)
plt.xticks([])
plt.yticks([])

In [ ]:
from skimage.measure import regionprops
import matplotlib.patches as mpatches
fig, ax = plt.subplots(figsize=(10, 6))
ax.imshow(image_label_overlay)

for region in regionprops(label_image):
    # take regions with large enough areas
    if region.area >= 100:
        # draw rectangle around segmented coins
        minr, minc, maxr, maxc = region.bbox
        rect = mpatches.Rectangle((minc, minr), maxc - minc, maxr - minr,
                                  fill=False, edgecolor='red', linewidth=2)
        ax.add_patch(rect)

ax.set_axis_off()
plt.tight_layout()

Exercise: Color each independent region in the following image

Note: Image is entireyly only black and white. It has already been thresholded and binaried


In [ ]:
n = 20
l = 256
im = np.zeros((l, l))
points = l * np.random.random((2, n ** 2))
im[(points[0]).astype(np.int), (points[1]).astype(np.int)] = 1
im = filters.gaussian_filter(im, sigma=l / (4. * n))
blobs = im > im.mean()
plt.imshow(blobs, cmap=plt.cm.gray)
plt.xticks([])
plt.yticks([])

In [ ]:
# enter code here