[Image-SIG] Implement sobel filter
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): # calcolo il gradiente per ogni punto
>>> for x in range( img.size):
>>> # 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 
> I obtain this image:
>> 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