def extract_masks(im, abs_threshold=1000, output='', report={}): """Generate a series masks at different thresholds.""" thresholds = [500, 1000, 2000, 3000, 4000, 5000] if abs_threshold not in thresholds: thresholds.append(abs_threshold) thresholds.sort() report['parameters']['simple_thresholds'] = thresholds mos = [] c_slcs = {} for thr in thresholds: ods = 'mask_thr{:05d}'.format(thr) outputpath = '' if output: outputpath = output.format(ods) mo = prob2mask(im, lower_threshold=thr, upper_threshold=np.inf, outputpath=outputpath) mo.load(load_data=False) c_slcs = {dim: get_centreslice(mo, '', dim) for dim in 'zyx'} report['centreslices'][ods] = c_slcs mos.append(mo) return mos, report
def postproc_masks(im, thrs=[], fill_holes=True, output='', report={}): """Apply slicewise thresholds to data and fill holes. NOTE: zyx assumed """ ods = 'mask_thr{:05d}'.format(0) im.load(load_data=False) if thrs: data = im.slice_dataset() mask = np.zeros(im.dims[:3], dtype='bool') for slc in range(0, mask.shape[0]): mask[slc, :, :] = data[slc, :, :] > thrs[slc] else: mask = im.slice_dataset() im.close() if fill_holes: for slc in range(0, mask.shape[0]): mask[slc, :, :] = binary_fill_holes(mask[slc, :, :]) props = im.get_props() mo = write_data(mask, props, output, ods) c_slcs = {dim: get_centreslice(mo, '', dim) for dim in 'zyx'} report['centreslices'][ods] = c_slcs return mo, report
def extract_smooth(im, sigma=48.0, keep_dtype=True, output='', report={}): """Smooth the image in-plane.""" def smooth(data, sigma, elsize): """Smooth data with Gaussian kernel.""" if len(sigma) == 1: sigma = sigma * len(elsize) elif len(sigma) != len(elsize): raise Exception('sigma does not match dimensions') sigma = [sig / es for sig, es in zip(sigma, elsize)] data_smoothed = gaussian_filter(data, sigma) return data_smoothed ods = 'smooth' if not isinstance(sigma, list): sigma = [sigma] * 3 sigma[im.axlab.index('z')] = 0.0 im.load(load_data=False) data_smoothed = smooth(im.slice_dataset(), sigma, im.elsize) if keep_dtype: data_smoothed = data_smoothed.astype(im.dtype) im.close() props = im.get_props() mo = write_data(data_smoothed, props, output, ods) c_slcs = {dim: get_centreslice(mo, '', dim) for dim in 'zyx'} report['centreslices'][ods] = c_slcs return mo, report
def downsample_channel(image_in, ch, resolution_level=-1, dsfacs=[1, 4, 4, 1, 1], ismask=False, output='', report={}): """Downsample an image.""" ods = 'data' if not ismask else 'mask' # return in case no mask provided if not image_in: return None, report, '' if resolution_level != -1 and not ismask: # we should have an Imaris pyramid image_in = '{}/DataSet/ResolutionLevel {}'.format( image_in, resolution_level) # load data im = Image(image_in, permission='r') im.load(load_data=False) props = im.get_props() if len(im.dims) > 4: im.slices[im.axlab.index('t')] = slice(0, 1, 1) props = im.squeeze_props(props, dim=4) if len(im.dims) > 3: im.slices[im.axlab.index('c')] = slice(ch, ch + 1, 1) props = im.squeeze_props(props, dim=3) data = im.slice_dataset() im.close() # downsample dsfac = tuple(dsfacs[:len(data.shape)]) if not ismask: data = downscale_local_mean(data, dsfac).astype('float32') else: data = block_reduce(data, dsfac, np.max) # generate output props['axlab'] = 'zyx' # FIXME: axlab returns as string-list props['shape'] = data.shape props['elsize'] = [es * ds for es, ds in zip(im.elsize[:3], dsfac)] props['slices'] = None mo = write_data(data, props, output, ods) # report data thr = 1000 meds_mask = data < thr report['medians'][ods] = get_zyx_medians(data, meds_mask) c_slcs = {dim: get_centreslice(mo, '', dim) for dim in 'zyx'} report['centreslices'][ods] = c_slcs return mo, report, meds_mask
def calculate_bias_field(im, mask=None, n_iter=50, n_fitlev=4, n_cps=[5, 5, 5], output='', report={}, meds_mask=''): """Calculate the bias field.""" import SimpleITK as sitk ods = 'bias' # wmem images to sitk images dsImage = sitk.GetImageFromArray(im.ds) dsImage.SetSpacing(np.array(im.elsize[::-1], dtype='float')) dsImage = sitk.Cast(dsImage, sitk.sitkFloat32) if mask is not None: dsMask = sitk.GetImageFromArray(mask.ds[:].astype('uint8')) dsMask.SetSpacing(np.array(im.elsize[::-1], dtype='float')) dsMask = sitk.Cast(dsMask, sitk.sitkUInt8) # run the N4 correction corrector = sitk.N4BiasFieldCorrectionImageFilter() corrector.SetDebug(True) corrector.SetMaximumNumberOfIterations([n_iter] * n_fitlev) corrector.SetNumberOfControlPoints(n_cps) if mask is None: dsOut = corrector.Execute(dsImage) else: dsOut = corrector.Execute(dsImage, dsMask) # get the bias field at lowres (3D) data = np.stack(sitk.GetArrayFromImage(dsImage)) data /= np.stack(sitk.GetArrayFromImage(dsOut)) data = np.nan_to_num(data, copy=False).astype('float32') # generate output props = im.get_props() mo = write_data(data, props, output, ods) # report data report['medians'][ods] = get_zyx_medians(data, meds_mask) c_slcs = {dim: get_centreslice(mo, '', dim) for dim in 'zyx'} report['centreslices'][ods] = c_slcs return mo, report
def calculate_distance_to_edge(im, output='', report={}): """"Calculate the euclidian distance transform of the mask.""" ods = 'mask_thr{:05d}_edt'.format(0) im.load(load_data=False) elsize = np.absolute(im.elsize) dt = np.zeros(im.ds.shape, dtype='float') for i, slc in enumerate(im.ds[:]): dt[i, :, :] = distance_transform_edt(slc, sampling=elsize[1:]) props = im.get_props() mo = write_data(dt, props, output, ods) c_slcs = {dim: get_centreslice(mo, '', dim) for dim in 'zyx'} report['centreslices'][ods] = c_slcs return mo, report
def divide_bias_field(im, bf, output='', report={}, meds_mask=''): """Apply bias field correction.""" ods = 'corr' data = np.copy(im.ds[:]).astype('float32') data /= bf.ds[:] data = np.nan_to_num(data, copy=False) props = im.get_props() mo = write_data(data, props, output, ods) report['medians'][ods] = get_zyx_medians(data, meds_mask) c_slcs = {dim: get_centreslice(mo, '', dim) for dim in 'zyx'} report['centreslices'][ods] = c_slcs return mo, report
def extract_mean(im, dim='c', keep_dtype=True, output='', report={}): """Calculate mean over channels.""" ods = 'mean' im.load(load_data=False) props = im.get_props() if len(im.dims) > 4: props = im.squeeze_props(props, dim=4) if len(im.dims) > 3: props = im.squeeze_props(props, dim=3) mo = Image(output.format(ods), **props) mo.create() zdim = im.axlab.index('z') if im.chunks is not None: nslcs = im.chunks[zdim] else: nslsc = 8 slc_thrs = [] for zstart in range(0, im.dims[zdim], nslcs): zstop = min(im.dims[zdim], zstart + nslcs) im.slices[zdim] = mo.slices[zdim] = slice(zstart, zstop, None) data_mean = np.mean(im.slice_dataset(), axis=im.axlab.index(dim)) if keep_dtype: data_mean = data_mean.astype(im.dtype) mo.write(data_mean) slc_thrs += list(np.median(np.reshape(data_mean, [data_mean.shape[0], -1]), axis=1)) mo.slices = None mo.set_slices() im.close() c_slcs = {dim: get_centreslice(mo, '', dim) for dim in 'zyx'} report['centreslices'][ods] = c_slcs return mo, report, slc_thrs