#!/usr/bin/python import random import Image, ImageDraw, ImageChops import copy import json import traceback import os im = Image.open("Mona_Lisa.png") width = im.size[0] height = im.size[1] aafactor = 1 listlen = 1 modperitem = 100 currentbest = 0 itemspergen = listlen*(modperitem+1) mu = 0.1 class triangle(object): def __init__(self,initobj=[]): try : self.R = initobj[0] self.G = initobj[1] self.B = initobj[2] self.A = initobj[3] self.X1 = initobj[4] self.Y1 = initobj[5] self.X2 = initobj[6] self.Y2 = initobj[7] self.X3 = initobj[8] self.Y3 = initobj[9] except : self.R = random.randint(0,255) self.G = random.randint(0,255) self.B = random.randint(0,255) self.A = random.randint(0,255) self.X1 = random.random() self.Y1 = random.random() self.X2 = random.random() self.Y2 = random.random() self.X3 = random.random() self.Y3 = random.random() def modify(self): case = random.randint(1,4) if case == 1: self.R = int(random.gauss(self.R,mu*255)) if self.R < 0: self.R = 0 elif self.R > 255: self.R = 255 self.G = int(random.gauss(self.G,mu*255)) if self.G < 0: self.G = 0 elif self.G > 255: self.G = 255 self.B = int(random.gauss(self.B,mu*255)) if self.B < 0: self.B = 0 elif self.B > 255: self.B = 255 self.A = int(random.gauss(self.A,mu*255)) if self.A < 0: self.A = 0 elif self.A > 255: self.A = 255 elif case == 2: self.X1 = random.gauss(self.X1,mu) self.Y1 = random.gauss(self.Y1,mu) elif case == 3: self.X2 = random.gauss(self.X2,mu) self.Y2 = random.gauss(self.Y2,mu) elif case == 4: self.X3 = random.gauss(self.X3,mu) self.Y3 = random.gauss(self.Y3,mu) def diagnostics(self): print "R:%i" %self.R print "G:%i" %self.G print "B:%i" %self.B print "A:%i" %self.A print "X1:%i" %self.X1 print "Y1:%i" %self.Y1 print "X2:%i" %self.X2 print "Y2:%i" %self.Y2 print "X3:%i" %self.X3 print "Y3:%i" %self.Y3 def contents(self): return [self.R, self.G, self.B, self.A, self.X1, self.Y1, self.X2, self.Y2, self.X3, self.Y3] class triimage(object): def __init__(self,initobj=[]): self.triangles = [] for i in initobj: self.triangles.append(triangle(i)) def modify(self): case1 = random.randint(1,12) if len(self.triangles) == 0 or case1 == 1: self.triangles.append(triangle()) elif case1 == 2: case2 = random.randint(0,len(self.triangles)-1) del self.triangles[case2] else : case2 = random.randint(0,len(self.triangles)-1) self.triangles[case2].modify() def diagnostics(self): for i in xrange(len(self.triangles)): self.triangles[i].diagnostics() print "-----" def contents(self): returnlist = [] for i in xrange(len(self.triangles)): returnlist.append(self.triangles[i].contents()) return returnlist def getimage(self): back = Image.new('RGBA',(width*aafactor,height*aafactor)) for i in xrange(len(self.triangles)): poly = Image.new('RGBA',(width*aafactor,height*aafactor)) pdraw = ImageDraw.Draw(poly) pdraw.polygon([(self.triangles[i].X1*width*aafactor,self.triangles[i].Y1*height*aafactor),(self.triangles[i].X2*width*aafactor,self.triangles[i].Y2*height*aafactor),(self.triangles[i].X3*width*aafactor,self.triangles[i].Y3*height*aafactor)],fill=(self.triangles[i].R,self.triangles[i].G,self.triangles[i].B,self.triangles[i].A)) back.paste(poly,mask=poly) back.thumbnail((width,height),Image.ANTIALIAS) return back.convert('RGB') def load(): global newgoodtriangles global generation try : fin = open('dump') loadlist = json.load(fin) loadtriimages = loadlist[0] generation = loadlist[1] readstate = loadlist[2] random.setstate(settable(readstate)) fin.close() newgoodtriangles = [] for i in loadtriimages: newgoodtriangles.append(triimage(i)) except : print "Couldn't load dump!" traceback.print_exc() print "Initializing with default values" newgoodtriangles = [] for i in xrange(listlen): newgoodtriangles.append(triimage()) generation = 0 random.seed(0) def save(): newgoodtriangles[0].getimage().save('images/' + str(generation) + '.png') try : savelist = [] savetrilist = [] for i in newgoodtriangles: savetrilist.append(i.contents()) savelist.append(savetrilist) savelist.append(generation) savelist.append(random.getstate()) fout = open('dump','w') fout2 = open('backups/' + str(generation) + '.dat','w') json.dump(savelist,fout) json.dump(savelist,fout2) fout.close() fout2.close() except : print "Couldn't dump the data!" traceback.print_exc() try : totalitemsran = generation * itemspergen fout = open('timedata.csv','a') fout.write(str(totalitemsran) + ',' + str(currentbest) + '\n') fout.close() except : print "Couldn't write time data!" traceback.print_exc() def main(): global newgoodtriangles global generation load() for i in xrange(5): generation = generation + 1 triimagelist = [] diff = [] for j in xrange(len(newgoodtriangles)): for k in xrange(modperitem): triimagelist.append(copy.deepcopy(newgoodtriangles[j])) triimagelist[-1].modify() diff.append(difference(im,triimagelist[-1].getimage())) triimagelist.append(copy.deepcopy(newgoodtriangles[j])) diff.append(difference(im,triimagelist[-1].getimage())) list3 = zip(diff,triimagelist) list3.sort() for j in xrange(len(newgoodtriangles)): newgoodtriangles[j] = list3[j][1] print str(generation) + ": " + str(list3[0][0]) global currentbest currentbest = list3[0][0] save() def settable(read): thatlist = [] for i in read[1]: thatlist.append(long(i)) nowoneisatuple = tuple(thatlist) return (read[0],nowoneisatuple,read[2]) def difference(im1,im2): if im1.size != im2.size: raise Exception('Image sizes don\'t match.') diff = 0 im1list = list(im1.getdata()) im2list = list(im2.getdata()) for i in xrange(len(im1list)): rgb1 = im1list[i] rgb2 = im2list[i] diffr = rgb1[0]-rgb2[0] diffg = rgb1[1]-rgb2[1] diffb = rgb1[2]-rgb2[2] diff = diff + diffr*diffr+diffg*diffg+diffb*diffb return diff if __name__ == '__main__': main()