def compute_metrics(outputs, targets, metrics, ids=None):
    """
    Computes the evaluation metrics for the given list of output and target images.

    :param outputs: list of output images
    :param targets: list of gold standard images
    :param metrics: dictionary containing each metric as {metric_name: metric_function}, the metric function must have
        two arguments as ``metric_function(output, target)``.
    :param ids: (Optional) list of image identifiers
    :return: list of dictionaries containing the metrics for each given sample

    :Example:

    >>> outs = [np.asarray([[0, 1, 0, 1]]), np.asarray([[0, 0, 1, 1]])]
    >>> tgts = [np.asarray([[0, 0, 1, 1]]), np.asarray([[0, 0, 1, 1]])]
    >>> compute_metrics(outs, tgts, metrics={'dsc': niclib.metrics.dsc, 'acc': niclib.metrics.accuracy})
    [{'id': '0', 'dsc': 0.5, 'acc': 0.5},
     {'id': '1', 'dsc': 1.0, 'acc': 1.0}]
    """
    assert len(outputs) == len(targets), 'len(outputs):{} != len(targets):{}'.format(len(outputs), len(targets))
    assert isinstance(metrics, dict), 'Provide metrics as a dictionary containing {metric_name: metric_function}'

    all_metrics = []
    for n, (output, target) in enumerate(zip(outputs, targets)):
        case_metrics = {'id': str(n) if ids is None else ids[n]}
        for metric_name, metric_func in metrics.items():
            case_metrics.update({metric_name: metric_func(output, target)})
        all_metrics.append(case_metrics)
    return all_metrics