Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Python Image Processing Cookbook

You're reading from   Python Image Processing Cookbook Over 60 recipes to help you perform complex image processing and computer vision tasks with ease

Arrow left icon
Product type Paperback
Published in Apr 2020
Publisher Packt
ISBN-13 9781789537147
Length 438 pages
Edition 1st Edition
Languages
Arrow right icon
Author (1):
Arrow left icon
Sandipan Dey Sandipan Dey
Author Profile Icon Sandipan Dey
Sandipan Dey
Arrow right icon
View More author details
Toc

Table of Contents (11) Chapters Close

Preface 1. Image Manipulation and Transformation 2. Image Enhancement FREE CHAPTER 3. Image Restoration 4. Binary Image Processing 5. Image Registration 6. Image Segmentation 7. Image Classification 8. Object Detection in Images 9. Face Recognition, Image Captioning, and More 10. Other Books You May Enjoy

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

lock icon The rest of the chapter is locked
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at £16.99/month. Cancel anytime