1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
|
#!/usr/bin/env python3
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-
# vi: set ft=python sts=4 ts=4 sw=4 et:
""" Script example of tissue classification
"""
from argparse import ArgumentParser
import numpy as np
from nipy import load_image, save_image
from nipy.algorithms.segmentation import BrainT1Segmentation
from nipy.core.image.image_spaces import make_xyz_image, xyz_affine
def fuzzy_dice(gold_ppm, ppm, mask):
"""
Fuzzy dice index.
"""
dices = np.zeros(3)
if gold_ppm is None:
return dices
for k in range(3):
pk = gold_ppm[mask][:, k]
qk = ppm[mask][:, k]
PQ = np.sum(np.sqrt(np.maximum(pk * qk, 0)))
P = np.sum(pk)
Q = np.sum(qk)
dices[k] = 2 * PQ / float(P + Q)
return dices
# Parse command line
description = 'Perform brain tissue classification from skull stripped T1 \
image in CSF, GM and WM. If no mask image is provided, the mask is defined by \
thresholding the input image above zero (strictly).'
parser = ArgumentParser(description=description)
parser.add_argument('img', metavar='img', nargs='+', help='input image')
parser.add_argument('--mask', dest='mask', help='mask image')
parser.add_argument('--niters', dest='niters',
help='number of iterations (default=%d)' % 25)
parser.add_argument('--beta', dest='beta',
help=f'Markov random field beta parameter (default={0.5:f})')
parser.add_argument('--ngb_size', dest='ngb_size',
help='Markov random field neighborhood system (default=%d)' % 6)
parser.add_argument('--probc', dest='probc', help='csf probability map')
parser.add_argument('--probg', dest='probg',
help='gray matter probability map')
parser.add_argument('--probw', dest='probw',
help='white matter probability map')
args = parser.parse_args()
def get_argument(dest, default):
val = args.__getattribute__(dest)
if val is None:
return default
else:
return val
# Input image
img = load_image(args.img[0])
# Input mask image
mask_img = get_argument('mask', None)
if mask_img is None:
mask_img = img
else:
mask_img = load_image(mask_img)
# Other optional arguments
niters = int(get_argument('niters', 25))
beta = float(get_argument('beta', 0.5))
ngb_size = int(get_argument('ngb_size', 6))
# Perform tissue classification
mask = mask_img.get_fdata() > 0
S = BrainT1Segmentation(img.get_fdata(), mask=mask, model='5k',
niters=niters, beta=beta, ngb_size=ngb_size)
# Save label image
outfile = 'hard_classif.nii'
save_image(make_xyz_image(S.label, xyz_affine(img), 'scanner'),
outfile)
print(f'Label image saved in: {outfile}')
# Compute fuzzy Dice indices if a 3-class fuzzy model is provided
if args.probc is not None and \
args.probg is not None and \
args.probw is not None:
print('Computing Dice index')
gold_ppm = np.zeros(S.ppm.shape)
gold_ppm_img = (args.probc, args.probg, args.probw)
for k in range(3):
img = load_image(gold_ppm_img[k])
gold_ppm[..., k] = img.get_fdata()
d = fuzzy_dice(gold_ppm, S.ppm, np.where(mask_img.get_fdata() > 0))
print(f'Fuzzy Dice indices: {d}')
|