-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathevoimage.py
108 lines (77 loc) · 2.43 KB
/
evoimage.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import Image
import numpy
import random
from dna import DNA
class EvoImage:
population_size = 6
selection_size = 3
def __init__(self, target=None, callback=None):
if target:
self.target = Image.open(target)
# this function is called with the closest specimen
# from the population on each iteration
self.callback = callback
def set_target(self, target):
self.target = Image.open(target)
def run(self):
pop = self.generate_random_population()
ng_size = self.population_size - self.selection_size
gen = 1
i = 0
while True:
i += 1
ng = self.generate_from_population(pop)
pop = self.select_from_population(pop+ng)
if self.callback:
rep = self.select_from_population(pop, 1)
self.callback(rep[0])
def generate_random_population(self):
pop = []
width, height = self.target.size
env = {'width': width, 'height': height}
for i in range(self.selection_size):
pop.append(DNA(environ=env))
return pop
def generate_from_population(self, pop):
ng_size = self.population_size - self.selection_size
ng = []
for i in range(ng_size):
p = random.choice(pop)
c = p.copy()
c.mutate()
ng.append(c)
return ng
def select_from_population(self, pop, n=-1):
if n < 0: n = self.selection_size
pop.sort(lambda x, y:
imgcompare(x.get_image(), y.get_image(),
self.target))
return pop[:n]
# Image operations
def img2array(im):
a = numpy.fromstring(im.tostring(), dtype=numpy.uint8)
a = numpy.reshape(a, (im.size[1], im.size[0], -1))
return a
def imgcompare(one, two, target):
width, height = target.size
# convert images to arrays
ona = img2array(one)
tna = img2array(two)
tga = img2array(target)
# calculate differences
diff = tga-ona
#diff = diff/255
od = numpy.average(diff)
diff = tga-tna
#diff = numpy.abs(diff)
td = numpy.average(diff)
# if one is closer to target, return > 0
# if two is closer to target, return < 0
# if equal, return 0
return cmp(od, td)
if __name__ == '__main__':
def dna_info(dna):
dna.print_info()
print dna._image
ei = EvoImage('monkey.png', dna_info)
ei.run()