def solve_monkey(dist = False): path = 'screenshots/%s.png' % datetime.now().strftime("%Y-%m-%d_%H-%M-%S") print('Taking screenshot') call(['monkeyrunner', 'monkeyscreen.py', path]) print('Rotating') call(['convert', '-rotate', '90', path, path]) print('Starting image solver') val, xmarks, ymarks = solve_image(path, dist) print('Generating solution path') pathparts = splitext(path) pathsol = '%s.sol_path.txt' % pathparts[0] solfile = open(pathsol, 'w') level = Level() level.rows = len(val) level.cols = len(val[0]) for x, y in product(range(level.cols), range(level.rows)): c, t = val[y][x][0] if t != 0: continue #print('Tracing color', c) # Found a dot, start cx, cy, ct = x, y, 0 while True: # Print current #print(cx, cy, ct) solfile.write('%d %d\n' % (avg([xmarks[cx], xmarks[cx+1]]), avg([ymarks[cy], ymarks[cy+1]]))) # Find next cx2, cy2, ct2 = -1, -1, -1 for nx, ny in level.neighbors(cx, cy): nc, nt = val[ny][nx][0] if nc >= 0 and connects(cx, cy, ct, nx, ny, nt): cx2 = nx cy2 = ny ct2 = nt break # Found nothing - done if cx2 == -1: break # Delete current and replace with next val[cy][cx][0] = -1, -1 cx = cx2 cy = cy2 ct = ct2 # Delete last val[cy][cx][0] = -1, -1 solfile.write('0 0\n') solfile.close() print('Solving on device') call(['monkeyrunner', 'monkeypath.py', pathsol]) print('DONE')
def parse_image(path, pathcrop): img = Image.open(path) pix = img.load() # TODO proper line detection instead of color matching #border_color = (131, 97, 66) # brown #border_color = (123, 125, 66) # green border_color = pix[2, 180] border_threshold = 128 xbuckets = defaultdict(int) ybuckets = defaultdict(int) # Find borders for pos in product(xrange(img.size[0]), xrange(img.size[1])): col = pix[pos] dist2 = color_dist2(col, border_color) if dist2 < border_threshold: xbuckets[pos[0]] += 1 ybuckets[pos[1]] += 1 # Throw away below average (keeps the main lines) xbuckets = {k:v for k,v in xbuckets.items() if v > avg(xbuckets.values())} ybuckets = {k:v for k,v in ybuckets.items() if v > avg(ybuckets.values())} # Merge neighbor buckets xmarks = sorted(merge_buckets(xbuckets).keys()) ymarks = sorted(merge_buckets(ybuckets).keys()) #pprint(xmarks) #pprint(ymarks) # Figure out coordinates minx, miny, maxx, maxy = avg([xmarks[0], xmarks[1]]), avg([ymarks[0], ymarks[1]]), avg([xmarks[-1], xmarks[-2]]), avg([ymarks[-1], ymarks[-2]]) xsize = len(xmarks) - 1 ysize = len(ymarks) - 1 level = Level() level.cols = xsize level.rows = ysize level.tiles = [[None for i in range(xsize)] for j in range(ysize)] circle_ratio = 0.4 out_ratio = 0.8 circle_threshold = 128 out_threshold = 1024 color_map = {} map_threshold = 32 for i, j in product(range(xsize), range(ysize)): x, y = avg([xmarks[i], xmarks[i+1]]), avg([ymarks[j], ymarks[j+1]]) w = min(xmarks[i+1] - xmarks[i], ymarks[j+1] - ymarks[j]) # Ignore empty if pix[x, y] == (0, 0, 0): continue center = avg_color([pix[x+a, y+b] for a,b in product([-1, 0, 1], [-1, 0, 1])]) inside = sample(pix, x, y, w*circle_ratio/2, 8) inside_dist2 = avg([color_dist2(center, ic) for ic in inside]) if inside_dist2 > circle_threshold: #print('IN Rejecting ', i, j) #print(inside) #print(inside_dist2) continue outside = sample(pix, x, y, w*out_ratio/2, 8) outside_dist2 = avg([color_dist2(center, oc) for oc in outside]) if outside_dist2 < out_threshold: #print('OUT Rejecting ', i, j) #print(outside) #print(outside_dist2) continue id = None for k, v in color_map.items(): if color_dist2(k, center) < map_threshold: id = v #print(x,y, 'id=', v) if id is None: id = len(color_map) color_map[center] = id level.tiles[j][i] = id ImageDraw.Draw(img).ellipse((x-w/5-1, y-w/5-1, x+w/5+1, y+w/5+1), fill = 'black') ImageDraw.Draw(img).ellipse((x-w/5, y-w/5, x+w/5, y+w/5), fill = 'white') ImageDraw.Draw(img).text((x+1, y), str(id), fill = 'black') ImageDraw.Draw(img).text((x-1, y), str(id), fill = 'black') ImageDraw.Draw(img).text((x, y+1), str(id), fill = 'black') ImageDraw.Draw(img).text((x, y-1), str(id), fill = 'black') ImageDraw.Draw(img).text((x, y), str(id), fill = 'white') level.colors = len(color_map) img = img.crop((xmarks[0], ymarks[0], xmarks[-1], ymarks[-1])) img = img.resize((int(img.size[0]*0.75), int(img.size[1]*0.75))) img.show() img.save(pathcrop) return (level, {v:k for k,v in color_map.items()}, xmarks, ymarks)