def main(): args = parse_args() mask = dwi.mask.read_mask(args.input) selected_slices = list(mask.selected_slices()) mbb = mask.bounding_box() mbb_shape = tuple([b - a for a, b in mbb]) d = dict(infile=args.input, shape=mask.shape(), size=np.prod(mask.shape()), nsel=mask.n_selected(), mbb=mbb, mbb_shape=mbb_shape, mbb_size=np.prod(mbb_shape), mbb_all=mask.mbb_equals_selection(), nsl=len(selected_slices), sl=selected_slices, msl=mask.max_slices()) s = ( 'mask: {infile}\n' 'mask shape: {shape}\n' 'mask size: {size}\n' 'selected voxels: {nsel}\n' 'minimum bounding box coordinates: {mbb}\n' 'minimum bounding box shape: {mbb_shape}\n' 'minimum bounding box size: {mbb_size} (equals selection: {mbb_all})\n' 'selected slices: {nsl}: {sl}\n' 'maximum slices: {msl}' ) print(s.format(**d)) if args.subregion: write_subregion(mask, args.pad, args.input, args.subregion)
def main(): args = parse_args() loglevel = logging.INFO if args.verbose else logging.WARNING logging.basicConfig(level=loglevel, stream=logging.sys.stdout) logging.info('Reading image: %s', args.input) img, attrs = dwi.files.read_pmap(args.input) if args.mode == 'T2': assert attrs['echotimes'][0] == 0 # TODO: Could be another? img = img[..., 0] assert img.ndim == 3 if args.mask is None: mask = np.zeros_like(img, dtype=np.bool) mbb = dwi.util.bbox(img, pad=0) logging.info('MBB mask: %s', mbb) mask[mbb] = True mask = dwi.mask.Mask3D(mask) else: logging.info('Using mask: %s', args.mask) mask = dwi.mask.read_mask(args.mask) if isinstance(mask, dwi.mask.Mask): mask = mask.convert_to_3d(img.shape[0]) if img.shape != mask.shape(): raise Exception('Image shape {} does not match mask shape {}'.format( img.shape, mask.shape())) if mask.n_selected() == 0: raise ValueError('Empty mask.') if args.slices == 'maxfirst': slice_indices = [mask.max_slices()[0]] elif args.slices == 'max': slice_indices = mask.max_slices() elif args.slices == 'all': slice_indices = mask.selected_slices() else: raise Exception('Invalid slice set specification', args.slices) # Zero other slices in mask. for i in range(len(mask.array)): if i not in slice_indices: mask.array[i, :, :] = 0 # Use only selected slices to save memory. if not args.voxel == 'all': img = img[slice_indices].copy() mask.array = mask.array[slice_indices].copy() # Get portion mask. if args.winspec in ('all', 'mbb'): pmask = mask.array # Some methods don't use window. elif args.winspec.isdigit(): winsize = int(args.winspec) assert winsize > 0 winshape = (1, winsize, winsize) pmask = portion_mask(mask.array, winshape, portion=args.portion) else: raise ValueError('Invalid window spec: {}'.format(args.winspec)) logging.info('Image: %s, slice: %s, voxels: %s, window: %s', img.shape, slice_indices, np.count_nonzero(mask.array), args.winspec) logging.info('Calculating %s texture features for %s...', args.method, args.mode) dwi.rcParams.texture_avg = args.voxel if dwi.rcParams.texture_avg != 'all': if args.mode.startswith('T2w') and args.method.startswith('gabor'): # These result arrays can get quite huge (if float64). dwi.rcParams.texture_path = args.output if args.method in ('glcm', 'glcm_mbb'): img = dwi.util.quantize(dwi.util.normalize(img, args.mode)) tmap, names = dwi.texture.get_texture(img, args.method, args.winspec, pmask) attrs['parameters'] = names # Number of windows, or resulting texture map volume in general. attrs['tmap_voxels'] = np.count_nonzero(pmask) logging.info('Writing shape %s, type %s to %s', tmap.shape, tmap.dtype, args.output) if dwi.rcParams.texture_path: attrs['shape'] = tmap.shape attrs['dtype'] = str(tmap.dtype) dwi.hdf5.write_attrs(tmap, attrs) # Attributes may need conversion. else: dwi.files.write_pmap(args.output, tmap, attrs)