1
votes

I am trying to implement Canny Edge detection algorithm and I've encountered some problems along the way. I think I understand every step of Canny edge detection, but when compared to results given by OpenCv implementation they vary greatly.

It seems that I just can't get the 1px wide edges like the algorithm should produce. Here are the steps and results for this very simple binary image:

Binary Image that is being processed:

Binary Image that is being processed

Gradient magnitude calculated using Sobel operators:

Gradient magnitudes

Edge directions:

1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 <br>
1 / - - - - - - - - - - - \ 1   <br>
1 | / - - - - - - - - - \ | 1  <br>
1 | | / - - - - - - - \ | | 1  <br>
1 | | | / - - - - - \ | | | 1  <br>
1 | | | | | | | | | | | | | 1  <br>
1 | | | | | | | | | | | | | 1  <br>
1 | | | | | | | | | | | | | 1 <br>
1 | | | | | | | | | | | | | 1 <br>
1 | | | | | | | | | | | | | 1 <br>
1 | | | \ - - - - - / | | | 1 <br>
1 | | \ - - - - - - - / | | 1 <br>
1 | \ - - - - - - - - - / | 1 <br>
1 \ - - - - - - - - - - - / 1 <br>
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 

Non maxima suppressed image:

0   0   0   0   0   0   0   0   0   0   0   0   0   0   0<br>
0   0   0   0   0   0   0   0   0   0   0   0   0   0   0<br>
0   0 255   0   0   0   0   0   0   0   0   0 255   0   0<br>
0   0   0   0   0   0   0   0   0   0   0   0   0   0   0<br>
0   0   0   0 255   0   0   0   0   0 255   0   0   0   0<br>
0   0   0   0   0   0   0   0   0   0   0   0   0   0   0<br>
0   0   0   0   0   0   0   0   0   0   0   0   0   0   0<br>
0   0   0   0   0   0   0   0   0   0   0   0   0   0   0<br>
0   0   0   0   0   0   0   0   0   0   0   0   0   0   0<br>
0   0   0   0   0   0   0   0   0   0   0   0   0   0   0<br>
0   0   0   0 255   0   0   0   0   0 255   0   0   0   0<br>
0   0   0   0   0   0   0   0   0   0   0   0   0   0   0<br>
0   0 255   0   0   0   0   0   0   0   0   0 255   0   0<br>
0   0   0   0   0   0   0   0   0   0   0   0   0   0   0<br>
0   0   0   0   0   0   0   0   0   0   0   0   0   0   0

If I perform hysteresis thresholding at this step, I get very thick-edged result. The obvious issue is gradient magnitude values, but I have no idea how to solve it. If someone more experienced and knowledgeable would, be kind enough to point me in the right direction, I would be extremely thankful.

1

1 Answers

2
votes

I don't think Sobel operator is good for your case. Actually the gradient magnitude should roughly sketch the edges already. The latter steps are refining the edge extraction. I am not sure how you implemented the thinning process, what I did is using interpolation to find the pixels where the norms of gradient are local maximum. When I applied Sobel operator, I didn't get very thick edges, but the edges are not very continuous at some points:

0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0
 0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0
 0     0     0     0   270   270   270   270   270   270   270   270     0     0     0     0
 0     0     0   270     0     0     0     0     0     0   270   270     0     0     0     0
 0     0   270     0     0     0     0     0     0     0     0     0     0     0   270     0
 0     0   270     0     0   270   270   270   270     0     0   270     0     0   270     0
 0     0   270     0     0   270     0     0     0     0     0   270     0     0   270     0
 0     0   270     0     0   270     0     0     0     0     0   270     0     0   270     0
 0     0   270     0     0   270     0     0     0     0     0   270     0     0   270     0
 0     0   270     0     0     0     0     0     0     0     0   270     0     0   270     0
 0     0   270   270     0     0     0     0     0     0     0   270     0     0   270     0
 0     0   270   270     0   270   270   270   270   270   270   270     0     0   270     0
 0     0     0     0     0     0     0     0     0     0     0     0     0   270   270     0
 0     0     0     0     0     0     0     0     0     0     0     0   270   270     0     0
 0     0     0     0   270   270   270   270   270   270   270   270   270     0     0     0
 0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0

When I used standard deviation of the gaussian function to convolve the original image in order to get the gradient, I can finally get clear thin edges:

0     0     0     0     0     0     0     0     0     0     0     0     0     0
 0     1   494   494   494   494   494   494   494   494   494   494     1     1
 0   494     1     1     1     1     1     1     1     1     1     1   494     1
 0   494     1     1   494   494   494   494   494   494     1     1   494     1
 0   494     1   494   494     1     1     1     1   494   494     1   494     1
 0   494     1   494     1     1     1     1     1     1   494     1   494     1
 0   494     1   494     1     1     1     1     1     1   494     1   494     1
 0   494     1   494     1     1     1     1     1     1   494     1   494     1
 0   494     1   494     1     1     1     1     1     1   494     1   494     1
 0   494     1   494   494     1     1     1     1   494   494     1   494     1
 0   494     1     1   494   494   494   494   494   494     1     1   494     1
 0   494     1     1     1     1     1     1     1     1     1     1   494     1
 0     1   494   494   494   494   494   494   494   494   494   494     1     1
 0     1     1     1     1     1     1     1     1     1     1     1     1     1