def process_block(image_in, ndim, blockreduce, func, blockoffset, blocksize, margin, fullsize, mo, is_labelimage, relabel, neighbourmerge, save_fwmap, maxlabel, mpi): """Write a block of data into a hdf5 file.""" # open data for reading im = Image(image_in, permission='r') im.load(mpi.comm, load_data=False) # get the indices into the input and output datasets # TODO: get indices from attributes # TODO: get from mpi.get_blocks set_slices_in_and_out(im, mo, blocksize, margin, fullsize) # simply copy the data from input to output """NOTE: it is assumed that the inputs are not 4D labelimages """ if ndim == 4: mo.write(im.slice_dataset()) im.close() return if ((not is_labelimage) or ((not relabel) and (not neighbourmerge) and (not blockreduce))): data = im.slice_dataset() #datatype = 'uint16' #from skimage.util.dtype import convert #data = convert(data, np.dtype(datatype), force_copy=False) mo.write(data) im.close() return # forward map to relabel the blocks in the output if relabel: # FIXME: make sure to get all data in the block fw, maxlabel = relabel_block(im.ds[:], maxlabel, mpi) if save_fwmap: comps = im.split_path() fpath = '{}_{}.npy'.format(comps['base'], comps['int'][1:]) np.save(fpath, fw) if (not neighbourmerge) and (not blockreduce): data = im.slice_dataset() mo.write(fw[data]) im.close() return else: ulabels = np.unique(im.ds[:]) fw = [l for l in range(0, np.amax(ulabels) + 1)] fw = np.array(fw) # blockwise reduction of input datasets if blockreduce is not None: pass else: data = im.slice_dataset() # merge overlapping labels fw = merge_overlap(fw, im, mo, data, margin) mo.write(fw[data]) im.close()
def add_features(df, image_in='', origin=[0, 0, 0], dsfacs=[1, 16, 16]): if 'centroid-0' in df.columns: cens = ['centroid-{}'.format(i) for i in [0, 1, 2]] coms = ['com_{}'.format(d) for d in 'zyx'] df[coms] = df[cens] + origin if image_in: dt_im = Image(image_in, permission='r') dt_im.load(load_data=False) data = dt_im.slice_dataset() dt_im.close() ds_centroid = np.array(df[coms] / dsfacs, dtype='int') ds_centroid = [data[p[0], p[1], p[2]] for p in ds_centroid] df['dist_to_edge'] = np.array(ds_centroid) if 'inertia_tensor_eigvals-0' in df.columns: ites = ['inertia_tensor_eigvals-{}'.format(i) for i in [0, 1, 2]] eigvals = np.clip(np.array(df[ites]), 0, np.inf) df['fractional_anisotropy'] = fractional_anisotropy(eigvals) df['major_axis_length'] = get_ellips_axis_lengths(eigvals[:, 0]) df['minor_axis_length'] = get_ellips_axis_lengths(eigvals[:, -1]) # TODO: range, variance, ... return df
def get_centreslice(image_in, ids, dim='z', ch=0): """Return an image's centreslice for a dimension.""" if isinstance(image_in, Image): im = image_in else: im = Image('{}/{}'.format(image_in, ids)) try: im.load(load_data=False) except KeyError: print('dataset {} not found'.format(ids)) return None if len(im.dims) > 3: ch_idx = im.axlab.index('c') im.slices[ch_idx] = slice(ch, ch + 1, 1) dim_idx = im.axlab.index(dim) cslc = int(im.dims[dim_idx] / 2) slcs = [slc for slc in im.slices] im.slices[dim_idx] = slice(cslc, cslc + 1, 1) data = im.slice_dataset() im.slices = slcs return data
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 get_data(h5_path, ids, ch=0, dim=''): im = Image('{}/{}'.format(h5_path, ids)) im.load(load_data=False) if dim: dim_idx = im.axlab.index(dim) cslc = int(im.dims[dim_idx] / 2) im.slices[dim_idx] = slice(cslc, cslc + 1, 1) if len(im.dims) > 3: im.slices[im.axlab.index('c')] = slice(ch, ch + 1, 1) data = im.slice_dataset() return data
def apply_bias_field_full(image_in, bias_in, dsfacs=[1, 64, 64, 1], in_place=False, write_to_single_file=False, blocksize_xy=1280, outputpath='', channel=None): """single-core in ~200 blocks""" perm = 'r+' if in_place else 'r' im = Image(image_in, permission=perm) im.load(load_data=False) bf = Image(bias_in, permission='r') bf.load(load_data=False) if channel is not None: im.slices[3] = slice(channel, channel + 1) if write_to_single_file: # assuming single-channel copied file here mo = Image(outputpath) mo.load() mo.slices[3] = slice(0, 1, 1) mpi = wmeMPI(usempi=False) mpi_nm = wmeMPI(usempi=False) if blocksize_xy: blocksize = [im.dims[0], blocksize_xy, blocksize_xy, 1, 1] blockmargin = [0, im.chunks[1], im.chunks[2], 0, 0] else: blocksize = im.dims[:3] + [1, 1] blockmargin = [0] * len(im.dims) mpi.set_blocks(im, blocksize, blockmargin) mpi_nm.set_blocks(im, blocksize) mpi.scatter_series() for i in mpi.series: print(i) block = mpi.blocks[i] data_shape = list(im.slices2shape(block['slices'])) block_nm = mpi_nm.blocks[i] it = zip(block['slices'], block_nm['slices'], blocksize, data_shape) data_shape = list(im.slices2shape(block_nm['slices'])) data_slices = [] for b_slc, n_slc, bs, ds in it: m_start = n_slc.start - b_slc.start m_stop = m_start + bs m_stop = min(m_stop, ds) data_slices.append(slice(m_start, m_stop, None)) data_slices[3] = block['slices'][3] data_shape = list(im.slices2shape(data_slices)) # get the fullres image block im.slices = block['slices'] data = im.slice_dataset().astype('float') # get the upsampled bias field bias = get_bias_field_block(bf, im.slices, data.shape) data /= bias data = np.nan_to_num(data, copy=False) if in_place: im.slices = block_nm['slices'] data = data[tuple(data_slices[:3])].astype(im.dtype) im.write(data) elif write_to_single_file: mo.slices = block_nm['slices'] mo.slices[3] = slice(0, 1, 1) data = data[tuple(data_slices[:3])].astype(mo.dtype) mo.write(data) else: 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) props['axlab'] = 'zyx' # FIXME: axlab return as string-list props['shape'] = bias.shape props['slices'] = None props['dtype'] = bias.dtype mo = Image(block['path'], **props) # FIXME: needs channel mo.create(comm=mpi.comm) mo.slices = None mo.set_slices() mo.write(data=bias) mo.close() im.close() bf.close()