1 """Image filters module.
3 All filters return a filtered copy of the image, the original image is
7 from PIL import Image, ImageFilter
11 def color_enhance(image):
12 """Stretch all color channels to their full range."""
13 image_l = image.load()
14 min_r, min_g, min_b = 999, 999, 999
15 max_r, max_g, max_b = -1, -1, -1
17 for x in xrange(image.size[0]):
18 for y in xrange(image.size[1]):
19 min_r = min(min_r, image_l[x, y][0])
20 max_r = max(max_r, image_l[x, y][0])
21 min_g = min(min_g, image_l[x, y][1])
22 max_g = max(max_g, image_l[x, y][1])
23 min_b = min(min_b, image_l[x, y][2])
24 max_b = max(max_b, image_l[x, y][2])
26 new_image = Image.new('RGB', image.size)
27 new_image_l = new_image.load()
28 for x in xrange(image.size[0]):
29 for y in xrange(image.size[1]):
30 r, g, b = image_l[x, y]
31 r = (r - min_r) * 255 / (max_r - min_r)
32 g = (g - min_g) * 255 / (max_g - min_g)
33 b = (b - min_b) * 255 / (max_b - min_b)
34 new_image_l[x, y] = (r, g, b)
35 # print min_r, max_r, r, g, b
39 def edge_detection(image):
40 """Edge detection (on BW images)."""
41 new_image = image.filter(ImageFilter.GaussianBlur())
42 # GaussianBlur is undocumented class, it might not work in future versions
44 new_image = Image.fromstring('L', image.size,
45 pcf.edge(image.size, image.tostring()))
49 """Peak filter (on BW images)."""
50 image_l = image.load()
51 new_image = Image.new('L', image.size)
52 new_image_l = new_image.load()
54 for x in range(2, image.size[0] - 2):
55 for y in range(2, image.size[1] - 2):
58 for b in range(y - 2, y + 3)])
59 for a in range(x - 2, x + 3)])
60 + (17 * image_l[x, y]))
65 new_image_l[x, y] = pix
68 def high_pass(image, height):
69 """High pass filter (on BW images)."""
70 image_l = image.load()
71 new_image = Image.new('L', image.size)
72 new_image_l = new_image.load()
74 for x in xrange(image.size[0]):
75 for y in xrange(image.size[1]):
76 if image_l[x, y] < height:
79 new_image_l[x, y] = image_l[x, y]
83 # TODO factor these into one method
85 def components(image):
86 image_l = image.load()
87 new_image = Image.new('L', image.size)
88 new_image_l = new_image.load()
93 for y in xrange(1, image.size[1] - 1):
94 for x in xrange(1, image.size[0] - 1):
97 s.add(new_image_l[x - 1, y - 1])
98 s.add(new_image_l[x, y - 1])
99 s.add(new_image_l[x + 1, y - 1])
100 s.add(new_image_l[x - 1, y])
102 components.append(set())
103 new_image_l[x, y] = comp_counter
104 components[comp_counter].add((x, y))
109 new_image_l[x, y] = c
110 components[c].add((x,y))
113 c1, c2 = s.pop(), s.pop()
114 components[c2].add((x, y))
115 for (x1, y1) in components[c2]:
116 new_image_l[x1, y1] = c1
117 components[c1] = components[c1] | components[c2]
118 components[c2] = None
120 new_image = Image.new('L', image.size)
121 new_image_l = new_image.load()
123 for component in components:
128 for (x, y) in component:
132 new_image_l[int(round(float(x_c)/c)), int(round(float(y_c)/c))] = 255
136 def components2(image):
137 image_l = image.load()
138 new_image = Image.new('L', image.size)
139 new_image_l = new_image.load()
144 for y in xrange(2, image.size[1] - 2):
145 for x in xrange(2, image.size[0] - 2):
149 for (a, b) in [(a,b) for a in range(x - 2, x + 3)
150 for b in range(y - 2, y + 1)]:
151 if not (b == y and a >= x):
152 s.add(new_image_l[a, b])
155 components.append(set())
156 new_image_l[x, y] = comp_counter
157 components[comp_counter].add((x, y))
162 new_image_l[x, y] = c
163 components[c].add((x,y))
167 components[c1].add((x, y))
168 new_image_l[x, y] = c1
170 for (x1, y1) in components[c2]:
171 new_image_l[x1, y1] = c1
172 components[c1] = components[c1] | components[c2]
173 components[c2] = None
175 new_image = Image.new('L', image.size)
176 new_image_l = new_image.load()
178 for component in components:
183 for (x, y) in component:
187 new_image_l[int(round(float(x_c)/c)), int(round(float(y_c)/c))] = 255