(model, path, dataset, opt, save_base=None)
| 54 | return sensitivity, specificity, precision, hd_val |
| 55 | |
| 56 | def test(model, path, dataset, opt, save_base=None): |
| 57 | data_path = os.path.join(path, dataset) |
| 58 | image_root = f'{data_path}/images/' |
| 59 | gt_root = f'{data_path}/masks/' |
| 60 | model.eval() |
| 61 | |
| 62 | test_loader = get_loader( |
| 63 | image_root=image_root, gt_root=gt_root, |
| 64 | batchsize=opt.test_batchsize, trainsize=opt.img_size, |
| 65 | shuffle=False, split='test', color_image=opt.color_image |
| 66 | ) |
| 67 | |
| 68 | DSC, IOU, total_images = 0.0, 0.0, 0 |
| 69 | detailed_results = [] |
| 70 | |
| 71 | with torch.no_grad(): |
| 72 | for pack in tqdm(test_loader, desc=f"Inference on {dataset}"): |
| 73 | images, gts, original_shapes, names = pack |
| 74 | images, gts = images.cuda(), gts.cuda().float() |
| 75 | |
| 76 | ress = model(images) |
| 77 | if not isinstance(ress, list): |
| 78 | ress = [ress] |
| 79 | # Take the primary output (EMCADNet usually uses the last item for final prediction) |
| 80 | predictions = ress[-1] |
| 81 | |
| 82 | for i in range(len(images)): |
| 83 | h_orig, w_orig = int(original_shapes[0][i]), int(original_shapes[1][i]) |
| 84 | |
| 85 | p = predictions[i].unsqueeze(0) |
| 86 | pred_resized = F.interpolate(p, size=(h_orig, w_orig), mode='bilinear', align_corners=False).sigmoid().squeeze() |
| 87 | pred_resized = (pred_resized - pred_resized.min()) / (pred_resized.max() - pred_resized.min() + 1e-8) |
| 88 | |
| 89 | g = gts[i].unsqueeze(0) |
| 90 | gt_resized = F.interpolate(g, size=(h_orig, w_orig), mode='nearest').squeeze() |
| 91 | |
| 92 | input_binary = (pred_resized >= 0.5).float() |
| 93 | target_binary = (gt_resized >= 0.2).float() |
| 94 | |
| 95 | d = dice_coefficient(input_binary, target_binary).item() |
| 96 | io = iou(input_binary, target_binary).item() |
| 97 | sens, spec, prec, hd = get_binary_metrics(input_binary, target_binary) |
| 98 | |
| 99 | DSC += d |
| 100 | IOU += io |
| 101 | total_images += 1 |
| 102 | |
| 103 | detailed_results.append({ |
| 104 | 'Name': names[i], 'Dice': d, 'IoU': io, |
| 105 | 'Sensitivity': float('{:.4f}'.format(sens)), |
| 106 | 'Specificity': float('{:.4f}'.format(spec)), |
| 107 | 'Precision': float('{:.4f}'.format(prec)), |
| 108 | 'HD95': float('{:.4f}'.format(hd)) |
| 109 | }) |
| 110 | |
| 111 | if save_base: |
| 112 | pred_img = (input_binary.cpu().numpy() * 255).astype(np.uint8) |
| 113 | cv2.imwrite(os.path.join(save_base, names[i]), pred_img) |
no test coverage detected