-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy patharena.py
56 lines (44 loc) · 2.23 KB
/
arena.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
import wx
import numpy as np
import weighting
class Arena:
def __init__(self, reference):
self.reference = wx.Bitmap(reference)
# init self.scratch to the same bitmap just to get correct size and bit depth
self.scratch = wx.Bitmap(reference)
# create numpy array from the reference bitmap
bpp = 4 # bytes per pixel
buffer_length = self.scratch.Width * self.scratch.Height * bpp
self.weights = weighting.radial(self.scratch.Width, self.scratch.Height,4).flat
self.ref_array = np.zeros(buffer_length, dtype=np.uint8)
buffer = memoryview(self.ref_array)
self.reference.CopyToBuffer(buffer, wx.BitmapBufferFormat_ARGB32)
# promote the reference array to INT64 to support calculations
self.ref_array = self.ref_array.astype(np.int64)
# now, also create numpy array for the scratch bitmap
self.scratch_array = np.zeros(buffer_length, dtype=np.uint8)
def render(self, genome):
w = self.scratch.Width
h = self.scratch.Height
points = genome[:, 0:6].copy().reshape(-1,3,2)
points[:,:] *= (w, h)
brushes = [wx.Brush(wx.Colour(r,g,b,a)) for (r,g,b,a) in genome[:,6:]*255]
dc = wx.MemoryDC()
dc.SelectObject(self.scratch)
dc.SetBackground(wx.WHITE_BRUSH)
dc.Clear()
# use the Graphics Device Context to support alpha channel drawing
gdc = wx.GCDC(dc)
gdc.SetPen(wx.NullPen)
gdc.DrawPolygonList(points, brushes=brushes)
# deselect the scratch bitmap, so that it can be used by other operations
dc.SelectObject(wx.NullBitmap)
return self.scratch
def getFitness(self, genome):
self.render(genome)
# use the buffer interface to efficiently convert bitmap to numpy array
buffer = memoryview(self.scratch_array)
self.scratch.CopyToBuffer(buffer, wx.BitmapBufferFormat_RGB32)
fitness = np.sum(((self.ref_array - self.scratch_array)*self.weights)**2)
#~ fitness = np.sum((abs(self.ref_array - self.scratch_array)*self.weights))
return fitness