import mdp from PIL import Image, ImageDraw, ImageFont #Generate data #Fix the random number generator mdp.numx_rand.seed(1266090063) #Functions for generating shpes taken from the mdp tutorial def uniform(min_, max_, dims): """Return a random number between min_ and max_ .""" return mdp.numx_rand.random(dims)*(max_-min_)+min_ def circumference_distr(center, radius, n): """Return n random points uniformly distributed on a circumference.""" phi = uniform(0, 2*mdp.numx.pi, (n,1)) x = radius*mdp.numx.cos(phi)+center[0] y = radius*mdp.numx.sin(phi)+center[1] return mdp.numx.concatenate((x,y), axis=1) def circle_distr(center, radius, n): """Return n random points uniformly distributed on a circle.""" phi = uniform(0, 2*mdp.numx.pi, (n,1)) sqrt_r = mdp.numx.sqrt(uniform(0, radius*radius, (n,1))) x = sqrt_r*mdp.numx.cos(phi)+center[0] y = sqrt_r*mdp.numx.sin(phi)+center[1] return mdp.numx.concatenate((x,y), axis=1) def rectangle_distr(center, w, h, n): """Return n random points uniformly distributed on a rectangle.""" x = uniform(-w/2., w/2., (n,1))+center[0] y = uniform(-h/2., h/2., (n,1))+center[1] return mdp.numx.concatenate((x,y), axis=1) N = 2000 cf1 = circumference_distr([7.5,6], 2, N/2) cf2 = circumference_distr([5,1], 0.3, N/2) cl1 = circle_distr([3.5,9], 0.5, N/2) cl2 = circle_distr([3,2.5], 0.7, N) r1 = rectangle_distr([5.5,3], 1, 1, N/2) r2 = rectangle_distr([0.5,1], 1, 2, N) r3 = rectangle_distr([1,7.5], 2, 1, N/2) r4 = rectangle_distr([8,1], 2, 1, N/2) x = mdp.numx.concatenate([cf1, cf2, cl1, cl2, r1,r2,r3,r4], axis=0) x = mdp.numx.take(x,mdp.numx_rand.permutation(x.shape[0]), axis=0) gng = mdp.nodes.GrowingNeuralGasNode(max_nodes=400) #Create base image #Convert floating point numbers to intergers for display in an image def point_convert (x, y): """Convert point for gng to image point""" scale = 100. nx = int(x*scale) ny = int(y*scale) return (nx, ny) baseim = Image.new('RGB', (1000, 1000), '#ffffff') pix = baseim.load() for point in x: impoint = point_convert(point[0], point[1]) pix[impoint[0], impoint[1]] = (0,0,0) font = ImageFont.truetype("arial.ttf", 24) step = 20 total_points = x.shape[0] fills = ['#ff0000', '#00ff00', '#0000ff', '#ff00ff', '#00ffff', '#ff0088', '#ff8800', '#0088ff'] for i in range(0, total_points, step): im = baseim.copy() gng.train(x[i: i+step]) objs = gng.graph.connected_components() n_obj = len(objs) draw = ImageDraw.Draw(im) for j,obj in enumerate(objs): for node in obj: fx, fy = node.data.pos nx, ny = point_convert(fx, fy) draw.ellipse((nx-5, ny-5, nx+5, ny+5), fill=fills[j % 8]) draw.text((700,900), "{0:.2%} complete".format(float(i+step)/float(total_points)), font=font, fill='#000000') draw.text((700,930), "{0:d} connected components".format(n_obj), font=font, fill='#000000') del draw im.save('training{0:d}.png'.format(i+step), 'PNG')