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
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)
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
def factor_f(image, ground_truth): if image.shape != ground_truth.shape: ground_truth = cv2.cvtColor(ground_truth, cv2.COLOR_BGR2GRAY) assert image.shape == ground_truth.shape relab_gt, fw_gt, inv_gt = relabel_sequential(ground_truth) relab, fw, inv = relabel_sequential(image) error, precision, recall = adapted_rand_error(relab_gt, relab) factor_f = 2 * (precision * recall) / (precision + recall) return factor_f
def test_embeddings_predictor(self, tmpdir): config = {'model': {'output_heads': 1}, 'device': torch.device('cpu')} slice_builder_config = { 'name': 'SliceBuilder', 'patch_shape': (64, 200, 200), 'stride_shape': (40, 150, 150) } transformer_config = { 'raw': [{ 'name': 'ToTensor', 'expand_dims': False, 'dtype': 'long' }] } gt_file = 'resources/sample_ovule.h5' output_file = os.path.join(tmpdir, 'output_segmentation.h5') dataset = StandardHDF5Dataset( gt_file, phase='test', slice_builder_config=slice_builder_config, transformer_config=transformer_config, mirror_padding=None, raw_internal_path='label') loader = DataLoader(dataset, batch_size=1, num_workers=1, shuffle=False, collate_fn=prediction_collate) predictor = FakePredictor(FakeModel(), loader, output_file, config, clustering='meanshift', bandwidth=0.5) predictor.predict() with h5py.File(gt_file, 'r') as f: with h5py.File(output_file, 'r') as g: gt = f['label'][...] segm = g['segmentation/meanshift'][...] arand_error = adapted_rand_error(gt, segm)[0] assert arand_error < 0.1
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)
def calculate_adapted_rand_error_slic(ground_truth: Dict, algo_output: Dict) -> Dict: """ Compute Adapted Rand error as defined by the SNEMI3D contest :param ground_truth: Dict with names and gt :param algo_output: Dict with Adaptive Segmentation results :return: are scores """ are_scores = {} for img_name, gt in ground_truth.items(): try: scores = metrics.adapted_rand_error(ground_truth[img_name][0], algo_output[img_name]) are_scores.update({img_name: scores}) except: continue return are_scores
def calculate(self, output, target): """Calculates metrics for given batch """ lbl = target.detach().cpu().numpy() pred = output.detach() pred = torch.sigmoid(pred) mse = self.mse_fn(pred, target) pred = pred.cpu().round().numpy() if self.full_metrics: error, precision, recall = adapted_rand_error( lbl.astype('int'), pred.astype('int')) self.metrics['error'] = self.batch_average(error, 'error') self.metrics['precision'] = self.batch_average( precision, 'precision') self.metrics['recall'] = self.batch_average(recall, 'recall') self.metrics['PSNR'] = self.batch_average( 10 * math.log10(1 / mse.item()), 'PSNR') self.metrics['IoU'] = self.batch_average(iou(pred, lbl), 'IoU') self.metrics["Dice"] = self.batch_average(dice(pred, lbl), 'IoU') return self.metrics
def _arand_err(gt, seg): n_seg = len(np.unique(seg)) if n_seg == 1: return 0. return adapted_rand_error(gt, seg)[0]
balloon=-1, 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()
def test_are(): im_true = np.array([[2, 1], [1, 2]]) im_test = np.array([[1, 2], [3, 1]]) assert_almost_equal(adapted_rand_error(im_true, im_test), (0.3333333, 0.5, 1.0))
def rand_error_3(prediction, target): return adapted_rand_error(prediction, target)