Canny Edge Detector

Welcome to the last section of the first chapter on the PluralSight course Building Image Processing Applications Using scikit-image by Janani Ravi.

In this post we will deal with the Canny edge detector. It is a more complex edge detector that Roberts or Sobel.

For starters we will create in the proper folder a Python script that we will edit as we go using the VSCode IDE. The IDE uses GitHub Copilot to increase productivity. The author of the course uses the Jupyter Notebook. I would like to disclose that I am a Microsoft employee and have been using VSCode for many years. Lately I started using the GitHub Copilot extension.

# **** folder of interest ****
cd C:\Documents\_Image Processing\scikit-image-building-image-processing-applications\02\demos

# **** open file of interest using VSCode ****
(base) C:\Documents\_Image Processing\scikit-image-building-image-processing-applications\02\demos>code CannyEdgeDetection.py

# **** execute python script of interest ****
(base) C:\Documents\_Image Processing\scikit-image-building-image-processing-applications\02\demos>python CannyEdgeDetection.py

We open the folder of interest. In that folder we start VSCode with the name of the Python script that we will edit in this post. Once VSCode opens we need to save the Python script at least once to create and update the contents of the script. After editing and saving, we can execute the Python script which in this case will generate a couple images.

# **** ****
import numpy as np
import matplotlib.pyplot as plt
from scipy import ndimage as ndi

# **** ****
from skimage.feature import canny
from skimage.draw import polygon

We start our Python script by including the libraries we will require for the different operations.

# **** ****
sample_image  = np.zeros(   (500, 500),                         # shape
                            dtype=np.double)                    # data type

# **** draw a polygon in the image ****
poly = np.array((   (200, 100),
                    (150, 200),
                    (150, 300),
                    (250, 300),
                    (350, 200)))

# **** ****
rr, cc = polygon(poly[:, 0], poly[:, 1], sample_image.shape)    # rr, cc = row, column

# **** ****
sample_image[rr, cc] = 1


# **** visualize image ****
plt.figure(figsize=(6, 6))
plt.imshow(sample_image, cmap=plt.cm.gray)
plt.title('sample_image')
plt.show()

We create a polygon with 5 sides. The dimensions and number of sides may be different. This is just a random example.

We then create an image in order to visualize the polygon.

# **** add gaussian noise to image ****
im = ndi.gaussian_filter(sample_image, 4)
im += 0.2 * np.random.random(im.shape)

# **** use canny to detect edges 
#      large values of sigma indicate that the edge detection method is less sensitive to noise ****
edges1 = canny( im, 
                sigma= 1.0)             # sigma = standard deviation of the Gaussian filter
edges12 = canny(im,
                sigma= 1.3)             # sigma = standard deviation of the Gaussian filter
edges2 = canny( im, 
                sigma= 1.7)             # sigma = standard deviation of the Gaussian filter


# **** display results ****
fig, (ax0, ax1, ax2, ax3) = plt.subplots(   nrows=1,                # number of rows 
                                            ncols=4,                # number of columns
                                            figsize=(12, 4),        # figure size
                                            sharex=True,            # share x axis
                                            sharey=True)            # share y axis

# **** plot original image ****
ax0.imshow(im, cmap='gray')
ax0.axis('off')
ax0.set_title('noisy')


# **** plot canny edge detection ****
ax1.imshow(edges1, cmap='gray')
ax1.axis('off')
ax1.set_title('Canny filter, $\sigma=1.0$')


# **** plot canny edge detection ****
ax2.imshow(edges12, cmap='gray')
ax2.axis('off')
ax2.set_title('Canny filter, $\sigma=1.3$')


# **** plot canny edge detection ****
ax3.imshow(edges2, cmap='gray')
ax3.axis('off')
ax3.set_title('Canny filter, $\sigma=1.7$')


# **** tight layout****
fig.tight_layout()

# **** plot canny edge detection ****
plt.show()

Now we add some gaussian noise to the image.

We then use the Canny edge detector to extract the original polygon using three different sigma values. Note that as the value of sigma increases, the edge detector is less sensitive to noise. We will see this when the images are displayed.

We then create a plot with four images. The first will contain the original image. The next three images will show the results of the Canny edge detector using the three sigma values we randomly chose.

The image is then displayed.

In a nutshell, in the past few post dealing with scikit-image we should have learned that working with images is increasingly important, scikit-image is an image processing toolkit, to perform image manipulation, contour and convex hull determination, and edge detection using Sobel, Roberts and Canny edge detectors.

Hope you enjoyed and learned features from the scikit-image library. I know I did.

Remember that one of the best ways to learn is to read, experiment, and repeat as needed. You never know when the concepts learned might be of use in an actual project.

If interested in the code I have placed it in my GitHub repository.

Thanks;

John

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.