Operating system: MacOS Sequioa 15.3.1 (24D70)
Slicer version: 5.8.0
Expected behavior: Image (NIfTI) and segmentation affine matrices to match after exporting segmentation to binary labelmap and saving to file (as NIfTI)
Actual behavior: If I use nibabel (nib.load) and check the image and segmentation file data (get_fdata), there is a warning that affines are ill-posed on some but not all segmentation files.
This leads to these particular images’ performance metrics being incorrectly calculated (for example, Dice score become <0.01 but when viewing the the ground truth segmentation and new segementation in Slicer, they overlap near perfectly). Code for Dice is:
import warnings
import numpy as np
import nibabel as nib
def compute_confusion_matrix(gt_class, seg_class):
if gt_class.shape != seg_class.shape:
raise ValueError("Ground truth and segmentation masks must have the same shape.")
# Optimise memory by storing binary label values as integers
gt_class = gt_class.astype(np.uint8)
seg_class = seg_class.astype(np.uint8)
tp = np.sum(gt_class * seg_class, dtype=np.float32)
fp = np.sum((1 - gt_class) * seg_class, dtype=np.float32)
tn = np.sum((1 - gt_class) * (1 - seg_class), dtype=np.float32)
fn = np.sum(gt_class * (1 - seg_class), dtype=np.float32)
# Replace zero values with a tiny number to avoid errors
tiny_number = 1e-10
tp = tp if tp != 0 else tiny_number
fp = fp if fp != 0 else tiny_number
tn = tn if tn != 0 else tiny_number
fn = fn if fn != 0 else tiny_number
return {"tp": tp, "fp": fp, "tn": tn, "fn": fn}
def dsc(conf_matrix):
numerator = 2 * conf_matrix["tp"]
denominator = 2 * conf_matrix["tp"] + conf_matrix["fp"] + conf_matrix["fn"]
if denominator == 0:
warnings.warn("Both gt and s are empty - set to 1 as correct solution even if not defined")
return 1
return numerator / denominator```
**Attempted solutions:**
1. Loaded image (as volume) and segmentation (as segmentation) --> Segment Editor --> Chose image as 'Source Volume' --> Click Specify Geometry --> Select image as 'Source Geometry'.
2. Python (3.9), forcing assignment seg.affine = img.affine, set sform code=4, set qform code=4