Source code for filters

"""Image filters module.

All filters return a filtered copy of the image, the original image is
preserved.
"""

from PIL import Image, ImageFilter
import numpy as np

import pcf

[docs]def color_enhance(image): """Stretch all color channels to their full range.""" image_l = image.load() min_r, min_g, min_b = 999, 999, 999 max_r, max_g, max_b = -1, -1, -1 for x in xrange(image.size[0]): for y in xrange(image.size[1]): min_r = min(min_r, image_l[x, y][0]) max_r = max(max_r, image_l[x, y][0]) min_g = min(min_g, image_l[x, y][1]) max_g = max(max_g, image_l[x, y][1]) min_b = min(min_b, image_l[x, y][2]) max_b = max(max_b, image_l[x, y][2]) new_image = Image.new('RGB', image.size) new_image_l = new_image.load() for x in xrange(image.size[0]): for y in xrange(image.size[1]): r, g, b = image_l[x, y] r = (r - min_r) * 255 / (max_r - min_r) g = (g - min_g) * 255 / (max_g - min_g) b = (b - min_b) * 255 / (max_b - min_b) new_image_l[x, y] = (r, g, b) return new_image
[docs]def edge_detection(image): """Edge detection (on BW images).""" new_image = image.filter(ImageFilter.GaussianBlur()) # GaussianBlur is undocumented class, it might not work in future versions # of PIL new_image = Image.fromstring('L', image.size, pcf.edge(image.size, image.tostring())) return new_image
[docs]def peaks(image): """Peak filter (on BW images).""" image_l = image.load() new_image = Image.new('L', image.size) new_image_l = new_image.load() for x in range(2, image.size[0] - 2): for y in range(2, image.size[1] - 2): pix = (sum([sum([ - image_l[a, b] for b in range(y - 2, y + 3)]) for a in range(x - 2, x + 3)]) + (17 * image_l[x, y])) if pix > 255: pix = 255 if pix < 0: pix = 0 new_image_l[x, y] = pix return new_image
[docs]def high_pass(image, height): """High pass filter (on BW images).""" image_l = image.load() new_image = Image.new('L', image.size) new_image_l = new_image.load() for x in xrange(image.size[0]): for y in xrange(image.size[1]): if image_l[x, y] < height: new_image_l[x, y] = 0 else: new_image_l[x, y] = image_l[x, y] return new_image
[docs]def components(image, diameter): # TODO comment # TODO refactor image_l = image.load() new_image_l = np.zeros(image.size, dtype=np.int) components = [None] comp_counter = 1 if diameter == 1: for y in xrange(1, image.size[1] - 1): for x in xrange(1, image.size[0] - 1): if image_l[x, y]: s = {0} s.add(new_image_l[x - 1, y - 1]) s.add(new_image_l[x, y - 1]) s.add(new_image_l[x + 1, y - 1]) s.add(new_image_l[x - 1, y]) if len(s) == 1: components.append(set()) new_image_l[x, y] = comp_counter components[comp_counter].add((x, y)) comp_counter += 1 elif len(s) == 2: s.remove(0) c = s.pop() new_image_l[x, y] = c components[c].add((x, y)) else: s.remove(0) c1, c2 = s.pop(), s.pop() components[c2].add((x, y)) for (x1, y1) in components[c2]: new_image_l[x1, y1] = c1 components[c1] = components[c1] | components[c2] components[c2] = None elif diameter == 2: for y in xrange(2, image.size[1] - 2): for x in xrange(2, image.size[0] - 2): if image_l[x, y]: s = {0} for (a, b) in [(a,b) for a in range(x - 2, x + 3) for b in range(y - 2, y + 1)]: if not (b == y and a >= x): s.add(new_image_l[a, b]) if len(s) == 1: components.append(set()) new_image_l[x, y] = comp_counter components[comp_counter].add((x, y)) comp_counter += 1 elif len(s) == 2: s.remove(0) c = s.pop() new_image_l[x, y] = c try: components[c].add((x, y)) except AttributeError: print s, c raise AttributeError else: s.remove(0) c1 = s.pop() components[c1].add((x, y)) new_image_l[x, y] = c1 for c2 in s: for (x1, y1) in components[c2]: new_image_l[x1, y1] = c1 components[c1] = components[c1] | components[c2] components[c2] = None else: pass #TODO error new_image = Image.new('L', image.size) new_image_l = new_image.load() for component in components: if component: x_c = 0 y_c = 0 c = 0 for (x, y) in component: x_c += x y_c += y c += 1 new_image_l[int(round(float(x_c)/c)), int(round(float(y_c)/c))] = 255 return new_image