ECE 847 Digital Image Processing Homework 3 Canny Edge Detection Sept. 26, 2008 By Bryan Willimon Homework 3 Homework 3: Canny Edge Detection Introduction The purpose of this assignment is to demonstrate the Canny algorithm for finding edges in an image. Three major steps were involved in determining the final result. The three steps were Convolution with a Gaussian kernel and its derivative, Non-maximal suppression, and edge-linking with hysteresis (double thresh holding). The Chamfer distance was computed on the resulting picture and a template to find an object inside of the image. Theory Several steps were taken in the design of the Canny edge detector. Calculations had to be made about the image to find where the pixel values created a step edge and then bring out the pixels with the higher magnitude to show the edge. Such calculations involve convolution with a Gaussian kernel with respect to x and y, finding the magnitude and angle of the convolved images, then use the magnitude and angle values to give an image with non-maximal suppression and finally use hysteresis to determine where the edges are. Gaussian Convolution The idea is to calculate a Gaussian kernel that would find all of the step edges in each the x-direction and y-direction. To give optimal results, a 5x1 kernel was computed and used in both directions. A 5x1 kernel was used based on the fact that it will give a standard deviation and variance of value 1 and capture 98.76% of the area in a Gaussian. When computing the Gaussian kernel, the formula is used from –x to x and –y to y based on how long the kernel is: When computed G(x), the y value would go to zero and then compute. The same goes for G(y) that x value would be zero. This was used to break down a 5x5 kernel to (2) 5x1 kernels to speed up the process of convolution. Once the Gaussian kernels were computed, then you were able to compute the derivative of the Gaussian kernel: The original Gaussian kernel was used to smooth out the image and derivative was used to look for the step edges in the x and y direction. 2 Homework 3 The following formula was the process of using both of the Gaussian kernels to compute the new image with convolution. Each of the formulas below computed the new gradient images for each convolution in the x and y direction and also calculated the magnitude and angle of the gradients. Non-maximal suppression This technique uses the values of the gradient’s magnitude and phase to find where the edges are location in the image. I uses the process of taking a 3x3 window for each pixel and uses the gradient phase to determine what direction to be looking at for comparison. When the angle is determined, then the value in the positive and negative angle location along with the current pixel is compared to find the maximum value. If the maximum turns out to be the pixel that you are currently on, then value stays the same. Otherwise, the current pixel value goes to zero in the event that one of the other pixels that you were looking at was the maximum. The various angles along with the pixels that you look at are in the following table: To account for all angle values positive and negative, then you would add π to the negative angles to give all values in the upper 180 degree range. In the end, the resulting image would contains all edges with one pixel thickness. Hysteresis (Double Thresh Holding) The final step is hysteresis which I have already used and discussed in the last project. Hysteresis uses the idea of double thresh holding to find the high values of the edges and weed out all of the weaker values as to give an accurate and cleaner image. The first step in 3 Homework 3 hysteresis is to sort all of the non-zero gradient magnitude values and create a histogram with each pixel value along with the amount of times that it shows up in the image. Then take a predetermined percentage value to evaluate the high thresh hold number. For instance, 10% was suggested for this project, but I used 20% based on what looked better for me. Once that value is computed, then take the high thresh hold and divide it by the ratio between high and low and compute the low thresh hold value. After having your two values, you would scan through the image to find all pixel values that had a number higher than the high thresh hold value and turn them to 255 and everything else to 0. Then take a second pass through the image and find all of the pixels that have the value of 255 and then check each of their 8-neighbors to determine which of those pixels have the value above the low thresh hold and then turn them on. I also took another pass in the opposite direction to make sure that I didn’t miss any edges from the first pass. The resulting should have all viable edges marked as foreground and the rest as background. Chamfering Chamfering is used to create a probability map based on how close each pixel is from the closest edge. The second part of this assignment required that we find an object in an image. Chamfering was used to create a probability map on the image and on the template. When each new image was computed, then the new template map is taken throughout the image to calculate the distance from each pixel in the template to the corresponding pixel in the image. All of the distances were added up and store for that area of the image. Next, you would search through your database of areas and find the lowest value and that would give the location of the object with the highest probability. The following images show the algorithm used to find the value of the probability map: Before the map is created, you would first go through the image and make each value equal to the (height*width)+1 to give a reasonable value to represent infinity in the image. Then the algorithm is computed throughout the image to calculate the values. Algorithm and Methodology 4 Homework 3 The first sets of steps were to calculate the 5x1 Gaussian kernel and then compute the derivative of the 5x1 kernel. Once the kernels were calculated, I went through the entire image and used convolution on a 5x1 window of the image and the Gaussian to compute the same image with a smoothing factor and create a new image. I then used the 5x1 Gaussian derivative kernel to move throughout the new image to compute the final X and Y gradients. Each gradient image requires a different function to calculate the gradient for the x and y direction, but with the kernel being the same value for the x and y direction, then the numbers in the kernel will look the same for x and y. Once the gradient images are created, then on to calculating the magnitude and angle of the two gradients to determine where the edges are located in the image. Each pixel value for the magnitude is calculated by taking the square root of the combination of each gradient pixel value squared. Then that gives you the magnitude of pixel value from the original image, and the higher the value, the better that it is an edge. Next, the phases are calculated for each pixel value by taking the tangent inverse of (y/x). Once the phases are computed, they will tell you at which angle that the edge would be pointing, if there is one there. The next step would deal with non-maximal suppression. Non-maximal suppression would look at the values for the phase and magnitude to determine if there is an edge at that particular pixel and how to calculate that. First, the phase would indicate at which angle to be focusing your view at, either it be somewhere between 0 -> 2π. To narrowing down the search, I added the value of π to all negative angles to rotate all of the negative angles 180 degrees to match the positive correspondents. Once I knew which group of angles to look at, I then compared the pixel that I was currently on and the two pixels either (above and below) or (left and right) or some combination of the two to determine which magnitude was greater. If the magnitude that I was currently on was higher, then that pixel value stays the same; otherwise if one of the two values around the current pixel were higher, then that current pixel value would suppress to zero (0). Now that a new image with all of the edges being one pixel thick and represented all of the step edges in the original image, I then use hysteresis to compute which edges are greater in value to bring them out and get rid of the rest based on percentages. The first part of hysteresis is to make a histogram of the pixel values and how many of each value are there in the suppressed image. Once the graph is made, I calculated that the high thresh hold would be the top 20% of the group and then used a ratio of 5 between the high thresh hold and low thresh hold. Once I had the two thresh holds, I just repeated the process from the last assignment of using double thresh holding. That would then give me my final image with all of the good edges showing up. Finally, as an add-on to the project, Chamfering is used to match a template of an object to the object within a larger image. Chamfering is used to calculate the distance from the nearest edge in both the template and larger image. I then take the probability image from both and scan through the larger image with the template as a window and take each individual pixel value within the template and subtract it from the corresponding pixel value within the larger image and sum up all of the distances within the template window to give a total value with each area. I then determine which area out of the whole image is the lowest and consider that area to be the most likely that contains the template. 5 Homework 3 Results Below is each group of original images, gradient-x and gradient-y, the magnitude and angle images of the gradients, the image after non-maximal suppression, resulting image using hysteresis and the images after using chamfering for special cases. I have included cat.pgm, cameraman.pgm, hydrant.pgm, and cherrypepsi.jpg along with cherrypepsi_template.jpg. Here are my results: cat.pgm Original Image Gradient Magnitude X-Gradient Gradient Angle Y-Gradient Non-maximal suppression 6 Homework 3 Resulting Image cameraman.pgm Original Image X-Gradient Y-Gradient 7 Homework 3 Gradient Magnitude Gradient Angle Resulting Image Hydrant.pgm Non-maximal suppression 8 Homework 3 Original Image Y-Gradient Gradient Angle X-Gradient Gradient Magnitude Non-maximal suppression 9 Homework 3 Resulting Image Chamfering Results: Finding a Cherry Pepsi Original Image Original Template Chamfered Image Chamfered Template 10 Homework 3 Resulting Image with location of Cherry Pepsi The results above show the Canny edge detection being used with a 5x1 Gaussian kernel with a sigma value of 1. Each test resulted in success in finding each of the edges for all images. Also, the chamfering gave back a successful run finding the Pepsi can in the image. Conclusion With the above results shown, the Canny edge detector turned out to be a very useful and successful tool that was easy to implement to find all viable edges in an image. Based on the tests that were run, the Canny edge detector picked up more edges in some instances that were not considered a boundary, but still was calculated as an edge. Different scenarios call for different values of sigma or maybe a different size kernel to accurately pick up all of the correct boundaries in an image and not all of the edges. The image that worked well to determine the boundaries was the cameraman because the background contrasted with him very well. Any images that are cluttered and shared the same color as the foreground and background tend to blend together and you can’t find the step edge too well. Also when shadows are involved, the edge detector will depict the shadow and the object as too separate objects and won’t be able to discern between the two. In conclusion, the Canny edge detector works well with any image just as long as the objects have a distinct difference in contrast and with the least amount of shadows. 11