Book Image

Python Image Processing Cookbook

By : Sandipan Dey
Book Image

Python Image Processing Cookbook

By: Sandipan Dey

Overview of this book

With the advancements in wireless devices and mobile technology, there's increasing demand for people with digital image processing skills in order to extract useful information from the ever-growing volume of images. This book provides comprehensive coverage of the relevant tools and algorithms, and guides you through analysis and visualization for image processing. With the help of over 60 cutting-edge recipes, you'll address common challenges in image processing and learn how to perform complex tasks such as object detection, image segmentation, and image reconstruction using large hybrid datasets. Dedicated sections will also take you through implementing various image enhancement and image restoration techniques, such as cartooning, gradient blending, and sparse dictionary learning. As you advance, you'll get to grips with face morphing and image segmentation techniques. With an emphasis on practical solutions, this book will help you apply deep learning techniques such as transfer learning and fine-tuning to solve real-world problems. By the end of this book, you'll be proficient in utilizing the capabilities of the Python ecosystem to implement various image processing techniques effectively.
Table of Contents (11 chapters)

Creating pencil sketches from images

Producing sketches from images is all about detecting edges in images. In this recipe, you will learn how to use different techniques, including the difference of Gaussian (and its extended version, XDOG), anisotropic diffusion, and dodging (applying Gaussian blur + invert + thresholding), to obtain sketches from images.

Getting ready

The following libraries need to be imported first:

import numpy as np
from skimage.io import imread
from skimage.color import rgb2gray
from skimage import util
from skimage import img_as_float
import matplotlib.pylab as plt
from medpy.filter.smoothing import anisotropic_diffusion
from skimage.filters import gaussian, threshold_otsu

How to do it...

The following steps need to be performed:

  1. Define the normalize() function to implement min-max normalization in an image:
def normalize(img):
return (img-np.min(img))/(np.max(img)-np.min(img))
  1. Implement the sketch() function that takes an image and the extracted edges as input:
def sketch(img, edges):
output = np.multiply(img, edges)
output[output>1]=1
output[edges==1]=1
return output

  1. Implement a function to extract the edges from an image with anisotropic diffusion:
def edges_with_anisotropic_diffusion(img, niter=100, kappa=10, gamma=0.1):
output = img - anisotropic_diffusion(img, niter=niter, \
kappa=kappa, gamma=gamma, voxelspacing=None, \
option=1)
output[output > 0] = 1
output[output < 0] = 0
return output
  1. Implement a function to extract the edges from an image with the dodge operation (there are two implementations):
def sketch_with_dodge(img):
orig = img
blur = gaussian(util.invert(img), sigma=20)
result = blur / util.invert(orig)
result[result>1] = 1
result[orig==1] = 1
return result

def edges_with_dodge2(img):
img_blurred = gaussian(util.invert(img), sigma=5)
output = np.divide(img, util.invert(img_blurred) + 0.001)
output = normalize(output)
thresh = threshold_otsu(output)
output = output > thresh
return output
  1. Implement a function to extract the edges from an image with a Difference of Gaussian (DOG) operation:
def edges_with_DOG(img, k = 200, gamma = 1):
sigma = 0.5
output = gaussian(img, sigma=sigma) - gamma*gaussian(img, \
sigma=k*sigma)
output[output > 0] = 1
output[output < 0] = 0
return output

  1. Implement a function to produce sketches from an image with an Extended Difference of Gaussian (XDOG) operation:
def sketch_with_XDOG(image, epsilon=0.01):
phi = 10
difference = edges_with_DOG(image, 200, 0.98).astype(np.uint8)
for i in range(0, len(difference)):
for j in range(0, len(difference[0])):
if difference[i][j] >= epsilon:
difference[i][j] = 1
else:
ht = np.tanh(phi*(difference[i][j] - epsilon))
difference[i][j] = 1 + ht
difference = normalize(difference)
return difference

If you run the preceding code and plot all of the input/output images, you will obtain an output like the following screenshot:

How it works...

As you can see from the previous section, many of the sketching techniques work by blurring the edges (for example, with Gaussian filter or diffusion) in the image and removing details to some extent and then subtracting the original image to get the sketch outlines.

The gaussian() function from the scikit-image filters module was used to blur the images.

The anisotropic_diffusion() function from the filter.smoothing module of the medpy library was used to find edges with anisotropic diffusion (a variational method).

The dodge operation divides (using np.divide()) the image by the inverted blurred image. This highlights the boldest edges in the image.

There's more...

There are a few more edge detection techniques, such as Canny (with hysteresis thresholds), that you can try to produce sketches from images. You can try them on your own and compare the sketches obtained using different algorithms. Also, by using OpenCV-Python's pencilSketch() and sylization() functions, you can produce black and white and color pencil sketches, as well as watercolor-like stylized images, with the following few lines of code:

import cv2
import matplotlib.pylab as plt
src = cv2.imread('images/bird.png')
#dst = cv2.detailEnhance(src, sigma_s=10, sigma_r=0.15)
dst_sketch, dst_color_sketch = cv2.pencilSketch(src, sigma_s=50, sigma_r=0.05, shade_factor=0.05)
dst_water_color = cv2.stylization(src, sigma_s=50, sigma_r=0.05)

If you run this code and plot the images, you will get a diagram similar to the following screenshot:

See also