Edge Detection
Learn edge detection algorithms, thinning, and Hough line detection.
Edges are the sharp color transitions in an image. If the contrast is sufficient, edges can indicate object boundaries but can also be stimulated by a strong texture.
In this lesson, our mission is to locate the edges of the electronic board in the image below.
Choice of the best channel for the task
The edge detection algorithms that we’ll study take a monochrome image as input. We could convert the original image to grayscale, but in this case, a better choice is to use one of the BGR channels. Let’s see why.
import cv2import numpy as nporiginal_img = cv2.imread('./images/electronics/rpi_back.jpg')# Split the image into its color channelsblue_img, green_img, red_img = cv2.split(original_img)cv2.imwrite('./output/0_original.png', original_img)cv2.putText(blue_img, 'blue', (10, 60), cv2.FONT_HERSHEY_SIMPLEX, 1.0, color=0, thickness=2)cv2.imwrite('./output/1_blue.png', blue_img)cv2.putText(green_img, 'green', (10, 60), cv2.FONT_HERSHEY_SIMPLEX, 1.0, color=0, thickness=2)cv2.imwrite('./output/2_blue.png', green_img)cv2.putText(red_img, 'red', (10, 60), cv2.FONT_HERSHEY_SIMPLEX, 1.0, color=0, thickness=2)cv2.imwrite('./output/3_blue.png', red_img)
In line 6, we call cv2.split()
to separate the three channels in separate grayscale images.
The three color channels show various contrast levels between the board area and the background.
Which color channel should we use?
From the inspection of the color channels we just split, which would be the best to locate the board edges?
Blue
Green
Red
Since the background has a texture that will trigger the edge detectors, let’s create a mask of a low red signal. This mask will be active on most of the board surface and inactive on the white background surface. We’ll use erosion and dilation to eliminate small spurious blobs and holes.
The red channel image will be blurred to make the edge detection less sensitive to weak local grayscale variations.
# ... continued# Create a mask of a low red signallow_red_inverse_threshold = 36retval, low_red_mask = cv2.threshold(red_img, low_red_inverse_threshold, 255,cv2.THRESH_BINARY_INV)# Erode and dilate the maskerosion_dilation_kernel = np.ones((3, 3), dtype=np.uint8)low_red_mask = cv2.erode(low_red_mask, erosion_dilation_kernel)low_red_mask = cv2.dilate(low_red_mask, erosion_dilation_kernel)# Dilate a few more times to include a bit more area in the peripherylow_red_mask = cv2.dilate(low_red_mask, erosion_dilation_kernel, iterations=5)# Blur the red channel imageblurred_red_img = cv2.blur(red_img, (5, 5))masked_red_img = np.minimum(blurred_red_img, low_red_mask)cv2.imwrite('./output/0_masked_red.png', masked_red_img)
In lines 4–5, we perform an inverse threshold on the red image to get a low red mask. In lines 8–9, we erode and dilate the low red mask to eliminate the small spurious blobs. In line 11, we dilate the mask five times to include a few pixels from the background in the periphery. In line 14, we blur the red image. In line 16, we mask the blurred red image with the low red mask.
We can see that the board edges were included in the active area, plus a few pixels in the periphery.
Laplacian Edge Detection
The first edge detection algorithm that we’ll try is the Laplacian Edge Detector. It convolves the image with this convolution kernel:
The sum of the entries of