Digital Image Processing: Edge Detection

Jeffrey
NTUST-AIVC
5 min readAug 31, 2022

--

Use openCV’s built-in Sobal and Laplacian to find the edge of the graph.

Prolegomenon

In the previous articles, I introduced the Fourier Transform, this time I will introduce another image processing method, edge detection. In openCV, there are many functions that allow us to find the edge of the image, and in this article, I will pick out the more representative Sobal operators and Laplacian operators for the introduction.

Edge detection

Since we want to detect the edge, first we need to understand what the edge is?

the easiest edge

Take the picture above as an example, we can see that the boundary between black and white is the edge we are looking for, that is, the sharp change between pixels.

Laplacian operator

principle

The Laplacian operator uses the method of differentiating the image to extract the edge. The specific derivation method is as follows.

Take a picture similar to the front as an example, take one of the horizontal lines and differentiate it.

(f) is the value of the image. (f’) the first-order differential of f. (f’’) the second-order differential of f.

It can be seen that at the junction of the edges, after a differentiation, there will be an obvious peak. We can set a threshold so that if the image after a differentiation exceeds this threshold, it will be judged as an edge, and subsequent processing will be performed.

However, this method is not rigorous enough, so the image can also be differentiated twice. And the Z point in the second derivative result, that is, “Zero-crossing”, is the edge we are looking for.

After understanding the basic principles, we need to mathematically deduce what the mask required by Laplacian should look like. From the above introduction, it can be seen that the most important part is to differentiate the image, but in fact, this is not difficult in the image, just subtract the pixels of the previous grid from the pixels of the next grid, that is The slope, which is the first derivative, can be obtained.

mathematical expression

After knowing how to derive the first-order differential, the second-order differential can also be derived in a similar way. Here, we will skip the derivation process and see the results directly.

The mathematical formula for second order differential

At this point, we got the Laplacian mask we need.

Laplacian operator mask

Implement

We can use the Laplacian operation function provided in openCV:

dst = cv2.Laplacian(src, ddepth, ksize)

src : the image to be processed.
dst : output image.
ddepth : The depth of the image. There are many flags that can be used. The most commonly used ones are cv2.CV_8U and cv2.CV_16S.
ksize : the size of the mask.

Sample program

The specific code can be viewed on my github.

import cv2def main():
# read image
gray_img = cv2.imread("./lenna.jpg", 0)
cv2.imshow("img",gray_img)
# Try masks of different sizes
for n in range(1, 4):
# 使用拉普拉斯算子
kernel_size = 1+(n*2)
gray_lap = cv2.Laplacian(gray_img, cv2.CV_16S, ksize=kernel_size)
# Convert image format to uint8
abs_lap = cv2.convertScaleAbs(gray_lap)
# display image
cv2.imshow(f"{1+n*2}_lap_img",abs_lap)
cv2.waitKey(0)
cv2.destroyAllWindows()
# save image
cv2.imwrite(f"./result/Laplacian/Laplacian_{1+n*2}.png",abs_lap)
if __name__ == "__main__":
main()
result

Sobal operator

Principle

The following picture is the mask used by the Sobal operator. The left side is for edge detection in the horizontal direction, and the right side is for edge detection in the vertical direction.

Then use this mask the image to get the edge image.

Implement

Just like the Laplacian operator, openCV also provides written Sobal functions.

dst = cv2.Sobel(src, ddepth, dx, dy, ksize)

src : the image to be processed.
dst : output image.
ddepth : The depth of the image. There are many flags that can be used. The most commonly used ones are cv2.CV_8U and cv2.CV_16S.
dx, dy : It is to select the operation to be performed in the horizontal or vertical direction, and choose (1, 0) or (0, 1).
ksize : the size of the mask.

After the Sobal operation, a convertScaleAbs operation is usually performed to convert the image back to a format that can be displayed normally.

dst = cv2.convertScaleAbs(src)

Sample program

The specific code can be viewed on my github.

import cv2def main():
# read image
gray_img = cv2.imread("./lenna.jpg", 0)
cv2.imshow("img",gray_img)
# Try masks of different sizes
for n in range(1, 4):
# use sobel operator
kernel_size = 1+(n*2)
x = cv2.Sobel(gray_img, cv2.CV_16S, 1, 0, ksize=kernel_size)
y = cv2.Sobel(gray_img, cv2.CV_16S, 0, 1, ksize=kernel_size)
# Convert image format to uint8
absX = cv2.convertScaleAbs(x)
absY = cv2.convertScaleAbs(y)
# Add the results from both directions to form a complete contour
dst = cv2.addWeighted(absX, 0.5, absY,0.5,0)
# display image
cv2.imshow(f"{1+n*2}_x",absX)
cv2.imshow(f"{1+n*2}_y",absY)
cv2.imshow(f"{1+n*2}_x+y",dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
# save image
cv2.imwrite(f"./result/Sobal/Sobal_{1+n*2}_x.png",absX)
cv2.imwrite(f"./result/Sobal/Sobal_{1+n*2}_y.png",absY)
cv2.imwrite(f"./result/Sobal/Sobal_{1+n*2}_x+y.png",dst)
if __name__ == "__main__":
main()
input
result(kernel size = 3)
result(kernel size = 5)
result(kernel size = 7)

Done!

Now you know how to use OpenCV to deal with the image, so just go try to do it by yourself. Thanks for your watching, If you like my article don’t forget to leave your clap or share it with your friend. Your appreciation is my motivation. — Jeffrey

Co-Author:Y. S. Huang, a master’s student studying AIVC and likes open-source, if you are interesting, go to check my Github!

--

--