2009/4/28 Eduardo Ismael <ei...@hotmail.com>: > 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?
Yes, but the range of operations is a little limited. Numpy would be easier, if you know that. I know vips well (I'm one of the maintainers) so I tried in that. On my machine (2.7 GHz amd64), this runs in about 3 seconds and needs 20mb of RAM for a 5,000 x 5,000 pixel TIFF: ---------------- from vipsCC import * filename = "bench/wtc_tiled_small.tif" # set all pixels within threshold of blue to 255 blue = [157, 196, 230] threshold = 10 im = VImage.VImage (filename) # calculate (im - blue) # b = a.lin (x, y) finds (b = a * x + y) for each pixel # we have to invert our blue values to get subtract diff = im.lin ([1,1,1], [x * -1 for x in blue]) # square each pixel sq = diff.multiply (diff) # break into three bands, then sum # vips has a split operator, but it's not wrapped in Python, # sadly r = sq.extract_band (0) g = sq.extract_band (1) b = sq.extract_band (2) sum = r.add (b.add(b)) # sqrt each pixel sq = sum.pow (0.5) # now find pixels within a certain distance of our blue point # we get an 8-bit mono image where 255 is "within threshold" mask = sq.less (threshold) # make the image we get the replacement pixels from # we need an image the same size as im, but with [255, 255, 255] for each # pixel # make a black image, add 255, then clip to 8-bit uchar black = VImage.VImage.black (im.Xsize (), im.Ysize (), 3) white = black.lin (1, 255).clip () # and use the mask to pick white or image pixels result = mask.ifthenelse (replace, im) result.write ("test.tif") ----------------- vips has cielab, so you can try that colour space as well. This takes about 5s/20mb. -------------- from vipsCC import * filename = "bench/wtc_tiled_small.tif" # set all pixels within threshold of blue to 255 blue = [157, 196, 230] threshold = 10 im = VImage.VImage (filename) # make a CIELAB image of the blue colour black = VImage.VImage.black (im.Xsize (), im.Ysize (), 3) blue_lab_im = black.lin ([1,1,1], blue).clip ().sRGB2XYZ ().XYZ2Lab () # turn our image to CIELAB as well lab_im = im.sRGB2XYZ ().XYZ2Lab () # find the colour difference diff = lab_im.dE_fromLab (blue_lab_im) # threshold to get a mask image mask = diff.less (threshold) # make a white rgb image white = black.lin (1, 255).clip () # and use the mask to pick white or image pixels result = mask.ifthenelse (white, im) result.write ("test.tif") -------------- J _______________________________________________ Image-SIG maillist - Image-SIG@python.org http://mail.python.org/mailman/listinfo/image-sig