NOTE: Are you interested in machine learning? You can get a copy of my TensorFlow machine learning book on Amazon by clicking HERE
In my previous tutorial, Color Detection in Python with OpenCV, I discussed how you could filter out parts of an image by color.
While it will work for detecting objects of a particular color, it doesn’t help if you’re trying to find a multi-colored object.
For this tutorial, we will be using this basket of fruits.
Let’s say we wanted to detect everything except for the table.
We could try and use color, but that would fail very quickly because all of the fruits are different colors. Since canny edge detection doesn’t rely on color, we can use it to solve our problem.
Canny Edge Detection
If I asked you to draw around the basket, you could easily do it.
But hold on, why is it possible for you to differentiate between the basket and the table?
The answer is that the basket has a different image gradient than the table.
To understand what I mean, take a look at the same image in black and white.
Even without color, you can clearly see the edges of the basket and fruits because the gradients are vastly different at the edges.
Canny edge detection uses this principle to differentiate between edges. All edges have different gradient intensities than their surroundings. If two adjacent parts of the image have the same gradient intensity, then it wouldn’t be an edge as they would have the same hue and saturation.
Applying Canny Edge Detection
We will be loading the image in as a black and white photo. Images in black and white still have gradients, so it is still possible to differentiate between edges. As a rule of thumb, things tend to be much simpler when they are in black and white.
After we load the image, we need to apply canny edge detection on it.
import cv2 from matplotlib import pyplot as plt def nothing(x): pass img_noblur = cv2.imread('fruitbasket.jpg', 0) img = cv2.blur(img_noblur, (7,7)) canny_edge = cv2.Canny(img, 0, 0) cv2.imshow('image', img) cv2.imshow('canny_edge', canny_edge) cv2.createTrackbar('min_value','canny_edge',0,500,nothing) cv2.createTrackbar('max_value','canny_edge',0,500,nothing) while(1): cv2.imshow('image', img) cv2.imshow('canny_edge', canny_edge) min_value = cv2.getTrackbarPos('min_value', 'canny_edge') max_value = cv2.getTrackbarPos('max_value', 'canny_edge') canny_edge = cv2.Canny(img, min_value, max_value) k = cv2.waitKey(37) if k == 27: break
There are four arguments for cv2.Canny. The first one is your input image. The second and third are the min and max values for the gradient intensity difference to be considered an edge. The fourth is an optional argument which we have left blank.
If the fourth argument is set to true, then it uses a slower and more accurate edge detection algorithm. But by default, it is false and will calculate gradient intensity by adding up the absolute values of the gradient’s X and Y components.
Before canny edge detection can be applied, it is usually a good idea to apply a blur to the image so that random noise doesn’t get detected as an edge.
You can adjust the track bar however you’d like to edit the min and max values for the canny edge detection. I found that a min value of 36 and a max value of 53 worked well.
It also depends on how much you are blurring the image. The more you blur the image, the less noise there is. However, blurrier image have less accurate edges.
On the flip side, not enough blurring causes random noise to be detected. In the end, the level of blur is a trade-off between noise and edge accuracy.
Canny edge detection is only one of the many ways to do edge detection. There are hundreds of different edge detection methods, including Sobel, Roberts, SUSAN, Prewitt, and Deriche.
All edge detection methods have pros and cons, and Canny is just one of them. In general, canny edge detection tends to yield good results in most scenarios, so it is well-suited for general use. However, other edge detectors may be better depending on the situation.
If Canny isn’t working effectively for you, try a different solution. The best way to know if something works well is to test it out for yourself.