Beispiel #1
0
def find_nearest_floss(block):
    # This way searches full blown sum of squared error for best color
    #error = [block.color_error(floss['rgb']) for floss in dmc_flosses.flosses]
    # This way does a jenky averaged color search
    average_point = [average(coord) for coord in zip(*block.points)]
    error = [sum_squared_error(average_point, Pixel.FromRGB(floss['rgb']).get_Lab()) for floss in dmc_flosses.flosses]
    best_error = min(error)
    idx = error.index(best_error)
    return dmc_flosses.flosses[idx]
Beispiel #2
0
def find_nearest_floss(region_point):
    error = [
        sum_squared_error(region_point,
                          Pixel.FromRGB(floss['rgb']).get_Lab())
        for floss in dmc_flosses.flosses
    ]
    best_error = min(error)
    idx = error.index(best_error)
    return dmc_flosses.flosses[idx]
Beispiel #3
0
def floss_image(image, color_map):
    x, y = image.size
    pixel_data = image.load()
    flossed_image = Image.new('RGB', (x, y), None)
    flossed_pixels = flossed_image.load()
    for r in range(x):
        for c in range(y):
            value = Pixel.FromRGB(pixel_data[r,c]).get_Lab()
            possible_flosses = [floss for block, floss in color_map.iteritems() if value in block]
            # FIXME: I may be doing something weird because I seem to have pixels that can fall into multiple blocks
            #assert len(possible_flosses) == 1
            flossed_pixels[r,c] = possible_flosses[0]['rgb']
    
    # save debug image
    flossed_image.save(os.path.join(options.output_dir, 'floss.bmp'), 'BMP')
    return flossed_image
Beispiel #4
0
def flossit(resized_image, median_cut_options):
    global options
    options = median_cut_options
    assert options.num_colors > 0

    if not options.strategy:
        options.strategy = 'random'
    elif options.strategy not in seed_strategies.keys():
        print '[Lloyd\'s] Unknown seeding strategy "%s" -- falling back to random seeds!' % options.strategy
        options.strategy = 'random'

    print '[Lloyd\'s] Enumerating the pixel data in the resized image...'
    all_points = [
        Pixel.FromRGB(rgb).get_Lab() for rgb in get_image_points(resized_image)
    ]
    print '[Lloyd\'s] Setting initial seed regions...'
    regions = seed_strategies[options.strategy](all_points, options.num_colors)
    region_kd_tree = kdtree(regions)
    print '[Lloyd\'s] Finding initial point assignments...'
    assignments = [
        closest_region(point, regions, region_kd_tree) for point in all_points
    ]
    iteration = 1
    last_assignments = []
    while last_assignments != assignments:
        print '[Lloyd\'s] Iterating regions (%s)...' % iteration

        populated_regions = [k for k, g in groupby(sorted(assignments))]
        regions = [
            central_point(
                compress(all_points,
                         [assignment == region for assignment in assignments]))
            for region in populated_regions
        ]
        region_kd_tree = kdtree(regions)

        iteration += 1
        last_assignments = assignments
        assignments = [
            closest_region(point, regions, region_kd_tree)
            for point in all_points
        ]

    print '[Lloyd\'s] Assigning floss colors to regions...'
    colors = [find_nearest_floss(region) for region in regions]
    print '[Lloyd\'s] Flossing image...'
    return floss_image(resized_image, regions, colors)
Beispiel #5
0
def flossit(resized_image, median_cut_options):
    global options
    options = median_cut_options
    assert options.num_colors > 0

    if not options.strategy:
        options.strategy = 'size'
    elif options.strategy not in division_strategies.keys():
        print '[Median Cut] Unknown division strategy "%s" -- falling back to size-based cuts!' % options.strategy
        options.strategy = 'size'

    print '[Median Cut] Enumerating the pixel data in the resized image...'
    all_points = [Pixel.FromRGB(rgb).get_Lab() for rgb in get_image_points(resized_image)]
    print '[Median Cut] Breaking image into %s discrete color groups...' % options.num_colors
    color_blocks = subdivide(all_points)
    print '[Median Cut] Finding best matching floss colors for each region...'
    color_map = map_blocks_to_floss(color_blocks)
    print '[Median Cut] Rendering image using appropriate floss colors...'
    return floss_image(resized_image, color_map)
Beispiel #6
0
def floss_image(image, region_points, region_colors):
    x, y = image.size
    pixel_data = image.load()
    flossed_image = Image.new('RGB', (x, y), None)
    flossed_pixels = flossed_image.load()
    for r in range(x):
        for c in range(y):
            pixel = Pixel.FromRGB(pixel_data[r, c]).get_Lab()
            error = [
                sum_squared_error(pixel, region_point)
                for region_point in region_points
            ]
            best_error = min(error)
            idx = error.index(best_error)
            flossed_pixels[r, c] = region_colors[idx]['rgb']

    # save debug image
    flossed_image.save(os.path.join(options.output_dir, 'floss.bmp'), 'BMP')
    return flossed_image