Search code examples
image-processingedge-detectionscikit-imagesobel

Skimage filters.sobel_v result not making sense. Why?


In scikit-image's documentation it says that the kernel for detecting the vertical lines, is:

1   0  -1
2   0  -2
1   0  -1

If I do:

img = np.array([[1.0, 2.0, 3.0], [4, 5, 6], [7, 8, 9]])
Lx = filters.sobel_v(img)

and, then print Lx, I get:

Lx
0.0000 0.0000 0.0000 
0.0000 2.0000 0.0000 
0.0000 0.0000 0.0000

Which doesn't make any sense, since the result should be:

1*(-1) + 3*1 + 4*(-2) + 6*2 + 7*(-1) + 9*1 = -16 + 24 = 8

and not 2, at the central position.

What is going on?


Solution

  • The difference is due to a scaling factor 1/4.

    The Sobel kernel for vertical edge detection is usually defined as:

    Gv

    This kernel can be decomposed as the product of a smoothing kernel and a derivative kernel like this:

    outer product

    In order for the smoothing kernel to be a true averaging filter, it should be scaled by a factor 1/(1+2+1) = 1/4. By doing so, the Sobel kernel becomes:

    Gv scaled

    Although the scaling factor is not mentioned in the documentation, it is actually used in the implementation (check out the source code to convince yourself).