# Canny non-max suppression intro

I have rich experience signal-processing, but haven't touched image processing since my happy university days... so:

Working on a side project, I need to enhance ridges (continuous lines) in a 2D grey-scale image. Using Matlab, I'm at a point where Canny edge detection does a great job, but since many lines are thick, I get 2-edges for each ridge. Some Questions:

• Is Canny a tool fit for the task?
• If so, How do I adapt the Canny algorithm to enhance ridges, instead of edges?
• Where can I find a good intro to Canny edge detection (googled it, nothing really helpful found)?

Canny's original paper addressed the issue of ridge edges and roof edges in addition to step edges, but I'm unaware of any implementation of "Canny" edge detection that detects anything other than step edges. Canny's paper is a pretty easy read, but, unfortunately, paywalled. J. Canny, "A computational approach to edge detection", IEEE Trans. Pattern Analysis and Machine Intelligence, 8:679-714, 1986.

Canny's paper is really about how to use calculus of variations to derive a 1-dimensional filter that has optimal response to each type of edge. It turns out that the ridge-edge filter is not scale invariant (you have to know how wide your ridges are). Here is the picture from Canny's paper of the optimal ridge and roof detection operators (page 683, © IEEE, 1986, this is "fair use"):

What is typically called "Canny edge detection" is as follows:

1. Perform an approximation of a derivative of Gaussian function in X and Y. (This is usually done with a Gaussian blur followed by the Sobel operator.) (The derivative of Guassian is actually not the optimal step-edge detection operator, but the optimal step-edge detection operator "kinda-looks-like" a derivative of Gaussian.)
2. Convert from $\langle\Delta x, \Delta y\rangle$ form at each pixel to $\langle$magnitude,"angle"$\rangle$. (Where "angle" is a 2-bit approximation that tells you whether the edge is closer to horizontal, vertical or one of the two 45-degree diagonals.)
3. "Thinning": For each pixel look at its two neighbors in the "angle" direction and keep the pixel only if it is the maximum of itself and its two neighbors. (Otherwise set the magnitude to 0.)
4. "Thresholding": For each pixel with magnitude less than some "weak threshold" suppress the pixel to 0. For each pixel with magnitude greater than some "strong threshold" set the pixel to whatever value means "definitely an edge." For pixels between the two thresholds set the pixel to the value "maybe an edge".
5. Hysteresis: For each "maybe an edge" pixel change it to "definitely an edge" if any of its 8 neighbors in the horizontal, vertical or diagonal directions is "definitely an edge."

Theoretically, you should be able to turn a Canny edge detector into a ridge-edge detector by changing just step 1, but I've never tried it.