[Image-SIG] Removing specific range of colors from scanned image
Scott David Daniels
Scott.Daniels at Acm.Org
Tue Apr 28 20:58:00 CEST 2009
Fredrik Lundh wrote:
> On Tue, Apr 28, 2009 at 4:13 PM, Eduardo Ismael <eismb at hotmail.com> wrote:
>> Thanks, John - I'll have a look at numpy and vips (and CIELAB) right away.
>>
>> I'm having trouble thinking out of the "for pixel in image" loop. Is it
>> possible to calculate with images and not pixels with PIL?
>
> Sure - the trick is to figure out how to express your problem in terms
> of the basic operations provided by the Image object itself, by the
> ImageChops or ImageOps modules (which should be merged some day), etc.
>
> And in 1.1.6 and later, there's also the ImageMath module.
>
> http://effbot.org/imagingbook/imagemath.htm
>
> To do a distance calculation, you could do something like:
>
> target = (red, green, blue)
> distance = 10
>
> # calculate a distance mask
> R, G, B = target
> r, g, b = im.split()
> distance3 = distance ** 3
>
> mask = ImageMath.eval(
> "convert(((abs(r - R)*abs(g - G)*abs(b - B)) < distance3)*255, 'L')",
> **locals())
>
> # paste in some nice color on pixels that are "close" to the target color
> im.paste("white", mask)
Warning: this distance function is the product of the three elements,
so an exact match on red, green, or blue will look like a match on all.
Try something like this:
distance2 = 3 * distance ** 2
mask = ImageMath.eval("convert((((r-R)**2 + (g-G)**2 + (b-B)**2) "
" < distance2) * 255, 'L')",
**locals())
--Scott David Daniels
Scott.Daniels at Acm.Org
More information about the Image-SIG
mailing list