Example #1
0
def detect_maxima(source, h_max=None, shape=5, threshold=None, verbose=False):
    # extended maxima
    maxima = md.find_maxima(source,
                            h_max=h_max,
                            shape=shape,
                            threshold=threshold,
                            verbose=verbose)

    #center of maxima
    if h_max:
        centers = md.find_center_of_maxima(source,
                                           maxima=maxima,
                                           verbose=verbose)
    else:
        centers = ap.where(maxima).array

    return centers
Example #2
0
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
Example #3
0
def _test():
    import numpy as np
    import ClearMap.ParallelProcessing.DataProcessing.ArrayProcessing as ap

    ## Lookup table processing

    #apply_lut
    x = np.random.randint(0, 100, size=(20, 30))
    lut = np.arange(100) + 1
    y = ap.apply_lut(x, lut)
    assert np.all(y == x + 1)

    #apply_lut_to_index
    import ClearMap.ImageProcessing.Topology.Topology3d as t3d
    kernel = t3d.index_kernel(dtype=int)

    import ClearMap.ImageProcessing.Binary.Smoothing as sm
    lut = sm.initialize_lookup_table()

    data = np.array(np.random.rand(150, 30, 40) > 0.75, order='F')

    result = ap.apply_lut_to_index(data, kernel, lut, sink=None, verbose=True)

    import ClearMap.Visualization.Plot3d as p3d
    p3d.plot([[data, result]])

    ### Correlation

    #correlate1d
    kernel = np.array(range(11), dtype='uint32')
    data = np.array(np.random.randint(0,
                                      2**27, (300, 400, 1500),
                                      dtype='uint32'),
                    order='F')
    #data = np.array(np.random.rand(3,4,5), order='F');

    data = np.empty((300, 400, 1500), order='F')
    kernel = np.array([1, 2, 3, 4, 5], dtype='uint8')

    sink = 'test.npy'

    import ClearMap.Utils.Timer as tmr
    import scipy.ndimage as ndi
    timer = tmr.Timer()
    for axis in range(3):
        print(axis)
        corr_ndi = ndi.correlate1d(data, axis=axis, mode='constant', cval=0)
    timer.print_elapsed_time('ndi')

    timer = tmr.Timer()
    for axis in range(3):
        print(axis)
        corr = ap.correlate1d(data,
                              sink=sink,
                              kernel=kernel,
                              axis=axis,
                              verbose=False,
                              processes=None)
    timer.print_elapsed_time('ap')

    assert np.allclose(corr.array, corr_ndi)

    # IO
    import ClearMap.ParallelProcessing.DataProcessing.ArrayProcessing as ap
    import numpy as np
    reload(ap)

    data = np.random.rand(10, 200, 10)

    sink = ap.write('test.npy', data, verbose=True)
    assert (np.all(sink.array == data))

    read = ap.read('test.npy', verbose=True)
    assert (np.all(read.array == data))

    ap.io.delete_file('test.npy')

    # where
    reload(ap)
    data = np.random.rand(30, 20, 40) > 0.5

    where_np = np.array(np.where(data)).T
    where = ap.where(data, cutoff=2**0)

    check_np = np.zeros(data.shape, dtype=bool)
    check = np.zeros(data.shape, dtype=bool)
    check_np[tuple(where_np.T)] = True
    check[tuple(where.array.T)] = True
    assert (np.all(check_np == check))
Example #4
0
def graph_from_skeleton(skeleton, points = None, radii = None, vertex_coordinates = True, 
                        check_border = True, delete_border = False, verbose = False):
  """Converts a binary skeleton image to a graph-tool graph.
  
  Arguments
  ---------
  skeleton : array
    Source with 2d/3d binary skeleton.
  points : array
    List of skeleton points as 1d indices of flat skeleton array (optional to save processing time).
  radii  : array
    List of radii associated with each vertex.
  vertex_coordinates : bool
    If True, store coordiantes of the vertices / edges.
  check_border : bool
    If True, check if the boder is empty. The algorithm reuqires this.
  delete_border : bool
    If True, delete the border.
  verbose : bool
    If True, print progress information.
    
  Returns
  -------
  graph : Graph class
    The graph corresponding to the skeleton. 
    
  Note
  ----
  Edges are detected between neighbouring foreground pixels using 26-connectivty.
  """
  skeleton = io.as_source(skeleton);
  
  if delete_border:
    skeleton = t3d.delete_border(skeleton);
    check_border = False;
  
  if check_border:
    if not t3d.check_border(skeleton):
      raise ValueError('The skeleton array needs to have no points on the border!');  

  
  if verbose:
    timer = tmr.Timer();
    timer_all = tmr.Timer();
    print('Graph from skeleton calculation initialize.!');
  
  if points is None:
    points = ap.where(skeleton.reshape(-1, order = 'A')).array;
    
    if verbose:
      timer.print_elapsed_time('Point list generation');
      timer.reset();
  
  #create graph
  n_vertices = points.shape[0];
  g = ggt.Graph(n_vertices=n_vertices, directed=False);
  g.shape = skeleton.shape;
    
  if verbose:
    timer.print_elapsed_time('Graph initialized with %d vertices' % n_vertices);
    timer.reset();
  
  #detect edges
  edges_all = np.zeros((0,2), dtype = int);
  for i,o in enumerate(t3d.orientations()):
    # calculate off set
    offset = np.sum((np.hstack(np.where(o))-[1,1,1]) * skeleton.strides) 
    edges = ap.neighbours(points, offset);
    if len(edges) > 0:
      edges_all = np.vstack([edges_all, edges]);
      
    if verbose:
      timer.print_elapsed_time('%d edges with orientation %d/13 found' % (edges.shape[0], i+1));
      timer.reset();
  
  if edges_all.shape[0] > 0:
    g.add_edge(edges_all);
    
  if verbose:
    timer.print_elapsed_time('Added %d edges to graph' % (edges_all.shape[0]));
    timer.reset();

  if vertex_coordinates:
    vertex_coordinates = np.array(np.unravel_index(points, skeleton.shape, order=skeleton.order)).T;
    g.set_vertex_coordinates(vertex_coordinates);
  
  if radii is not None:
    g.set_vertex_radius(radii);  
  
  if verbose:
    timer_all.print_elapsed_time('Skeleton to Graph');

  return g;
Example #5
0
def skeletonize_index(binary,
                      points=None,
                      steps=None,
                      removals=False,
                      radii=False,
                      return_points=False,
                      check_border=True,
                      delete_border=False,
                      verbose=True):
    """Skeletonize a binary 3d array using PK12 algorithm via index coordinates.
  
  Arguments
  ---------
  binary : array
    Binary image to be skeletonized. 
  steps : int or None
    Number of maximal iteration steps. If None, use maximal reduction.
  removals :bool
    If True, returns the steps in which the pixels in the input data 
    were removed.
  radii :bool
    If True, the estimate of the local radius is returned.
  verbose :bool
    If True, print progress info.
    
  Returns
  -------
  skeleton : array
    The skeleton of the binary input.
  points : nxd array
    The point coordinates of the skeleton.
  """

    if verbose:
        print('#############################################################')
        print('Skeletonization PK12 [convolution, index]')
        timer = tmr.Timer()

    #TODO: make this work for any memmapable source
    if not isinstance(binary, np.ndarray):
        raise ValueError('Numpy array required for binary in skeletonization!')
    if binary.ndim != 3:
        raise ValueError('The binary array dimension is %d, 3 is required!' %
                         binary.ndim)

    if delete_border:
        binary = t3d.delete_border(binary)
        check_border = False

    if check_border:
        if not t3d.check_border(binary):
            raise ValueError(
                'The binary array needs to have not points on the border!')

    binary_flat = binary.reshape(-1, order='A')

    # detect points
    if points is None:
        points = ap.where(binary_flat).array
    npoints = points.shape[0]

    if verbose:
        timer.print_elapsed_time('Foreground points: %d' % (points.shape[0], ))

    if removals is True or radii is True:
        #birth = np.zeros(binary.shape, dtype = 'uint16');
        order = 'C'
        if binary.flags.f_contiguous:
            order = 'F'
        death = np.zeros(binary.shape, dtype='uint16', order=order)
        deathflat = death.reshape(-1, order='A')
        with_info = True
    else:
        with_info = False

    # iterate
    if steps is None:
        steps = -1
    step = 1
    nnonrem = 0
    while True:
        if verbose:
            print(
                '#############################################################'
            )
            print('Iteration %d' % step)
            timer_iter = tmr.Timer()

        print(type(points), points.dtype, binary.dtype)
        border = cpl.convolve_3d_indices_if_smaller_than(
            binary, t3d.n6, points, 6)
        borderpoints = points[border]
        #borderids    = np.nonzero(border)[0];
        borderids = ap.where(border).array
        keep = np.ones(len(border), dtype=bool)
        if verbose:
            timer_iter.print_elapsed_time('Border points: %d' %
                                          (len(borderpoints), ))

        #if info is not None:
        #  b = birth[borderpoints[:,0], borderpoints[:,1], borderpoints[:,2]];
        #  bids = b == 0;
        #  birth[borderpoints[bids,0], borderpoints[bids,1], borderpoints[bids,2]] = step;

        # sub iterations
        remiter = 0
        for i in range(12):
            if verbose:
                print(
                    '-------------------------------------------------------------'
                )
                print('Sub-Iteration %d' % i)
                timer_sub_iter = tmr.Timer()

            remborder = delete[cpl.convolve_3d_indices(binary, rotations[i],
                                                       borderpoints)]
            rempoints = borderpoints[remborder]
            if verbose:
                timer_sub_iter.print_elapsed_time('Matched points  : %d' %
                                                  (len(rempoints), ))

            binary_flat[rempoints] = 0
            keep[borderids[remborder]] = False
            rem = len(rempoints)
            remiter += rem

            #death times
            if with_info is True:
                #remo = np.logical_not(keep);
                deathflat[rempoints] = 12 * step + i

            if verbose:
                timer_sub_iter.print_elapsed_time('Sub-Iteration %d' % (i, ))

        if verbose:
            print(
                '-------------------------------------------------------------'
            )

        #update foregroud
        points = points[keep]

        if step % 3 == 0:
            npts = len(points)
            points = points[consider[cpl.convolve_3d_indices(
                binary, base, points)]]
            nnonrem += npts - len(points)
            if verbose:
                print('Non-removable points: %d' % (npts - len(points)))

        if verbose:
            print('Foreground points   : %d' % points.shape[0])

        if verbose:
            print(
                '-------------------------------------------------------------'
            )
            timer_iter.print_elapsed_time('Iteration %d' % (step, ))

        step += 1
        if steps >= 0 and step >= steps:
            break
        if remiter == 0:
            break

    if verbose:
        print('#############################################################')
        timer.print_elapsed_time('Skeletonization done')
        print('Total removed:   %d' % (npoints - (len(points) + nnonrem)))
        print('Total remaining: %d' % (len(points) + nnonrem))

    if radii is True or return_points is True:
        points = ap.where(binary_flat).array

    if radii is True:
        #calculate average diameter as death average death of neighbourhood
        radii = cpl.convolve_3d_indices(death,
                                        t3d.n18,
                                        points,
                                        out_dtype='uint16')
    else:
        radii = None

    result = [binary]
    if return_points:
        result.append(points)
    if removals is True:
        result.append(death)
    if radii is not None:
        result.append(radii)

    if len(result) > 1:
        return tuple(result)
    else:
        return result[0]
Example #6
0
def skeletonize(binary,
                points=None,
                steps=None,
                removals=False,
                radii=False,
                check_border=True,
                delete_border=False,
                return_points=False,
                verbose=True):
    """Skeletonize a binary 3d array using PK12 algorithm.
  
  Arguments
  ---------
  binary : array
    Binary image to skeletonize.
  points : array or None.
    Optional list of points in the binary to speed up processing.
  steps : int or None
    Number of maximal iteration steps (if None maximal reduction).
  removals : bool
    If True, returns also the steps at which the pixels in the input data 
    where removed. 
  radii : bool
    If True, the estimate of the local radius is returned.
  check_border : bool
    If True, check if the boder is empty. The algorithm reuqires this.
  delete_border : bool
    If True, delete the border.
  verbose : bool
    If True print progress info.
    
  Returns
  -------
  skeleton : array
    The skeleton of the binary.
  points : array
    The point coordinates of the skeleton nx3
  
  Note
  ----
  The skeletonization is done in place on the binary. Copy the binary if
  needed for further processing.
  """

    if verbose:
        print('#############################################################')
        print('Skeletonization PK12 [convolution]')
        timer = tmr.Timer()

    #TODO: make this work for any memmapable source !
    if not isinstance(binary, np.ndarray):
        raise ValueError('Numpy array required for binary in skeletonization!')
    if binary.ndim != 3:
        raise ValueError('The binary array dimension is %d, 3 is required!' %
                         binary.ndim)

    if delete_border:
        binary = t3d.delete_border(binary)
        check_border = False

    if check_border:
        if not t3d.check_border(binary):
            raise ValueError(
                'The binary array needs to have no points on the border!')

    # detect points
    #points = np.array(np.nonzero(binary)).T;
    if points is None:
        points = ap.where(binary).array

    if verbose:
        timer.print_elapsed_time(head='Foreground points: %d' %
                                 (points.shape[0], ))

    if removals is True or radii is True:
        #birth = np.zeros(binary.shape, dtype = 'uint16');
        death = np.zeros(binary.shape, dtype='uint16')
        with_info = True
    else:
        with_info = False

    # iterate
    if steps is None:
        steps = -1
    step = 1
    removed = 0
    while True:
        if verbose:
            print(
                '#############################################################'
            )
            print('Iteration %d' % step)
            timer_iter = tmr.Timer()

        border = cpl.convolve_3d_points(binary, t3d.n6, points) < 6
        borderpoints = points[border]
        borderids = np.nonzero(border)[0]
        keep = np.ones(len(border), dtype=bool)
        if verbose:
            timer_iter.print_elapsed_time('Border points: %d' %
                                          (len(borderpoints), ))

        #if info is not None:
        #  b = birth[borderpoints[:,0], borderpoints[:,1], borderpoints[:,2]];
        #  bids = b == 0;
        #  birth[borderpoints[bids,0], borderpoints[bids,1], borderpoints[bids,2]] = step;

        # sub iterations
        remiter = 0
        for i in range(12):
            if verbose:
                print(
                    '-------------------------------------------------------------'
                )
                print('Sub-Iteration %d' % i)
                timer_sub_iter = tmr.Timer()

            remborder = delete[cpl.convolve_3d_points(binary, rotations[i],
                                                      borderpoints)]
            rempoints = borderpoints[remborder]
            if verbose:
                timer_sub_iter.print_elapsed_time('Matched points: %d' %
                                                  (len(rempoints), ))

            binary[rempoints[:, 0], rempoints[:, 1], rempoints[:, 2]] = 0
            keep[borderids[remborder]] = False
            rem = len(rempoints)
            remiter += rem
            removed += rem
            if verbose:
                print('Deleted points: %d' % (rem))
                timer_sub_iter.print_elapsed_time('Sub-Iteration %d' % (i))

            #death times
            if with_info is True:
                #remo = np.logical_not(keep);
                death[rempoints[:, 0], rempoints[:, 1],
                      rempoints[:, 2]] = 12 * step + i

        #update foreground
        points = points[keep]
        if verbose:
            print('Foreground points: %d' % points.shape[0])

        if verbose:
            print(
                '-------------------------------------------------------------'
            )
            timer_iter.print_elapsed_time('Iteration %d' % (step, ))

        step += 1
        if steps >= 0 and step >= steps:
            break
        if remiter == 0:
            break

    if verbose:
        print('#############################################################')
        print('Total removed:   %d' % (removed))
        print('Total remaining: %d' % (len(points)))
        timer.print_elapsed_time('Skeletonization')

    result = [binary]
    if return_points:
        result.append(points)
    if removals is True:
        result.append(death)
    if radii is True:
        #calculate average diameter as average death of neighbourhood
        radii = cpl.convolve_3d(death, np.array(t3d.n18, dtype='uint16'),
                                points)
        result.append(radii)

    if len(result) > 1:
        return tuple(result)
    else:
        return result[0]