def find_size(label, max_label=None, verbose=False): """Find size given object shapes as a labled image Arguments --------- label : array, str or Source Labeled image in which each object has its own label. max_label : int or None Maximal label to include, if None use all label. verbose : bool Print progress info. Returns ------- sizes : array Measured intensities """ if verbose: timer = tmr.Timer() hdict.pprint(head='Size detection:', max_label=max_label) label = io.as_source(label) if max_label is None: max_label = int(label.max()) sizes = scipy.ndimage.measurements.sum(np.ones(label.shape, dtype=bool), labels=label, index=np.arange(1, max_label + 1)) if verbose: timer.print_elapsed_time(head='Size detection') return sizes
def _test(): import ClearMap.Utils.HierarchicalDict as hdict d = dict(x=10, y=100, z=dict(a=10, b=20)) print(hdict.get(d, 'z_a')) hdict.set(d, 'z_c_q', 42) hdict.pprint(d)
def find_intensity(source, label, max_label=None, method='sum', verbose=False): """Find integrated intensity given object shapes as labled image. Arguments --------- source : array, str, or Source Source to measure intensities from. label : array, str, or Source Labeled image with a separate label for each object. max_label : int or None Maximal label to include. If None use all. method : {'sum', 'mean', 'max', 'min'} Method to use to measure the intensities in each object's area. verbose : bool If True, print progress information. Returns ------- intensities : array Measured intensities. """ if verbose: timer = tmr.Timer() hdict.pprint(head='Intensity detection:', max_label=max_label, method=method) source = io.as_source(source).array label = io.as_source(label) if max_label is None: max_label = label.max() if method.lower() == 'sum': measure = scipy.ndimage.measurements.sum elif method.lower() == 'mean': measure = scipy.ndimage.measurements.mean elif method.lower() == 'max': measure = scipy.ndimage.measurements.maximum elif method.lower() == 'min': measure = scipy.ndimage.measurements.minimum else: raise RuntimeError('Unkown method %r!' % (method, )) intensities = measure(label, labels=label, index=np.arange(1, max_label + 1)) if verbose: timer.print_elapsed_time(head='Intensity detection') return intensities
def grey_reconstruct(source, mask=None, sink=None, method=None, shape=3, verbose=False): """Calculates the grey reconstruction of the image Arguments --------- source : array The source image data. method : 'dilation' or 'erosion' or None The mehtjod to use, if None return original image. shape : in or tuple Shape of the strucuturing element for the grey reconstruction. verbose : boo; If True, print progress info. Returns ------- reconstructed: array Grey reconstructed image. Note ---- The reconstruction is done slice by slice along the z-axis. """ if verbose: timer = tmr.Timer() hdict.pprint(head='Grey reconstruction', method=method, shape=shape) if method is None: return source if sink is None: sink = np.empty(source.shape, dtype=source.dtype) # background subtraction in each slice selem = se.structure_element(form='Disk', shape=shape, ndim=2).astype('uint8') for z in range(source.shape[2]): #img[:,:,z] = img[:,:,z] - grey_opening(img[:,:,z], structure = structureElement('Disk', (30,30))); #img[:,:,z] = img[:,:,z] - morph.grey_opening(img[:,:,z], structure = self.structureELement('Disk', (150,150))); sink[:, :, z] = source[:, :, z] - reconstruct( source[:, :, z], mask=mask[:, :, z], method=method, selem=selem) if verbose: timer.print_elapsed_time('Grey reconstruction') return sink
def find_maxima(source, h_max=None, shape=5, threshold=None, verbose=None): """Find local and extended maxima in an image. Arguments --------- source : array The source data. h_max : float or None H parameter for the initial h-Max transform. If None, do not perform a h-max transform. shape : int or tuple Shape for the structure element for the local maxima filter. threshold : float or None If float, include only maxima larger than this threshold. verbose : bool Print progress info. Returns ------- maxima : array Binary image with True pixel at extended maxima. Notes ----- This routine performs a h-max transfrom, followed by a local maxima search and thresholding of the maxima. See also -------- :func:`h_max_transform`, :func:`local_max` """ if verbose: timer = tmr.Timer() hdict.pprint(head='Find Maxima:', h_max=h_max, shape=shape, threshold=threshold) # extended maxima maxima = h_max_transform(source, h_max=h_max) #local maxima maxima = local_max(maxima, shape=shape) #thresholding if not threshold is None: maxima = np.logical_and(maxima, source >= threshold) if verbose: timer.print_elapsed_time(head='Find Maxima') return maxima
def detect_shape(source, seeds, threshold=None, verbose=False): """Detect object shapes by generatng a labeled image from seeds. Arguments --------- source : array, str or Source Source image. seeds : array, str or Source Cell centers as point coordinates. threshold : float or None Threshold to determine mask for watershed, pixel below this are treated as background. If None, the seeds are expanded indefinately. verbose :bool If True, print progress info. Returns ------- shapes : array Labeled image, where each label indicates a object. """ if verbose: timer = tmr.Timer() hdict.pprint(head='Shape detection', threshold=threshold) source = io.as_source(source).array seeds = io.as_source(seeds) if threshold is None: mask = None else: mask = source > threshold peaks = vox.voxelize(seeds, shape=source.shape, weights=np.arange(1, seeds.shape[0] + 1)).array shapes = skimage.morphology.watershed(-source, peaks, mask=mask) #shapes = watershed_ift(-source.astype('uint16'), peaks); #shapes[numpy.logical_not(mask)] = 0; if verbose: timer.print_elapsed_time('Shape detection') return shapes
def __str__(self, ident=None, with_children=False): if ident is None: ident = '' s = '' if with_children and isinstance(self.children, list): for c in self.children: s = s + '\n' + c.__str__(ident=ident + ' ') h = ident + self.name + '\n' + ident + '=' * len(self.name) + '\n' s = h + hdict.write(self.data, head=ident[:-1]) + '\n' + s return s
def detect_cells_block(source, parameter=default_cell_detection_parameter): """Detect cells in a Block.""" #initialize parameter and slicings verbose = parameter.get('verbose', False) if verbose: prefix = 'Block %s: ' % (source.info(), ) total_time = tmr.Timer(prefix) base_slicing = source.valid.base_slicing valid_slicing = source.valid.slicing valid_lower = source.valid.lower valid_upper = source.valid.upper lower = source.lower parameter_intensity = parameter.get('intensity_detection', None) measure_to_array = dict() if parameter_intensity: parameter_intensity = parameter_intensity.copy() measure = parameter_intensity.pop('measure', []) if measure is None: measure = [] for m in measure: measure_to_array[m] = None if 'source' in measure_to_array: measure_to_array['source'] = source # correct illumination parameter_illumination = parameter.get('illumination_correction', None) if parameter_illumination: parameter_illumination = parameter_illumination.copy() if verbose: timer = tmr.Timer(prefix) hdict.pprint(parameter_illumination, head=prefix + 'Illumination correction') save = parameter_illumination.pop('save', None) corrected = ic.correct_illumination(source, **parameter_illumination) if save: save = io.as_source(save) save[base_slicing] = corrected[valid_slicing] if verbose: timer.print_elapsed_time('Illumination correction') else: corrected = np.array(source.array) if 'illumination' in measure_to_array: measure_to_array['illumination'] = corrected #background subtraction parameter_background = parameter.get('background_correction', None) if parameter_background: parameter_background = parameter_background.copy() if verbose: timer = tmr.Timer(prefix) hdict.pprint(parameter_background, head=prefix + 'Background removal') save = parameter_background.pop('save', None) background = remove_background(corrected, **parameter_background) if save: save = io.as_source(save) save[base_slicing] = corrected[valid_slicing] if verbose: timer.print_elapsed_time('Illumination correction') else: background = corrected del corrected if 'background' in measure_to_array: measure_to_array['background'] = background # equalize parameter_equalize = parameter.get('equalization', None) if parameter_equalize: parameter_equalize = parameter_equalize.copy() if verbose: timer = tmr.Timer(prefix) hdict.pprint(parameter_equalize, head=prefix + 'Equalization:') save = parameter_equalize.pop('save', None) equalized = equalize(background, mask=None, **parameter_equalize) if save: save = io.as_source(save) save[base_slicing] = equalized[valid_slicing] if verbose: timer.print_elapsed_time('Equalization') else: equalized = background del background if 'equalized' in measure_to_array: measure_to_array['equalized'] = equalized #DoG filter parameter_dog_filter = parameter.get('dog_filter', None) if parameter_dog_filter: parameter_dog_filter = parameter_dog_filter.copy() if verbose: timer = tmr.Timer(prefix) hdict.pprint(parameter_dog_filter, head=prefix + 'DoG filter:') save = parameter_dog_filter.pop('save', None) dog = dog_filter(equalized, **parameter_dog_filter) if save: save = io.as_source(save) save[base_slicing] = dog[valid_slicing] if verbose: timer.print_elapsed_time('DoG filter') else: dog = equalized del equalized if 'dog' in measure_to_array: measure_to_array['dog'] = dog #Maxima detection parameter_maxima = parameter.get('maxima_detection', None) parameter_shape = parameter.get('shape_detection', None) if parameter_shape or parameter_intensity: if not parameter_maxima: print( prefix + 'Warning: maxima detection needed for shape and intensity detection!' ) parameter_maxima = dict() if parameter_maxima: parameter_maxima = parameter_maxima.copy() if verbose: timer = tmr.Timer(prefix) hdict.pprint(parameter_maxima, head=prefix + 'Maxima detection:') save = parameter_maxima.pop('save', None) valid = parameter_maxima.pop('valid', None) # extended maxima maxima = md.find_maxima(source.array, **parameter_maxima, verbose=verbose) if save: save = io.as_source(save) save[base_slicing] = maxima[valid_slicing] #center of maxima if parameter_maxima['h_max']: centers = md.find_center_of_maxima(source, maxima=maxima, verbose=verbose) else: centers = ap.where(maxima).array if verbose: timer.print_elapsed_time('Maxima detection') #correct for valid region if valid: ids = np.ones(len(centers), dtype=bool) for c, l, u in zip(centers.T, valid_lower, valid_upper): ids = np.logical_and(ids, np.logical_and(l <= c, c < u)) centers = centers[ids] del ids del dog, maxima results = (centers, ) #cell shape detection if parameter_shape: parameter_shape = parameter_shape.copy() if verbose: timer = tmr.Timer(prefix) hdict.pprint(parameter_shape, head=prefix + 'Shape detection:') save = parameter_shape.pop('save', None) # shape detection shape = sd.detect_shape(source, centers, **parameter_shape, verbose=verbose) if save: save = io.as_source(save) save[base_slicing] = shape[valid_slicing] #size detection max_label = centers.shape[0] sizes = sd.find_size(shape, max_label=max_label) valid = sizes > 0 if verbose: timer.print_elapsed_time('Shape detection') results += (sizes, ) else: valid = None shape = None #cell intensity detection if parameter_intensity: parameter_intensity = parameter_intensity.copy() if verbose: timer = tmr.Timer(prefix) hdict.pprint(parameter_intensity, head=prefix + 'Intensity detection:') if not shape is None: r = parameter_intensity.pop('shape', 3) if isinstance(r, tuple): r = r[0] for m in measure: if shape is not None: intensity = sd.find_intensity(measure_to_array[m], label=shape, max_label=max_label, **parameter_intensity) else: intensity = me.measure_expression(measure_to_array[m], centers, search_radius=r, **parameter_intensity, processes=1, verbose=False) results += (intensity, ) if verbose: timer.print_elapsed_time('Shape detection') if valid is not None: results = tuple(r[valid] for r in results) #correct coordinate offsets of blocks results = (results[0] + lower, ) + results[1:] #correct shapes for merging results = tuple(r[:, None] if r.ndim == 1 else r for r in results) if verbose: total_time.print_elapsed_time('Cell detection') gc.collect() return results
def binarize_block(source, sink, parameter = default_binarization_parameter): """Binarize a Block.""" #initialize parameter and slicings verbose = parameter.get('verbose', False); if verbose: prefix = 'Block %s: ' % (source.info(),); total_time = tmr.Timer(prefix); max_bin = parameter.get('max_bin', MAX_BIN); base_slicing = sink.valid.base_slicing; valid_slicing = source.valid.slicing; #initialize binary status for inspection binary_status = parameter.get('binary_status', None); if binary_status: binary_status = io.as_source(binary_status); binary_status = binary_status[base_slicing]; #clipping parameter_clip = parameter.get('clip', None); if parameter_clip: parameter_clip = parameter_clip.copy(); if verbose: timer = tmr.Timer(prefix); hdict.pprint(parameter_clip, head = prefix + 'Clipping:') parameter_clip.update(norm=max_bin, dtype=DTYPE); save = parameter_clip.pop('save', None); clipped, mask, high, low = clip(source, **parameter_clip); not_low = np.logical_not(low); if save: save = io.as_source(save); save[base_slicing] = clipped[valid_slicing]; if binary_status is not None: binary_status[high[valid_slicing]] += BINARY_STATUS['High'] else: sink[valid_slicing] = high[valid_slicing]; del high, low if verbose: timer.print_elapsed_time('Clipping'); else: clipped = source mask = not_low = np.ones(source.shape, dtype=bool); #high = low = np.zeros(source.shape, dtype=bool); #low = np.zeros(source.shape, dtype=bool); #not_low = np.logical_not(low); #active arrays: clipped, mask, not_low #lightsheet correction parameter_lightsheet = parameter.get('lightsheet', None); if parameter_lightsheet: parameter_lightsheet = parameter_lightsheet.copy(); if verbose: timer = tmr.Timer(prefix); hdict.pprint(parameter_lightsheet, head = prefix + 'Lightsheet:') #parameter_lightsheet.update(max_bin=max_bin); save = parameter_lightsheet.pop('save', None); corrected = lc.correct_lightsheet(clipped, mask=mask, max_bin=max_bin, **parameter_lightsheet); if save: save = io.as_source(save); save[base_slicing] = corrected[valid_slicing]; if verbose: timer.print_elapsed_time('Lightsheet'); else: corrected = clipped; del clipped #active arrays: corrected, mask, not_low #median filter parameter_median = parameter.get('median', None); if parameter_median: parameter_median = parameter_median.copy(); if verbose: timer = tmr.Timer(prefix); hdict.pprint(parameter_median, head = prefix + 'Median:') save = parameter_median.pop('save', None); median = rnk.median(corrected, max_bin=max_bin, mask=not_low, **parameter_median); if save: save = io.as_source(save); save[base_slicing] = median[valid_slicing]; if verbose: timer.print_elapsed_time('Median'); else: median = corrected; del corrected, not_low; #active arrays: median, mask #pseudo deconvolution parameter_deconvolution = parameter.get('deconvolve', None); if parameter_deconvolution: parameter_deconvolution = parameter_deconvolution.copy(); if verbose: timer = tmr.Timer(prefix); hdict.pprint(parameter_deconvolution, head = prefix + 'Deconvolution:') save = parameter_deconvolution.pop('save', None); threshold = parameter_deconvolution.pop('threshold', None); if binary_status is not None: binarized = binary_status > 0; else: binarized = sink[:]; deconvolved = deconvolve(median, binarized[:], **parameter_deconvolution) del binarized if save: save = io.as_source(save); save[base_slicing] = deconvolved[valid_slicing]; if verbose: timer.print_elapsed_time('Deconvolution'); if threshold: binary_deconvolved = deconvolved > threshold; if binary_status is not None: binary_status[binary_deconvolved[valid_slicing]] += BINARY_STATUS['Deconvolved']; else: sink[valid_slicing] += binary_deconvolved[valid_slicing]; del binary_deconvolved if verbose: timer.print_elapsed_time('Deconvolution: binarization'); else: deconvolved = median; #active arrays: median, mask, deconvolved #adaptive parameter_adaptive = parameter.get('adaptive', None); if parameter_adaptive: parameter_adaptive = parameter_adaptive.copy(); if verbose: timer = tmr.Timer(prefix); hdict.pprint(parameter_adaptive, head = prefix + 'Adaptive:') save = parameter_adaptive.pop('save', None); adaptive = threshold_adaptive(deconvolved, **parameter_adaptive) if save: save = io.as_source(save); save[base_slicing] = adaptive[valid_slicing]; binary_adaptive = deconvolved > adaptive; if binary_status is not None: binary_status[binary_adaptive[valid_slicing]] += BINARY_STATUS['Adaptive']; else: sink[valid_slicing] += binary_adaptive[valid_slicing]; del binary_adaptive, adaptive; if verbose: timer.print_elapsed_time('Adaptive'); del deconvolved #active arrays: median, mask # equalize parameter_equalize = parameter.get('equalize', None); if parameter_equalize: parameter_equalize = parameter_equalize.copy(); if verbose: timer = tmr.Timer(prefix); hdict.pprint(parameter_equalize, head = prefix + 'Equalization:') save = parameter_equalize.pop('save', None); threshold = parameter_equalize.pop('threshold', None); equalized = equalize(median, mask=mask, **parameter_equalize); if save: save = io.as_source(save); save[base_slicing] = equalized[valid_slicing]; if verbose: timer.print_elapsed_time('Equalization'); if threshold: binary_equalized = equalized > threshold if binary_status is not None: binary_status[binary_equalized[valid_slicing]] += BINARY_STATUS['Equalized']; else: sink[valid_slicing] += binary_equalized[valid_slicing]; #prepare equalized for use in vesselization parameter_vesselization = parameter.get('vesselize', None); if parameter_vesselization and parameter_vesselization.get('background', None): equalized[binary_equalized] = threshold; equalized = float(max_bin-1) / threshold * equalized; del binary_equalized if verbose: timer.print_elapsed_time('Equalization: binarization'); else: equalized = median; del median #active arrays: mask, equalized # smaller vessels /capilarries parameter_vesselization = parameter.get('vesselize', None); if parameter_vesselization: parameter_vesselization = parameter_vesselization.copy(); if verbose: timer = tmr.Timer(prefix); hdict.pprint(parameter_vesselization, head = prefix + 'Vesselization:') parameter_background = parameter_vesselization.get('background', None) parameter_background = parameter_background.copy(); if parameter_background: save = parameter_background.pop('save', None); equalized = np.array(equalized, dtype = 'uint16'); background = rnk.percentile(equalized, max_bin=max_bin, mask=mask, **parameter_background); tubeness = equalized - np.minimum(equalized, background); del background if save: save = io.as_source(save); save[base_slicing] = tubeness[valid_slicing]; else: tubeness = equalized; parameter_tubeness = parameter_vesselization.get('tubeness', {}) tubeness = tubify(tubeness, **parameter_tubeness); save = parameter_vesselization.get('save', None); if save: save = io.as_source(save); save[base_slicing] = tubeness[valid_slicing]; if verbose: timer.print_elapsed_time('Vesselization'); threshold = parameter_vesselization.get('threshold', None); if threshold: binary_vesselized = tubeness > threshold; if binary_status is not None: binary_status[binary_vesselized[valid_slicing]] += BINARY_STATUS['Tube']; else: sink[valid_slicing] += binary_vesselized[valid_slicing]; del binary_vesselized if verbose: timer.print_elapsed_time('Vesselization: binarization'); del tubeness del equalized, mask #active arrays: None #fill holes parameter_fill = parameter.get('fill', None); if parameter_fill: parameter_fill = parameter_fill.copy(); if verbose: timer = tmr.Timer(prefix); #hdict.pprint(parameter_fill, head = 'Filling:') if binary_status is not None: foreground = binary_status > 0; filled = ndi.morphology.binary_fill_holes(foreground); binary_status[np.logical_and(filled, np.logical_not(foreground))] += BINARY_STATUS['Fill']; del foreground, filled else: filled = ndi.morphology.binary_fill_holes(sink[:]); sink[valid_slicing] += filled[valid_slicing]; del filled if verbose: timer.print_elapsed_time('Filling'); if binary_status is not None: sink[valid_slicing] = binary_status[valid_slicing] > 0; #smooth binary parameter_smooth = parameter.get('smooth', None); if parameter_smooth: parameter_smooth = parameter_smooth.copy(); if verbose: timer = tmr.Timer(prefix); hdict.pprint(parameter_smooth, head = prefix + 'Smoothing:') smoothed = bs.smooth_by_configuration(sink, sink=None, processes=1, **parameter_smooth); sink[valid_slicing] = smoothed[valid_slicing]; del smoothed; if verbose: timer.print_elapsed_time('Smoothing'); if verbose: total_time.print_elapsed_time('Binarization') gc.collect() return None;
def correct_illumination(source, flatfield = None, background = None, scaling = None, dtype = None, verbose = False): """Correct illumination and background. Arguments --------- source : array, str, or Source The image to correct for illumination. sink : array, str, Source, or None The sink to write results to. flatfield : str, array, Source or None The flatfield estimate. If None, no flat field correction is done. background : str, array, Source or None The background estimate. If None, backgorund is assumed to be zero. scaling : float, 'max', 'mean' or None Scale the corrected result by this factor. If 'max' or 'mean' scale the result to match the 'max' or 'mean'. If None, dont scale the result. processes : int or None Number of processes to use. If None use macimal available. verbose : bool If true, print progrss infomration. Returns ------- corrected : array Illumination corrected image. Note ---- The intensity image :math:`I(x)` given a flat field :math:`F(x)` and a background :math:`B(x)` image is corrected to :math:`C(x)` as: .. math: C(x) = \\frac{I(x) - B(x)}{F(x) - B(x)} If the background is not given :math:`B(x) = 0`. The correction is done slice by slice assuming the data was collected with a light sheet microscope. The image is finally optionally scaled. References ---------- [1] Fundamentals of Light Microscopy and Electronic Imaging, p 421 See Also -------- :const:`default_flatfield_line_file_name` """ if background is not None: background = io.as_source(background); if flatfield is None: return source; if flatfield is True: # default flatfield correction flatfield = default_flat_field_line_file_name; if isinstance(flatfield, str): flatfield = io.as_source(flatfield); if flatfield.ndim == 1: flatfield = flatfield_from_line(flatfield, source.shape[1]); if flatfield.shape[:2] != source.shape[:2]: raise ValueError("The flatfield shape %r does not match the source shape %r!" % (flatfield.shape[:2], source.shape[:2])); flatfield = io.as_source(flatfield); if verbose: timer = tmr.Timer(); hdict.pprint(head = 'Illumination correction:', flatfield=flatfield, background=background, scaling=scaling); #initilaize source source = io.as_source(source); if dtype is None: dtype = source.dtype; # rescale factor flatfield = flatfield.array.astype(dtype); if scaling is True: scaling = "mean"; if isinstance(scaling, str): if scaling.lower() == "mean": # scale back by average flat field correction: scaling = flatfield.mean(); elif scaling.lower() == "max": scaling = flatfield.max(); else: raise RuntimeError('Scaling not "max" or "mean" but %r!' % (scaling,)); # illumination correction in each slice corrected = np.array(source.array, dtype=dtype) if background is None: for z in range(source.shape[2]): corrected[:,:,z] = source[:,:,z] / flatfield; else: if background.shape != flatfield.shape: raise RuntimeError("Illumination correction: background does not match source shape: %r vs %r!" % (background.shape, source[:,:,0].shape)); background = background.array.astype('float32'); flatfield = (flatfield - background); for z in range(source.shape[2]): corrected[:,:,z] = (source[:,:,z] - background) / flatfield; if not scaling is None: corrected= corrected * scaling; if verbose: timer.print_elapsed_time('Illumination correction'); return corrected
'source', 'background' ] cell_detection_parameter['verbose'] = False # Save cell_detection_parameter.p fname = '/jukebox/witten/Chris/data/clearmap2/utilities/cell_detection_parameter.p' with open(fname, 'wb') as f: pickle.dump(cell_detection_parameter, f) cell_detection_parameter = None # Load and print cell_detection_parameter.p with open(fname, 'rb') as f: cell_detection_parameter = pickle.load(f) print() print('path : ' + fname) hdict.pprint(cell_detection_parameter) print() # Set ClearMap2 cell detection filter thresholds cell_detection_filter = {} cell_detection_filter['x'] = (None, None) cell_detection_filter['y'] = (None, None) cell_detection_filter['z'] = (None, None) cell_detection_filter['size'] = (20, None) cell_detection_filter['intensity'] = (None, None) cell_detection_filter['region'] = (None, None) # Save cell_detection_filters.p fname = '/jukebox/witten/Chris/data/clearmap2/utilities/cell_detection_filter.p' with open(fname, 'wb') as f: pickle.dump(cell_detection_filter, f)