Ioannis mentioned another edge detector he’s fond of using – so here’s a comparison.
To summarise, his method involves shifting the image 1 pixel to the right, and subtracting it from the original image. And then doing the same but shifting one pixel down instead.
This is equivalent to convolving with
[1 0 -1] [2 0 -2] [1 0 -1]
There’s two differences that are worth commenting on:
* Being an even length kernel means that the output is shifted by a half pixel, so the output has a peak which lines up slightly to one side of the edge transition.
* Being so small, the kernel has no noise-reducing properties. The Sobel kernel takes more pixels into it, performing some low-pass filtering, which reduces the noise response. This is of no matter if the image is already pre-low-pass-filtered before edge-detection.
To demonstrate this effect, here’s some samples. I’ve added some (alright, quite a lot of) Gaussian noise to the original image using ImageMagick:
`convert testkb.pgm -evaluate gaussian-noise 15 testkb_noisy.pgm`
[img_assist|nid=51|title=testkb noisy sobel|desc=|link=none|align=none|width=640]
[img_assist|nid=52|title=testkb noisy simple|desc=|link=none|align=none|width=640]
The Sobel filter performs much better on noisy images. But there’s 6 additions and 2 shifts per pixel (and per dimension), and their corresponding memory/register reads+writes, compared to only 2 for the simple one. On the other hand, a Gaussian filter tends to be 5×5 at least, which means 25 full-multiplies (not simple shifts) and adds. So unless there’s a need for the Gaussian pre-filter, the Sobel wins performance-wise…
Next stop, detecting corners…