pythonimage-processingpython-imaging-libraryscikit-imagesobel

Why does the Sobel filter return a black square?


I'm trying to use sobel and prewitt filters from skimage for edge detection to compare the results, but for both I just get black squares!

That's my code:

import numpy as np
from skimage import filters
from PIL import Image

a=Image.open('F:/CT1.png').convert('L')
a.show()
a=np.asarray(a)
b=filters.sobel(a)
b=Image.fromarray(b)
b.show()

Solution

  • As most methods from scikit-image, the sobel function uses np.float64 for calculations, and thus converts your image appropriately to the range 0.0 ... 1.0. Following, your result b is also of type np.float64 with values in the same range. When now converting to some Pillow Image object, its mode is set to F, which is used for 32-bit floating point pixels.

    Now, the documentation on Image.show tells us, for example:

    On Windows, the image is opened with the standard PNG display utility.

    It remains unclear, in which file format(?) the image is actually displayed. Seemingly, it's PNG, at least according to the temporary file name. But, for example, saving some Image object with mode F as PNG or JPG doesn't work! So, it seems, the image must be somehow converted to make it displayable. The first guess is, that some regular 8-bit image is chosen as default, since you get a nearly all black image, indicating that values 0 and maybe 1 are treated as "very dark". And, in fact, when using something like

    b=Image.fromarray(b * 255)
    

    the Windows image preview displays a proper image when using b.show().

    So, that would be a workaround for the displaying.

    Nevertheless, if you want to save the image instead, you don't necessarily need that conversion, but just need to use a proper file format to store those 32-bit information, TIFF for example:

    b=Image.fromarray(b)
    b.save('b.tiff')