Now, we’ve seen the importance of using both low pass and high pass filters for accurate edge detection. But even with these used together, edge detection is still a very complex problem. We have to think about what level of intensity change constitutes an edge, and how we can consistently detect and represent both thin and thick edges. One of the best and most frequently used edge detectors that takes all of these questions into account is the canny edge detector. Canny edge detection is used very widely in computer vision applications because it goes through a series of steps that consistently produce accurately detected edges. First, it filters out noise using a Gaussian blur. Second, it finds the strength and direction of edges in an image using Sobel filters, and we’ve gone through steps like these before. Third, using the output of the Sobel filters, Canny then applies non-maximum suppression which looks at the strength and direction of each detected edge and selects the local maximum pixel to create consistent one pixel wide thin lines that align with the strongest edges. Finally, it uses a process called hysteresis thresholding to isolate the best edges. Hysteresis is a double thresholding process. Let’s see an example taking a one pixel wide cross-section of an image. Here the curve represents the level of intensity in edges where the peaks are very strong edges. To perform hysteresis, we define a high threshold that allows these strong edges to pass through. And we use a second low threshold too. Any edge below this low threshold is considered weak and discarded. But an edge whose strength falls in between this low threshold and the high threshold will be kept only when it’s connected to another strong edge. This way Canny eliminates weak edges and noise and isolates the edges that are the most connected and therefore are most likely to be part of an object boundary. And because Canny emphasizes important edges, we’ll see that it’s very useful in boundary and shape detection. The code to implement Canny edge detection is fairly simple. Here, I’ve read in an image of a sunflower as an example. I’ll first convert it to grayscale using CVT color. Then I’ll begin to implement Canny edge detection. I’ll have to define lower and upper thresholds for implementing hysteresis. The edges that are detected range in intensity values from 0 to 255. So I’ll set the low threshold to 120 and the upper threshold to twice that value, 240. It’s recommended to use a low to high threshold ratio between 1:2 like this, or 1:3 for best results. Then we can use OpenCVs Canny function. This takes in our grayscale image and our lower and upper thresholds that we just defined. And it returns an edge detected image which I’m calling edges. Then I’ll plot the result. The Canny algorithm blurs our image automatically, but you can choose to blur it even more since we’re picking up some noise here. But you can see the basic output: Canny detects the edges of the flower and produces a binary image. But let’s see if we can get even better performance. This time, I’ll try two different Canny implementations. One, I’ll call a wide because it has a very low lower threshold. And the other I called tight which has a much narrower range for acceptable edges. And I’ll display these two images side by side. Here they are. The wide image shows a lot of detected edges, and the tight shows fewer since the cutoff for weak edges is higher. In both cases, we can see that Canny detects boundaries quite well, and produces a binary image within the lines. We can especially see that in this tight version. This becomes very useful when we want to select a certain area of interest to mask or further analyze.