def main(data_file, outdir, image_prefix, cell_images, label):
    images_by_class = dict()
    image_name = image_prefix + "_y{:02d}_x{:02d}.bmp"
    # read csv file
    r = csv.DictReader(data_file)
    for row in r:
        # Create lists of images from each class
        cell_image_name = image_name.format(int(row["j"]), int(row["i"]))
        if row[label] in images_by_class:
            images_by_class[row[label]].append(cell_image_name)
        else:
            images_by_class[row[label]] = [ cell_image_name ]

    for key in images_by_class:
        #print key, images_by_class[key], "\n"
        dilution = 1.0/float(len(images_by_class[key]))
        print key, "at a dilution of:", dilution
        # Create an image for each list of images
        size = Image.open(images_by_class[key][0]).size
        mean_image = Image.new("L", size, "white")
        template = None
        #print image_by_class[key]
        for image_name in images_by_class[key]:
            with open(image_name, "rb") as f:
                cell = Image.open(f)
                if template:
                    image = align_images.align_to(template, cell)
                else:
                    template = cell
                mean_image = Image.blend(mean_image, cell, dilution)
                del cell
        mean_image.save(os.path.join(outdir,key+".bmp") if outdir else key+".bmp")
def compare_images(A, B, scale=.4, align=True):
    if align:
        Bmatch = align_images.align_to(A, B).convert('L')
    else:
        Bmatch = B.convert('L')
    A = A.convert('L')
    new_shape = (np.array(A.size) * scale).astype(int)
    A = A.resize(new_shape, Image.ANTIALIAS)
    Bmatch = Bmatch.resize(new_shape, Image.ANTIALIAS)
    Bmatch = Bmatch.filter(ImageFilter.BLUR)
    A = A.filter(ImageFilter.BLUR)
    dataA = np.array(A.getdata())
    dataB = np.array(Bmatch.getdata())
    diff = abs(dataA - dataB)
    return float(diff.sum()) / np.prod(new_shape)
    # collect all cells by class name
    img_by_class = dict()
    for j in range(rows):
        for i in range(cols):
            name = classes[j][i]
            cell = grid.crop(bounding_box(i * width, j * height, width, height))
            if name in img_by_class:
                img_by_class[name].append(cell)
            else:
                img_by_class[name] = [cell]

    # align all the images to the first
    if not args.noalign:
        for name, imgs in img_by_class.items():
            for i in range(1, len(imgs)):
                imgs[i] = align_images.align_to(imgs[0], imgs[i])

    # blend all the images
    for name, imgs in img_by_class.items():
        img_by_class[name]  = dict(
            template=imgs[0],
            image=blend_images(imgs),
            n=len(imgs))

    # update the meta_data and global means
    for name, newdata in img_by_class.items():
        if name in meta_data:
            data = meta_data[name]
            data['n'] += newdata['n']
            cell = newdata['image']
            if not args.noalign: