Exemplo n.º 1
0
def get_metric_val(label_tensor, predict_tensor, thres=0.5):
    '''
    label_tensor: batchsize x 1 x 512 x 512
    predict_tensor: batchsize x 1 x 512 x 512
    '''
    label_array = np.squeeze(label_tensor.data.cpu().numpy(), 1).astype(np.int)
    predict_array = np.squeeze(predict_tensor.data.cpu().numpy(), 1)
    predict_array = (predict_array > thres).astype(np.int)

    random_error_error = 0.0
    random_error_precision = 0.0
    random_error_recall = 0.0

    false_split = 0.0
    false_merge = 0.0

    for i in range(label_array.shape[0]):
        error, precision, recall = adapted_rand_error(label_array[i],
                                                      predict_array[i])
        splits, merges = variation_of_information(label_array[i],
                                                  predict_array[i])
        random_error_error += error
        random_error_precision += precision
        random_error_recall += recall
        false_split += splits
        false_merge += merges

    return random_error_error, random_error_precision, random_error_recall, false_split, false_merge
Exemplo n.º 2
0
def get_vi(pred: np.ndarray,
           mask: np.ndarray,
           bg_value: int = 0,
           method: int = 1) -> Tuple:
    """
    Referenced by:
    Marina Meilă (2007), Comparing clusterings—an information based distance,
    Journal of Multivariate Analysis, Volume 98, Issue 5, Pages 873-895, ISSN 0047-259X, DOI:10.1016/j.jmva.2006.11.013.
    :param method: 0: skimage implementation and 1: gala implementation (https://github.com/janelia-flyem/gala.)
    :return Tuple = (VI, merger_error, split_error)
    """
    vi, merger_error, split_error = 0.0, 0.0, 0.0

    label_pred, num_pred = label(pred,
                                 connectivity=1,
                                 background=bg_value,
                                 return_num=True)
    label_mask, num_mask = label(mask,
                                 connectivity=1,
                                 background=bg_value,
                                 return_num=True)
    if method == 0:
        # scikit-image
        split_error, merger_error = metrics.variation_of_information(
            label_mask, label_pred)
    elif method == 1:
        # gala
        merger_error, split_error = ev.split_vi(label_pred, label_mask)
    vi = merger_error + split_error
    if math.isnan(vi):
        return 10, 5, 5
    return merger_error, split_error, vi
Exemplo n.º 3
0
    def forward(self, x):
        input1 = x["reference"].cpu().numpy().astype(np.uint8)
        input2 = x["other"].cpu().numpy().astype(np.uint8)

        sizeIn = input1.shape

        distance = np.empty((sizeIn[0], sizeIn[1]))
        for i in range(sizeIn[0]):
            for j in range(sizeIn[1]):
                in1 = np.transpose(input1[i, j], [1, 2, 0])
                in2 = np.transpose(input2[i, j], [1, 2, 0])
                if self.mode == "L2":
                    distance[i, j] = metrics.mean_squared_error(
                        in1, in2) / (255.0 * 255.0)
                elif self.mode == "SSIM":
                    distance[i, j] = 1 - metrics.structural_similarity(
                        in1, in2,
                        multichannel=True)  #invert as distance measure
                elif self.mode == "PSNR":
                    distance[i, j] = -metrics.peak_signal_noise_ratio(
                        in1, in2)  #invert as distance measure
                elif self.mode == "MI":
                    distance[i, j] = np.mean(
                        metrics.variation_of_information(in1, in2))
        return torch.from_numpy(distance)
Exemplo n.º 4
0
 def __call__(self, input_seg, gt_seg):
     splits, merges = variation_of_information(gt_seg, input_seg)
     self.splits_scores.append(splits)
     self.merges_scores.append(merges)
     are, arp, arr = adapted_rand_error(gt_seg, input_seg)
     self.are_score.append(are)
     self.arp_score.append(arp)
     self.arr_score.append(arr)
Exemplo n.º 5
0
def eval_metric_array(pred, label):
    im_true = ndi.label(ndi.binary_fill_holes(label))[0]
    im_pred = ndi.label(ndi.binary_fill_holes(pred))[0]

    error, precision, recall = adapted_rand_error(im_true, im_pred)
    splits, merges = variation_of_information(im_true, im_pred)

    return error, precision, recall, splits, merges
Exemplo n.º 6
0
def test_vi_ignore_labels():
    im1 = np.array([[1, 0], [2, 3]], dtype='uint8')
    im2 = np.array([[1, 1], [1, 0]], dtype='uint8')

    false_splits, false_merges = variation_of_information(im1,
                                                          im2,
                                                          ignore_labels=[0])
    assert (false_splits, false_merges) == (0, 2 / 3)
Exemplo n.º 7
0
 def compare(self, f_quote: str):
     images = [self.image_base.copy(), cv2.imread(f_quote)]
     shape_min = (min([i.shape[1]
                       for i in images]), min([i.shape[0] for i in images]))
     logging.debug('Comparing size: %s', shape_min)
     for i in range(len(images)):
         images[i] = Image.fromarray(images[i]).resize(
             shape_min, Image.ANTIALIAS)
         images[i] = numpy.array(images[i])
     return numpy.mean(variation_of_information(images[0], images[1]))
def validate(res_path, exp_path):
    seg_key = 'connected_components'
    with z5py.File(res_path, 'r') as f:
        ds = f[seg_key]
        res = ds[:]
    with z5py.File(exp_path, 'r') as f:
        ds = f[seg_key]
        exp = ds[:]
    assert res.shape == exp.shape
    vi0, vi1 = variation_of_information(exp, res)
    print("variation of information (should be close to zero):", vi0 + vi1)
Exemplo n.º 9
0
def eval_metric(pred_path, label_path):
    pred = Image.open(pred_path)
    label = Image.open(label_path)
    label = np.array(label)
    pred = np.array(pred)[:, :, 0]
    label[label == 255] = 1
    pred[pred == 255] = 1

    im_true = ndi.label(ndi.binary_fill_holes(label))[0]
    im_pred = ndi.label(ndi.binary_fill_holes(pred))[0]

    error, precision, recall = adapted_rand_error(im_true, im_pred)
    splits, merges = variation_of_information(im_true, im_pred)

    return (error, precision, recall), (splits, merges)
Exemplo n.º 10
0
 def compute_similarity(self, im, im_deg, sim_method='mutual_info'):
     im = np.array(im)
     im_deg = np.array(im_deg)
     if sim_method == 'mutual_info':
         return mutual_information(im, im_deg)
     elif sim_method == 'dice':
         return f1_score(
             im.astype(bool).ravel(),
             im_deg.astype(bool).ravel())
     elif sim_method == 'ssim':
         return ssim(im.astype(bool), im_deg.astype(bool))
     elif sim_method == 'var_info':
         under_seg, over_seg = variation_of_information(
             im.astype(bool), im_deg.astype(bool))
         return 1 - (under_seg + over_seg)
     elif sim_method == 'mse':
         return 1 - mean_squared_error(
             im.astype(bool).ravel(),
             im_deg.astype(bool).ravel())
                                                 threshold=0.69)
im_test3 = label(im_test3)

method_names = [
    'Compact watershed', 'Canny filter',
    'Morphological Geodesic Active Contours'
]
short_method_names = ['Compact WS', 'Canny', 'GAC']

precision_list = []
recall_list = []
split_list = []
merge_list = []
for name, im_test in zip(method_names, [im_test1, im_test2, im_test3]):
    error, precision, recall = adapted_rand_error(im_true, im_test)
    splits, merges = variation_of_information(im_true, im_test)
    split_list.append(splits)
    merge_list.append(merges)
    precision_list.append(precision)
    recall_list.append(recall)
    print(f"\n## Method: {name}")
    print(f"Adapted Rand error: {error}")
    print(f"Adapted Rand precision: {precision}")
    print(f"Adapted Rand recall: {recall}")
    print(f"False Splits: {splits}")
    print(f"False Merges: {merges}")

fig, axes = plt.subplots(2, 3, figsize=(9, 6), constrained_layout=True)
ax = axes.ravel()

ax[0].scatter(merge_list, split_list)
Exemplo n.º 12
0
def test_vi():
    im_true = np.array([1, 2, 3, 4])
    im_test = np.array([1, 1, 8, 8])
    assert_equal(np.sum(variation_of_information(im_true, im_test)), 1)
Exemplo n.º 13
0
def segment_from_directory(
        directory, 
        suffix,
        affinities_channels, 
        centroids_channel, 
        thresholding_channel, 
        scale = (4, 1, 1),
        w_scale=None, 
        compactness=0.,
        display=True, 
        validation=False, 
        **kwargs
        #
    ):
    images, _, output, GT = get_dataset(directory, 
                                        GT=True, 
                                        validation=validation)
    images = da.squeeze(images)
    print(output.shape)
    segmentations = []
    masks = []
    scores = {'GT | Output' : [], 'Output | GT' : []}
    for i in range(output.shape[0]):
        gt = GT[i].compute()
        seg, _, mask = segment_output_image(
                output[i], 
                affinities_channels, 
                centroids_channel, 
                thresholding_channel, 
                scale=w_scale, 
                compactness=0.)
        vi = variation_of_information(gt, seg)
        scores['GT | Output'].append(vi[0])
        scores['Output | GT'].append(vi[1])
        seg = da.from_array(seg)
        segmentations.append(seg)
        masks.append(mask)
    segmentations = da.stack(segmentations)
    masks = da.stack(masks)
    # Save the VI data
    scores = pd.DataFrame(scores)
    if validation:
        s = 'validation_VI.csv'
    else:
        s = '_VI.csv'
    s_path = os.path.join(directory, suffix + s)
    scores.to_csv(s_path)
    gt_o = scores['GT | Output'].mean()
    o_gt = scores['Output | GT'].mean()
    print(f'Conditional entropy H(GT|Output): {gt_o}')
    print(f'Conditional entropy H(Output|GT): {o_gt}')
    if display:
        # Now Display
        z_affs = output[:, affinities_channels[0], ...]
        y_affs = output[:, affinities_channels[1], ...]
        x_affs = output[:, affinities_channels[2], ...]
        c = output[:, thresholding_channel, ...]
        cl = output[:, centroids_channel, ...]
        v_scale = [1] * len(images.shape)
        v_scale[-3:] = scale
        print(images.shape, v_scale, z_affs.shape, masks.shape)
        v = napari.Viewer()
        v.add_image(images, name='Input images', blending='additive', visible=True, scale=v_scale)
        v.add_image(c, name='Thresholding channel', blending='additive', visible=False, scale=v_scale)
        v.add_image(cl, name='Centroids channel', blending='additive', visible=False, scale=v_scale)
        v.add_image(z_affs, name='z affinities', blending='additive', visible=False, scale=v_scale, 
                    colormap='bop purple')
        v.add_image(y_affs, name='y affinities', blending='additive', visible=False, scale=v_scale, 
                    colormap='bop orange')
        v.add_image(x_affs, name='x affinities', blending='additive', visible=False, scale=v_scale, 
                    colormap='bop blue')
        v.add_labels(masks, name='Masks', blending='additive', visible=False, scale=v_scale)
        v.add_labels(GT, name='Ground truth', blending='additive', visible=False, scale=v_scale)
        v.add_labels(segmentations, name='Segmentations', blending='additive', visible=True, 
                     scale=v_scale)
        napari.run()