Advertisement
Guest User

gp.py

a guest
Sep 29th, 2016
185
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.77 KB | None | 0 0
  1. import math
  2. import string
  3. import random
  4. import time
  5. from PIL import Image
  6. from PIL import ImageDraw
  7. from operator import attrgetter
  8.  
  9. POSITION_MULTIPLIER = 1
  10. RADIUS_MULTIPLIER = 1
  11. two_pass = False
  12.  
  13. source = "./src.jpg"
  14.  
  15. class Graph:
  16.     def __init__(self, width, height):
  17.         self.width = width
  18.         self.height = height
  19.         self.mse = []
  20.         self.max = 755**2
  21.         self.image = Image.new("RGB", (self.width,self.height), (255,255,255))
  22.  
  23.     def draw(self):
  24.         self.image = Image.new("RGB", (self.width,self.height),(255,255,255))
  25.         self.max = max(self.bot) + 20
  26.         draw = ImageDraw.Draw(self.image)
  27.         for i in range(len(self.mse)):
  28.             if i > 1:
  29.                 x1 = int(float(self.width)/(len(self.mse)-1)*(i))
  30.                 x2 = int(float(self.width)/(len(self.mse)-1)*(i-1))
  31.                 y1 = self.height - (int(float(self.height) / self.max * self.mse[i]))
  32.                 y2 = self.height - (int(float(self.height) / self.max * self.mse[i-1]))
  33.                 draw.line([(x1,y1),(x2,y2)],(0,0,0))
  34.  
  35.         self.image.save("/tmp/graph.png")
  36.         return
  37.  
  38.  
  39. class Stroke:
  40.     def __init__(self, x, y, r, c):
  41.         self.x = x
  42.         self.y = y
  43.         self.r = r
  44.         self.c = c
  45.  
  46.     def soft_mutate(self, magnitude):
  47.         if random.randint(0,1) == 1:
  48.             self.x += int(random.uniform( -magnitude, magnitude) * POSITION_MULTIPLIER)
  49.             self.y += int(random.uniform( -magnitude, magnitude) * POSITION_MULTIPLIER)
  50.             if self.x < 0:
  51.                 self.x = 0
  52.             if self.x > art.width - 1:
  53.                 self.x = art.width -1
  54.             if self.y < 0:
  55.                 self.y = 0
  56.             if self.y > art.height - 1:
  57.                 self.y = art.height - 1
  58.             self.c = art.getpixel((self.x, self.y))
  59.         else:
  60.             self.r += int(random.uniform( -magnitude, magnitude) * RADIUS_MULTIPLIER)
  61.             if self.r < MIN_RADIUS:
  62.                 self.r = MIN_RADIUS
  63.             if self.r > MAX_RADIUS:
  64.                 self.r = MAX_RADIUS
  65.         return
  66.  
  67.  
  68. class Painting:
  69.     def __init__(self, strokes, image):
  70.         self.strokes = strokes
  71.         self.image = image
  72.         self.error = 90000
  73.  
  74.     def mean_square_error( self ):
  75.         ar,ag,ab = self.image.split()
  76.         br,bg,bb = art.split()
  77.         errors = []
  78.         for y in range(art.height):
  79.             for x in range(art.width):
  80.                 if y > 0 and y < art.height and x > 0 and x < art.width:
  81.                     errors.append(( ar.getpixel((x,y)) - br.getpixel((x,y)) ) ** 2)
  82.                     errors.append(( ag.getpixel((x,y)) - bg.getpixel((x,y)) ) ** 2)
  83.                     errors.append(( ab.getpixel((x,y)) - bb.getpixel((x,y)) ) ** 2)
  84.         mean_error = sum(errors)/ ( art.width * art.height )
  85.         return mean_error
  86.  
  87.     def duplicate( self ):
  88.  
  89.         strokes = []
  90.         for stroke in self.strokes:
  91.             strokes.append(Stroke(stroke.x, stroke.y, stroke.r, stroke.c))
  92.         return Painting(strokes, Image.new("RGB", self.image.size, (255,255,255)))
  93.  
  94.     def create_image(self):
  95.         image = Image.new("RGB", self.image.size, (255,255,255))
  96.         draw = ImageDraw.Draw(image)
  97.         for stroke in self.strokes:
  98.             draw_circle( draw, stroke.x, stroke.y, stroke.r, stroke.c)
  99.         self.image = image
  100.         return image
  101.  
  102.  
  103. def draw_circle(draw, x, y, r, c):
  104.  
  105.     draw.ellipse([x-r,y-r,x+r,y+r],c,c)
  106.     return
  107.  
  108. def scale_painting( painting, factor ):
  109.     image = Image.new("RGB", (painting.width*factor,painting.height*factor),(255,255,255))
  110.     strokes = []
  111.     for stroke in painting.strokes:
  112.         strokes.append(Stroke(stroke.x*factor,stroke.y*factor,stroke.r*factor,stroke.c))
  113.     painting = Painting(strokes)
  114.     painting.create_image()
  115.     painting.image.save("./scaled_painting.png")
  116.     return painting
  117.  
  118. def paint( source, num_of_strokes, num_of_tries ):
  119.     global art, MIN_RADIUS, MAX_RADIUS
  120.     graph = Graph(600,400)
  121.     art = Image.open(source)
  122.     art.convert("RGB")
  123.     MIN_RADIUS = int(float(2 )/695*art.width)
  124.     if MIN_RADIUS < 1:
  125.         MIN_RADIUS = 1
  126.     MAX_RADIUS = int(float(66)/695*art.width)
  127.     layers = []
  128.     strokes = []
  129.     print("Creating initial generation")
  130.     prev_error = 999999
  131.     painting = Painting(strokes, Image.new( "RGB", art.size, (255, 255,255)))
  132.     old_image = painting.image
  133.     for stroke in range(num_of_strokes):
  134.         print("STROKE #" + str(stroke))
  135.         x = random.randint(0,art.width - 1)
  136.         y = random.randint(0,art.height- 1)
  137.         r = random.randint(MIN_RADIUS,MAX_RADIUS)
  138.         c = art.getpixel((x,y))
  139.         c2 = old_image.getpixel((x,y))
  140.         n = 0
  141.         ar,ab,ag = c
  142.         br,bb,bg = c2
  143.         av = ar+ab+ag
  144.         bv = br+bb+bg
  145.         while (av-bv)**2 < 32:
  146.             n += 1
  147.             x = random.randint(0,art.width - 1)
  148.             y = random.randint(0,art.height- 1)
  149.             c = art.getpixel((x,y))
  150.             c2 = old_image.getpixel((x,y))
  151.             ar,ab,ag = c
  152.             br,bb,bg = c2
  153.             av = ar+ab+ag
  154.             bv = br+bb+bg
  155.         painting.strokes.append(Stroke(x,y,r,c))
  156.         prev_error = painting.mean_square_error(painting.strokes[stroke])
  157.         loop_num = 0
  158.         while loop_num < num_of_tries:
  159.             old_painting = painting.duplicate()
  160.             painting.strokes[stroke].soft_mutate(5)
  161.             painting.create_image()
  162.             error = painting.mean_square_error(painting.strokes[stroke])
  163.             graph.mse.append(error)
  164.             graph.draw()
  165.             print("MSE: " + str(error))
  166.             if error < prev_error:
  167.                 loop_num = 0
  168.                 painting.create_image()
  169.                 prev_error = error
  170.                 painting.image.save("./painting.png")
  171.             else:
  172.                 painting = old_painting
  173.                 loop_num += 1
  174.     if two_pass:
  175.         for stroke in range(len(painting.strokes)):
  176.             loop_num = 0
  177.             while loop_num < num_of_tries:
  178.                 old_painting = painting.duplicate()
  179.                 painting.strokes[stroke].soft_mutate(5)
  180.                 painting.create_image()
  181.                 error = painting.mean_square_error(painting.strokes[stroke])
  182.                 graph.mse.append(error)
  183.                 graph.draw()
  184.                 print("MSE: " + str(error))
  185.                 if error < prev_error:
  186.                     loop_num = 0
  187.                     painting.create_image()
  188.                     prev_error = error
  189.                     painting.image.save("./painting.png")
  190.                 else:
  191.                     painting = old_painting
  192.                     loop_num += 1
  193.     return painting
  194.  
  195.  
  196. painting = paint('./src.jpg', 500, 30)
  197.  
  198. scale_painting(painting, 10)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement