[Image-SIG] Implement sobel filter

Guilherme Polo ggpolo at gmail.com
Wed Aug 31 17:06:07 CEST 2011


2011/8/31 Claudio <claudyus84 at gmail.com>:
> 2011/8/31 Guilherme Polo <ggpolo at gmail.com>:
>> 2011/8/31 Claudio <claudyus84 at gmail.com>:
>>> Hi all,
>>> I'm tring to implement a sobel filter using PIL library with few success.
>>>
>>> Now I never used this library before so any help is appreciate.
>>> I wrote the following code that essential is a standard implementation
>>> of the sobel filter:
>>>
>>> input img, output dimg:
>>> dx = [-1,  0,  1, -2, 0, 2, -1, 0, 1]
>>> dy = [-1, -2, -1,  0, 0, 0,  1, 2, 1]
>>>
>>> ximg = img.filter(ImageFilter.Kernel((3,3), dx, None, 0)) #apply the
>>> kernel in x e y
>>> yimg = img.filter(ImageFilter.Kernel((3,3), dy, None, 0))
>>>
>>> dimg = img.copy()
>>> dest = dimg.load()
>>> xdata = ximg.load() #retrieve the x e y data
>>> ydata = yimg.load()
>>>
>>> for y in range ( img.size[1]):                  # calcolo il gradiente per ogni punto
>>>        for x in range( img.size[0]):
>>> #            dest[x, y] = sqrt( xdata[x, y] * xdata[x, y] + ydata[x, y] * ydata[x, y])
>>>             dest[x, y] = abs( xdata[x, y] ) + abs (ydata[x, y])
>>>
>>> The result is not what I expected, so I misunderstood some function usage?
>>
>> "not what I expected" is too vague. Maybe you have a 8 bits image and
>
> Ok that's true, I was too vague.
> So using the same photo of the stream engine that is on wikipedia [1]
> I obtain this image:
>  https://www.mignanti.eu/articoli/tmp
>
>> the convolution only uses 8 bits to store the results and then you get
>> weird results ?
>
> Well, I'm working on grayscale image but the results should be in the
> same domain.
>

Do you want something like http://i.imgur.com/Ij6s6.png (res1) or
http://imgur.com/kTBLK (res2) ?


# orig is your RGB image, I don't know how you wish to handle the bands
img = ImageOps.grayscale(orig)

dxn = scipy.signal.convolve2d(numpy.array(img), [[-1, 0, 1], [-2, 0,
2], [-1, 0, 1]])
dyn = scipy.signal.convolve2d(numpy.array(img), [[-1, -2, -1], [0, 0,
0], [1, 2, 1]])
resn = dxn + dyn
a = 255. / (resn.max() - resn.min())
b = -a * resn.min()

# cap is a function that returns 0 if a point is below 0 and
# returns 255 if a point is above 255
res1 = Image.fromarray(numpy.uint8((resn * a + b).round()))
res2 = Image.fromarray(numpy.uint8((cap(resn)).round()))


Now I see that I'm very naive with PIL, I don't know how to achieve
exactly the same result using only PIL.


-- 
-- Guilherme H. Polo Goncalves


More information about the Image-SIG mailing list