Esempio n. 1
0
 def create_screen_paper(self, resolution):
     # it seems value is useless, its zero...
     # why does this need to be four dimensional
     data = numpy.zeros((resolution[1], resolution[0], 4))
     # data = numpy.zeros((200, 200, 4))
     self.ptr = coordinate_functions.prime_
     self.color_ptr = color_r_x_g_y_b_y
     for (x_coor, y_coor, z), value in numpy.ndenumerate(data):
         if self.ptr(x_coor, y_coor):
             data[x_coor, y_coor] = self.color_ptr(x_coor, y_coor)
     im = Image.fromarray(data.astype('uint8'), 'RGBA')
     ImageShow.register(Feh, -500)
     ImageShow.show(im)
     return im
def visualize(solution):
    print solution.solution
    image = Image.new('L', (len(solution.solution[0]) * SIDE_LENGTH, len(solution.solution) * SIDE_LENGTH))
    pixels = image.load()
    
    for x in range(len(solution.solution[0])):
        for y in range(len(solution.solution)):
            for i in range(SIDE_LENGTH):
                for j in range(SIDE_LENGTH):
                    curr_x = x * SIDE_LENGTH + i 
                    curr_y = y * SIDE_LENGTH + j
                    if solution.solution[y][x] == 0:
                        pixels[curr_x, curr_y] = 255
                    else:
                        pixels[curr_x, curr_y] = 0
    
    ImageShow.show(image, 'solution')
    image.save('fakesolution.jpg')
def visualize(solution):
    print solution.solution
    image = Image.new('L', (len(solution.solution[0]) * SIDE_LENGTH,
                            len(solution.solution) * SIDE_LENGTH))
    pixels = image.load()

    for x in range(len(solution.solution[0])):
        for y in range(len(solution.solution)):
            for i in range(SIDE_LENGTH):
                for j in range(SIDE_LENGTH):
                    curr_x = x * SIDE_LENGTH + i
                    curr_y = y * SIDE_LENGTH + j
                    if solution.solution[y][x] == 0:
                        pixels[curr_x, curr_y] = 255
                    else:
                        pixels[curr_x, curr_y] = 0

    ImageShow.show(image, 'solution')
    image.save('fakesolution.jpg')
def find_numbers(puzzlegrid, skewless_picture, pic_name):
    positions = []
    width, height = skewless_picture.size
    print "image size: ", width, height

    # traverse grid, determine min/max x and y coords
    min_x = int(puzzlegrid.grid[0][0])
    max_x = int(puzzlegrid.grid[1][0])
    min_y = int(puzzlegrid.grid[0][1])
    max_y = int(puzzlegrid.grid[1][1])

    # sort coordinates in ascending order
    puzzlegrid.x_coords = sorted(puzzlegrid.x_coords)
    puzzlegrid.y_coords = sorted(puzzlegrid.y_coords)

    print "min x, max x: ", min_x, max_x
    print "min_y, max_y: ", min_y, max_y

    # convert image to grayscale array
    grayscale_picture = skewless_picture.convert("L")
    pixels = grayscale_picture.load()

    # calculate average change in color per cell
    # compare to threshold, if greater, has number
    THRES_LOW = 2000  #??
    THRES_HIGH = 10000

    # top
    top = []
    for x in puzzlegrid.x_coords:
        if x == max_x:
            continue

        x_list = []
        for y in range(min_y - puzzlegrid.cell_height, 0,
                       -puzzlegrid.cell_height):
            # calculate average
            average = 0
            for k in range(puzzlegrid.cell_width):
                for l in range(puzzlegrid.cell_height):
                    curr_x = x + k
                    curr_y = y + l
                    average += pixels[curr_x, curr_y]  #??
            average /= (puzzlegrid.cell_width * puzzlegrid.cell_height)

            # calculate variance
            variance = 0
            for k in range(puzzlegrid.cell_width):
                for l in range(puzzlegrid.cell_height):
                    curr_x = x + k
                    curr_y = y + l
                    variance += pow(pixels[curr_x, curr_y] - average, 2)  #??
            variance /= (puzzlegrid.cell_width * puzzlegrid.cell_height)

            # has number, save cell top-left corner in positions
            if variance > THRES_LOW and variance < THRES_HIGH:
                x_list.append((x, y))
                positions.append((x, y))
            else:
                break
        top.append(x_list)

    # left
    side = []
    for y in puzzlegrid.y_coords:
        if y == max_y:
            continue

        y_list = []
        for x in range(min_x - puzzlegrid.cell_width, 0,
                       -puzzlegrid.cell_width):
            # calculate average
            average = 0
            for k in range(puzzlegrid.cell_width):
                for l in range(puzzlegrid.cell_height):
                    curr_x = x + k
                    curr_y = y + l
                    average += pixels[curr_x, curr_y]  #??
            average /= (puzzlegrid.cell_width * puzzlegrid.cell_height)

            # calculate variance
            variance = 0
            for k in range(puzzlegrid.cell_width):
                for l in range(puzzlegrid.cell_height):
                    curr_x = x + k
                    curr_y = y + l
                    variance += pow(pixels[curr_x, curr_y] - average, 2)  #??
            variance /= (puzzlegrid.cell_width * puzzlegrid.cell_height)

            # has number, save cell top-left corner in positions
            if variance > THRES_LOW and variance < THRES_HIGH:
                y_list.append((x, y))
                positions.append((x, y))
            else:
                break
        side.append(y_list)

    if DRAW:
        draw = ImageDraw.Draw(skewless_picture)
        BOXSIZE = 3
        for point in positions:
            ptx = point[0]
            pty = point[1]
            draw.rectangle(
                [ptx - BOXSIZE, pty - BOXSIZE, ptx + BOXSIZE, pty + BOXSIZE],
                fill=128)
        del draw
        ImageShow.show(skewless_picture, 'with points')
        skewless_picture.save('./images/intermediate/' + pic_name +
                              '_foundnumbers.jpg')

    # save training images
    if TRAIN:
        for point in positions:
            ptx = int(point[0])
            pty = int(point[1])
            picture = skewless_picture.crop([
                ptx, pty, ptx + puzzlegrid.cell_width,
                pty + puzzlegrid.cell_height
            ])
            picture.save("./images/train/{0}_{1}_{2}.jpg".format(
                pic_name, ptx, pty))

    digits = Representations.DigitsRep(top, side)
    print "top"
    print digits.top
    print "side"
    print digits.side

    return digits  # digits representation
def find_numbers(puzzlegrid, skewless_picture, pic_name):
    positions = []
    width, height = skewless_picture.size
    print "image size: ", width, height
    
    # traverse grid, determine min/max x and y coords
    min_x = int(puzzlegrid.grid[0][0])
    max_x = int(puzzlegrid.grid[1][0])
    min_y = int(puzzlegrid.grid[0][1])
    max_y = int(puzzlegrid.grid[1][1])
    
    # sort coordinates in ascending order
    puzzlegrid.x_coords = sorted(puzzlegrid.x_coords)
    puzzlegrid.y_coords = sorted(puzzlegrid.y_coords)
    
    print "min x, max x: ", min_x,  max_x
    print "min_y, max_y: ", min_y,  max_y
    
    # convert image to grayscale array
    grayscale_picture = skewless_picture.convert("L")
    pixels = grayscale_picture.load()
    
    # calculate average change in color per cell
    # compare to threshold, if greater, has number
    THRES_LOW = 2000 #??
    THRES_HIGH = 10000
    
    # top
    top = []
    for x in puzzlegrid.x_coords:
        if x == max_x:
            continue
        
        x_list = []
        for y in range(min_y - puzzlegrid.cell_height, 0, -puzzlegrid.cell_height):  
            # calculate average
            average = 0
            for k in range(puzzlegrid.cell_width):
                for l in range(puzzlegrid.cell_height):
                    curr_x = x + k
                    curr_y = y + l
                    average += pixels[curr_x, curr_y] #??
            average /= (puzzlegrid.cell_width * puzzlegrid.cell_height)
            
            # calculate variance
            variance = 0
            for k in range(puzzlegrid.cell_width):
                for l in range(puzzlegrid.cell_height):
                    curr_x = x + k
                    curr_y = y + l
                    variance += pow(pixels[curr_x, curr_y] - average, 2) #??
            variance /= (puzzlegrid.cell_width * puzzlegrid.cell_height)
            
            # has number, save cell top-left corner in positions
            if variance > THRES_LOW and variance < THRES_HIGH:
                x_list.append((x, y))
                positions.append((x, y))
            else:
                break
        top.append(x_list)
        
    # left
    side = []
    for y in puzzlegrid.y_coords:
        if y == max_y:
            continue
         
        y_list = []
        for x in range(min_x - puzzlegrid.cell_width, 0, -puzzlegrid.cell_width):
            # calculate average
            average = 0
            for k in range(puzzlegrid.cell_width):
                for l in range(puzzlegrid.cell_height):
                    curr_x = x + k
                    curr_y = y + l
                    average += pixels[curr_x, curr_y] #??
            average /= (puzzlegrid.cell_width * puzzlegrid.cell_height)
            
            # calculate variance
            variance = 0
            for k in range(puzzlegrid.cell_width):
                for l in range(puzzlegrid.cell_height):
                    curr_x = x + k
                    curr_y = y + l
                    variance += pow(pixels[curr_x, curr_y] - average, 2) #??
            variance /= (puzzlegrid.cell_width * puzzlegrid.cell_height)
            
            # has number, save cell top-left corner in positions
            if variance > THRES_LOW and variance < THRES_HIGH:
                y_list.append((x, y))
                positions.append((x, y))
            else:
                break
        side.append(y_list)
                
    if DRAW:
        draw = ImageDraw.Draw(skewless_picture)
        BOXSIZE = 3
        for point in positions:
            ptx = point[0]
            pty = point[1]  
            draw.rectangle([ptx-BOXSIZE, pty-BOXSIZE, ptx+BOXSIZE, pty+BOXSIZE], fill=128)
        del draw
        ImageShow.show(skewless_picture, 'with points')
        skewless_picture.save('./images/intermediate/' + pic_name + '_foundnumbers.jpg')
    
    # save training images
    if TRAIN:
        for point in positions:
            ptx = int(point[0])
            pty = int(point[1])
            picture = skewless_picture.crop([ptx, pty, ptx + puzzlegrid.cell_width, pty + puzzlegrid.cell_height]);
            picture.save("./images/train/{0}_{1}_{2}.jpg".format(pic_name, ptx, pty))

    digits = Representations.DigitsRep(top, side)
    print "top"
    print digits.top
    print "side"
    print digits.side
    
    return digits # digits representation
Esempio n. 6
0
def fix_skew(pic_name, picture):
    accumulator = {} # (theta, rho): num_votes
    found_points = {}
    rotation = 0;
    
    # convert image to grayscale array
    grayscale_picture = picture.convert("L")
    pixels = grayscale_picture.load()
    
    # traverse pixels in image to vote
    width, height = picture.size
    
    THRES_BLACK = 30
    
    for x in range(width):
        for y in range(height):
            # check if pixel is "black"
            if pixels[x, y] < THRES_BLACK:
                # 180 lines through (x, y), vote
                THETA_RANGE = 10
                for theta in range(-1 * THETA_RANGE, THETA_RANGE):
                    rho = round(x * math.cos(theta) + y * math.sin(theta))
                    ac_key = (theta, rho)
                    if ac_key not in accumulator:
                        accumulator[ac_key] = 1
                        found_points[ac_key] = []
                    else:
                        accumulator[ac_key] += 1
                    found_points[ac_key].append((x, y))
    
    # find (theta, rho) with most votes
    max_votes = 0
    max_key = (0,0)
    
    for key in accumulator:
        if accumulator[key] > max_votes:
            max_votes = accumulator[key] # num_votes
            max_key = key
    
    print "votes: ", max_votes
    print "key: ", max_key
    
    # draw points associated with max key
    # find min y value to crop
    if DRAW:
        draw = ImageDraw.Draw(picture)
        BOXSIZE = 3
        min_y = 0
        for point in found_points[max_key]:
            ptx = point[0]
            pty = point[1]
            if (pty > min_y):
                min_y = pty   
            draw.rectangle([ptx-BOXSIZE, pty-BOXSIZE, ptx+BOXSIZE, pty+BOXSIZE], fill=128)
        del draw
        ImageShow.show(picture, 'with points')
        image.save('./images/intermediate/' + pic_name + '_getpicture_line.jpg')
    
    # perform rotation & composite to make bkg white
    # source: http://stackoverflow.com/questions/5252170/
    # specify-image-filling-color-when-rotating-in-python-with-pil-and-setting-expand
    picture = picture.convert('RGBA')
    picture = picture.rotate(max_key[0], expand=True)
    white = Image.new('RGBA', picture.size, (255,)*4)
    picture = Image.composite(picture, white, picture)
    width, height = picture.size
    
    ImageShow.show(picture, 'anti-skewed')
    picture.save('./images/intermediate/' + pic_name + '_antiskewed.jpg')
    
    return picture # picture
Esempio n. 7
0
                min_y = pty   
            draw.rectangle([ptx-BOXSIZE, pty-BOXSIZE, ptx+BOXSIZE, pty+BOXSIZE], fill=128)
        del draw
        ImageShow.show(picture, 'with points')
        image.save('./images/intermediate/' + pic_name + '_getpicture_line.jpg')
    
    # perform rotation & composite to make bkg white
    # source: http://stackoverflow.com/questions/5252170/
    # specify-image-filling-color-when-rotating-in-python-with-pil-and-setting-expand
    picture = picture.convert('RGBA')
    picture = picture.rotate(max_key[0], expand=True)
    white = Image.new('RGBA', picture.size, (255,)*4)
    picture = Image.composite(picture, white, picture)
    width, height = picture.size
    
    ImageShow.show(picture, 'anti-skewed')
    picture.save('./images/intermediate/' + pic_name + '_antiskewed.jpg')
    
    return picture # picture


# testing main
if __name__=='__main__':
    pic_name = 'blue_9_crop'
    test_pic = './images/' + pic_name + '.jpg'
    image = Image.open(test_pic)
    fixed = fix_skew(pic_name, image)
    ImageShow.show(fixed, 'skew removed')


def picture(pic_name, test_pic):
    image = Image.open(test_pic)
    
    # flip along vertical axis
    image = image.transpose(Image.FLIP_LEFT_RIGHT)
    
    # preprocess: trim to game screen
    image = image.convert('L')
    pixels = image.load();
    
    width, height = image.size
    
    center = (width/2, height/2)
    
    # center intensity should be in DS screen and therefore above some threshold
    cent_x = center[0]
    cent_y = center[1]
    screen_intensity = (pixels[center] + pixels[cent_x-1, cent_y-1] + pixels[cent_x-1, cent_y] + pixels[cent_x-1, cent_y+1] + pixels[cent_x, cent_y-1] + pixels[cent_x, cent_y+1] + pixels[cent_x+1, cent_y-1] + pixels[cent_x+1, cent_y] + pixels[cent_x+1, cent_y+1]) / 9.
    X_INC = width / 100
    Y_INC = height / 100
    THRES_DIFF = 40
    NEIGH_SIZE = 5
    
    # get max x of screen border
    prev_intensity = screen_intensity
    potential_border = width
    for x in range(center[0] + X_INC, width, X_INC):
        # get average of neighborhood
        average_intensity = 0
        num_pixels = 0
                
        for x_offset in range(-1 * NEIGH_SIZE, 1 * NEIGH_SIZE):
            neigh_x = x + x_offset
            # if within image, factor into average
            if neigh_x < 0 or neigh_x >= width:
                continue
            for y_offset in range(-1 * NEIGH_SIZE, 1 * NEIGH_SIZE):
                neigh_y = cent_y + y_offset
                # if within image, factor into average
                if neigh_y < 0 or neigh_y >= height:
                    continue
                            
                average_intensity += pixels[neigh_x, neigh_y]
                num_pixels += 1
                
        average_intensity = average_intensity / num_pixels
        
        if abs(average_intensity - prev_intensity) > THRES_DIFF:
            if potential_border < width:
                break
            potential_border = x
        else:
            potential_border = width
            prev_intensity = average_intensity
    max_x = potential_border
    print max_x
    
    # get min x of screen border
    prev_intensity = screen_intensity
    potential_border = 0
    for x in range(center[0] - X_INC, 0, -1 * X_INC):
        # get average of neighborhood
        average_intensity = 0
        num_pixels = 0
                
        for x_offset in range(-1 * NEIGH_SIZE, 1 * NEIGH_SIZE):
            neigh_x = x + x_offset
            # if within image, factor into average
            if neigh_x < 0 or neigh_x >= width:
                continue
            for y_offset in range(-1 * NEIGH_SIZE, 1 * NEIGH_SIZE):
                neigh_y = cent_y + y_offset
                # if within image, factor into average
                if neigh_y < 0 or neigh_y >= height:
                    continue
                            
                average_intensity += pixels[neigh_x, neigh_y]
                num_pixels += 1
                
        average_intensity = average_intensity / num_pixels
        
        if abs(average_intensity - prev_intensity) > THRES_DIFF:
            if potential_border > 0:
                break
            potential_border = x
        else:
            potential_border = 0
            prev_intensity = average_intensity
    min_x = potential_border
    print min_x
    
    # get max y of screen border
    prev_intensity = screen_intensity
    potential_border = height
    for y in range(center[1] + Y_INC, height, Y_INC):
        # get average of neighborhood
        average_intensity = 0
        num_pixels = 0
                
        for x_offset in range(-1 * NEIGH_SIZE, 1 * NEIGH_SIZE):
            neigh_x = cent_x + x_offset
            # if within image, factor into average
            if neigh_x < 0 or neigh_x >= width:
                continue
            for y_offset in range(-1 * NEIGH_SIZE, 1 * NEIGH_SIZE):
                neigh_y = y + y_offset
                # if within image, factor into average
                if neigh_y < 0 or neigh_y >= height:
                    continue
                            
                average_intensity += pixels[neigh_x, neigh_y]
                num_pixels += 1
                
        average_intensity = average_intensity / num_pixels
        
        if abs(average_intensity - prev_intensity) > THRES_DIFF:
            if potential_border < height:
                break
            potential_border = y
        else:
            potential_border = height
            prev_intensity = average_intensity
    max_y = potential_border
    print max_y
    
    # get min y of screen border
    prev_intensity = screen_intensity
    potential_border = 0
    for y in range(center[1] - Y_INC, 0, -1 * Y_INC):
        # get average of neighborhood
        average_intensity = 0
        num_pixels = 0
                
        for x_offset in range(-1 * NEIGH_SIZE, 1 * NEIGH_SIZE):
            neigh_x = cent_x + x_offset
            # if within image, factor into average
            if neigh_x < 0 or neigh_x >= width:
                continue
            for y_offset in range(-1 * NEIGH_SIZE, 1 * NEIGH_SIZE):
                neigh_y = y + y_offset
                # if within image, factor into average
                if neigh_y < 0 or neigh_y >= height:
                    continue
                            
                average_intensity += pixels[neigh_x, neigh_y]
                num_pixels += 1
                
        average_intensity = average_intensity / num_pixels
        
        if abs(average_intensity - prev_intensity) > THRES_DIFF:
            if potential_border > 0:
                break
            potential_border = y
        else:
            potential_border = 0
            prev_intensity = average_intensity
    min_y = potential_border
    print min_y
    
    """pixels = list(image.getdata())
    
    width, height = image.size
    (both, hor_filt, vert_filt) = prewitt.prewitt(pixels, width, height)
    
    prewitt_pixels = both.load()
    
    # edge detect on "both" with very high threshold for intensity
    horiz = {}
    vert = {}
    
    # traverse pixels in a direction
    # if intensity greater than threshold, vote for value and neighborhood
    THRES_BLACK = 70
    
    NEIGH_SIZE = 5
    for x in range(width):
        for y in range(height):
            if prewitt_pixels[x, y] < THRES_BLACK:
                # pixel only votes if direct neighborhood is dark
                # check if average intensity of direct neighborhood over threshold
                average_intensity = 0
                num_pixels = 0
                
                for x_offset in range (-1, 1):
                    neigh_x = x + x_offset
                    # if within image, factor into average
                    if neigh_x < 0 or neigh_x >= width:
                        continue
                    for y_offset in range (-1, 1):
                        neigh_y = y + y_offset
                        # if within image, factor into average
                        if neigh_y < 0 or neigh_y >= height:
                            continue
                            
                        average_intensity += prewitt_pixels[x + x_offset, y+y_offset]
                        num_pixels += 1
                
                average_intensity = average_intensity / num_pixels
                if average_intensity >= THRES_BLACK:
                    continue
                    
                # if neighborhood dark enough
                # pixel votes for everything in neighborhood
                
                # horizontal: x voting
                for x_offset in range (-1 * NEIGH_SIZE, NEIGH_SIZE):
                    neigh_x = x + x_offset
                    
                    # if within image, increment
                    if neigh_x < 0 or neigh_x >= width:
                        continue
                    if neigh_x not in horiz:
                        horiz[neigh_x] = 1
                    else:
                        horiz[neigh_x] += 1
                
                # vertical: y voting
                for y_offset in range (-1 * NEIGH_SIZE, NEIGH_SIZE):
                    neigh_y = y + y_offset
                    
                    # if within image, increment
                    if neigh_y < 0 or neigh_y >= height:
                        continue
                    if neigh_y not in vert:
                        vert[neigh_y] = 1
                    else:
                        vert[neigh_y] += 1
            
    # look in appropriate dictionaries for max/min x/y values
    horiz = sorted(horiz.iteritems(), key=lambda (k,v): (v,k))
    vert = sorted(vert.iteritems(), key=lambda (k,v): (v,k))
    
    x1 = horiz[len(horiz)-1][0]
    x2 = x1
    y1 = vert[len(vert)-1][0]
    y2 = y1
    
    FRACTION = .2
    MIN_DIST_X = FRACTION * width
    x_index = len(horiz)-1
    while abs(x2 - x1) < MIN_DIST_X:
        x2 = horiz[x_index][0]
        x_index -= 1
    
    MIN_DIST_Y = FRACTION * height
    y_index = len(vert)-1
    while abs(y2 - y1) < MIN_DIST_Y:
        y2 = vert[y_index][0]
        y_index -=1
    
    min_x = min(x1, x2)
    max_x = max(x1, x2)
    min_y = min(y1, y2)
    max_y = max(y1, y2)"""
    
    if DRAW:
        draw = ImageDraw.Draw(image)
        draw.line((min_x, 0, min_x, height), fill=128)
        draw.line((max_x, 0, max_x, height), fill=128)
        draw.line((0, min_y, width, min_y), fill=128)
        draw.line((0, max_y, width, max_y), fill=128)
        del draw
    ImageShow.show(image, 'with points')
    image.save('./images/intermediate/' + pic_name + '_getpicture_precrop.jpg')
    
    # crop image
    BUFFER = 5
    min_x = max(0, min_x - BUFFER)
    max_x = min(width - 1, max_x + BUFFER)
    min_y = max(0, min_y - BUFFER)
    max_y = min(height - 1, max_y + BUFFER)
    image = image.crop([min_x, min_y, max_x, max_y]);
    
    image.save('./images/intermediate/' + pic_name + '_getpicture_cropped.jpg')
    
    return image # picture
    
    if DRAW:
        draw = ImageDraw.Draw(image)
        draw.line((min_x, 0, min_x, height), fill=128)
        draw.line((max_x, 0, max_x, height), fill=128)
        draw.line((0, min_y, width, min_y), fill=128)
        draw.line((0, max_y, width, max_y), fill=128)
        del draw
    ImageShow.show(image, 'with points')
    image.save('./images/intermediate/' + pic_name + '_getpicture_precrop.jpg')
    
    # crop image
    BUFFER = 5
    min_x = max(0, min_x - BUFFER)
    max_x = min(width - 1, max_x + BUFFER)
    min_y = max(0, min_y - BUFFER)
    max_y = min(height - 1, max_y + BUFFER)
    image = image.crop([min_x, min_y, max_x, max_y]);
    
    image.save('./images/intermediate/' + pic_name + '_getpicture_cropped.jpg')
    
    return image # picture


if __name__=='__main__':
    result = picture('webcam', './images/webcam.jpg')
    ImageShow.show(result, "window title")



def detect_lines(picture, name):
    if picture.mode != 'L' : picture = picture.convert('L')
    pixels = list(picture.getdata())
    width, height = picture.size
    (both, hor_filt, vert_filt) = prewitt.prewitt(pixels, width, height)
    
    picture.save("./images/original.jpg")

    v = "vertical"
    h = "horizontal"
    (saved, xcoords) = detect_hv_lines(hor_filt,h)
    (savedy, ycoords) = detect_hv_lines(vert_filt,v)

    paint_lines(hor_filt,saved,h).save("./images/saveda.jpg")
    paint_lines(vert_filt,savedy,v).save("./images/savedv.jpg")


    # we'll trust the max coordinates as those are near the edge of the image
    # and are unlikely to be mistaken compared to the min coordinates
    max_x = max(xcoords)
    max_y = max(ycoords)
    min_x = min(xcoords)
    min_y = min(ycoords)

    projected_avg_x = (max_x-min_x)/global_board_size
    projected_avg_y = (max_y-min_y)/global_board_size

    avg_x = vote_avg_diff(xcoords)
    avg_y = vote_avg_diff(ycoords)
    #avg = (avg_x+avg_y)/2
    print "avg x diff: ", projected_avg_x
    print "avg y diff: ", projected_avg_y
    print "voted x df: ", avg_x
    print "voted y df: ", avg_y


    # get an evenly spaced set of lines
    xcoords = extrapolate_coords(max_x, projected_avg_x)
    ycoords = extrapolate_coords(max_y, projected_avg_y)
    #xcoords = extrapolate_coords(max_x, avg_x)
    #ycoords = extrapolate_coords(max_y, avg_y)


    paintedh = paint_lines(hor_filt,xcoords,h)
    paintedh.save("./images/painted_lines_hor_"+name+".jpg")

    paintedv = paint_lines(vert_filt, ycoords,v)
    paintedv.save("./images/painted_lines_vert_"+name+".jpg")

    combined = Image.blend(paintedv, paintedh, 0.5)
    grid_coords = []
    max_x = max(xcoords)
    min_x = min(xcoords)
    max_y = max(ycoords)
    min_y = min(ycoords)
    grid_coords.append((min_y,min_x))
    grid_coords.append((max_y,max_x))


    print "grid_coords:"
    print grid_coords

    if DRAW:
        draw = ImageDraw.Draw(combined)
        draw.rectangle(grid_coords,outline=128)
        del draw
        combined.save("./images/painted_lines_both_"+name+".jpg")
        ImageShow.show(combined,"blah")
    

    # return a Grid Representation of this solution
    cell_width = max(1, projected_avg_x)
    cell_height = max(1, projected_avg_y)
    gr = Representations.GridRep(grid_coords, ycoords, xcoords, cell_height, cell_width)
    return gr