def main(image, image_name, rows, columns, filter_list, csv_output,
        yaml_out=None, save_cell_images=False, filter_image_name=None):
    cell_w, cell_h = dims.celldims(image.size, rows, columns)
    filter_name = "-".join(map(base_name_no_ext, args.filters))
    filtered_image = apply_filters(image, filter_list)
    if filter_image_name:
        filtered_image.save(filter_image_name)
    stats_data = []
    vector_data = []
    stat_functions = dict(mean=chi_mean, stddev=np.std, peaks=count_max_peaks)
    for i in range(rows):
        stats_data.append(list())
        vector_data.append(list())
        for j in range(columns):
            stats_data[i].append(dict())
            bb = bounding_box(j * cell_w, i * cell_h, cell_w, cell_h)
            cell = filtered_image.crop(bb)
            if save_cell_images:
                cell_name = "{:s}-{:s}_y{:02d}_x{:02d}.bmp".format(image_name, filter_name, i, j)
                cell.save(cell_name)
            vectors = get_vectors(cell)
            for key in vectors:
                # union of two dict to add new keys
                stats_data[i][j].update(dict_map(vectors[key], stat_functions, key + "_"))

            vector_data[i].append(vectors)

            if yaml_out:   #  yaml lib doesn't like numpy data types.
                vectors['x'] = list(map(float, vectors['x']))
                vectors['y'] = list(map(float, vectors['x']))

    if yaml_out:
        yaml_out.write(yaml_dump(vector_data))

    stat_names = stats_data[0][0].keys()
    header_names = [filter_name + "-" + stat_name for stat_name in stat_names]
    stats_writer = csv.writer(csv_output)
    stats_writer.writerow(['i', 'j', 'x', 'y'] + header_names)
    for i in range(rows):
        for j in range(columns):
            row = [i, j, float(j) / columns, float(i) / rows]
            for k in stat_names:
                row.append(stats_data[i][j][k])
            stats_writer.writerow(row)
if __name__ == "__main__":
    args = parse_args()

    if args.gold:
        meta_data = yaml.load(open(args.gold))
        for name, data in meta_data.items():
            meta_data[name]['image'] = Image.open(data['path'])
            meta_data[name]['template'] = Image.open(data['template_path'])
    else:
        meta_data = dict()

    grid = Image.open(args.map)
    classes = [r for r in csv.reader(open(args.intended))]
    rows = len(classes)
    cols = len(classes[0])
    width, height = dims.celldims(grid.size, rows, cols)

    # 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():
    parser.add_argument('-split', type=int)
    return parser.parse_args()


def gold_classify(gold_images, cell_image, align=True):
    return [(compare_images(gold, cell_image, align=False), className) for className, gold in gold_images.items()]


def bounding_box(x, y, w, h, inset=7):
    return (x + inset, y + inset, x + w - 2 * inset, y + h - 2 * inset)


if __name__ == "__main__":
    args = parse_args()
    grid = Image.open(args.image)
    cell_w, cell_h = dims.celldims(grid.size, args.rows, args.cols)
    answer = []

    gold = yaml.load(open(args.gold))
    for name, mean_img in gold.items():
        if 'path' in mean_img:
            gold[name] = Image.open(mean_img['path'])
        else:
            gold[name] = Image.open(mean_img)
        if args.split:
            gold[name] = as_black_and_white(gold[name], args.split, contrast=True)

    class_errs = [[gold_classify(gold,
                grid.crop(bounding_box(
                    j * cell_w, i * cell_h, cell_w, cell_h)))
                    for j in range(args.cols)] for i in range(args.rows)]