def clean_labels(labels, rad, OPEN=3): """default cleaning. Fill holes, remove small and large objects and opening. """ labels = gray_fill_holes(labels) labels = clear_border(labels, buffer_size=2) labels = remove_small_objects(labels, rad[0]**2 * np.pi, connectivity=4) antimask = remove_small_objects(labels, rad[1]**2 * np.pi, connectivity=4) labels[antimask > 0] = False labels = label(binary_opening(labels, np.ones((int(OPEN), int(OPEN))), iterations=1)) return labels
def agglomeration_seed(labels, img, MINSIZE=50, STEPS=100, FILSIZE=5, RATIO=0): """ MINSIZE: minimum area for a seed object. It can be smaller than actual objects. STEPS: Larger it is, more resolution and computation FILSIZE: argument for adaptive thresholding. Larger if capturing too much backrgound. RATIO: argument for adaptive thresholding. Larger if capturing too much backrgound. """ seed = binary_erosion(labels, np.ones((3, 3))) li = [] img = img.astype(np.float32) mask = adaptive_thresh(img, RATIO, FILSIZE) mask = binary_opening(mask, np.ones((3, 3))) mask = remove_small_objects(mask, MINSIZE) foreground = img[mask] perclist = [ np.percentile(foreground, r) for r in np.linspace(0, 100, STEPS) ] for _r in perclist: thresed = remove_small_objects(img > _r, MINSIZE, connectivity=2) > 0 li.append(thresed.astype(np.uint16)) if seed is not None: li.append((seed > 0).astype(np.uint16)) for l in li: l[seed > 0] = 1 q = np.sum(np.dstack(li), axis=2) p = label(q) for ind in reversed(np.unique(q).tolist()): c = seeding_separate(label(q >= ind), p) w = watershed(q >= ind, markers=c, mask=(q >= ind), watershed_line=True) w[mask == 0] = 0 w = remove_small_objects(w, MINSIZE) p = label(w, connectivity=2) return p
def cytoplasm_levelset(labels, img, niter=20, dt=-0.5, thres=0.5): """ Segment cytoplasm from supplied nuclear labels and probability map Expand using level sets method from nuclei to membrane. Uses an implementation of Level set method. See: https://wiseodd.github.io/techblog/2016/11/05/levelset-method/ Args: labels (numpy.ndarray): nuclear mask labels img (numpy.ndarray): probability map niter (int): step size to expand mask, number of iterations to run the levelset algorithm dt (float): negative values for porgation, positive values for shrinking thres (float): threshold of probability value to extend the nuclear mask to Returns: cytolabels (numpy.ndarray): cytoplasm mask labels """ from skimage.morphology import closing, disk, remove_small_holes from utils.dlevel_set import dlevel_set phi = labels.copy() phi[labels == 0] = 1 phi[labels > 0] = -1 outlines = img.copy() outlines = -outlines outlines = outlines - outlines.min() outlines = outlines/outlines.max() mask = outlines < thres phi = dlevel_set(phi, outlines, niter=niter, dt=dt, mask=mask) cytolabels = label(remove_small_holes(label(phi < 0))) cytolabels = closing(cytolabels, disk(3)) temp = cytolabels.copy() temp[labels == 0] = 0 cytolabels = convert_labels(temp, labels, cytolabels) return cytolabels
def watershed_divide(labels, regmax=10, min_size=100): """ divide objects in labels with watershed segmentation. regmax: min_size: objects smaller than this size will not be divided. """ from utils.subdetect_utils import watershed_labels large_labels = remove_small_objects(labels, min_size, connectivity=4) labels[large_labels > 0] = 0 ws_large = label(watershed_labels(large_labels, regmax)) ws_large += labels.max() ws_large[ws_large == labels.max()] = 0 return labels + ws_large
def _wd(labels0, labels, img0, img1): labels1 = -labels.copy() rps0 = regionprops(labels0, img0) from subdetect_operation import watershed_divide # DO NOT MOVE IT from utils.track_utils import _find_match untracked_labels = labels1.copy() untracked_labels[untracked_labels < 0] = 0 wshed_labels = watershed_divide(untracked_labels, regmax=REGMAX, min_size=MIN_SIZE) wshed_labels = label(wshed_labels) store = regionprops(wshed_labels, img1) good_cells = _find_match(rps0, store, DISPLACEMENT, MASSTHRES) for gc in good_cells: # needed to reuse _update_labels_neck_cut gccrds = gc.coords[0] gc.raw_label = labels1[gccrds[0], gccrds[1]] labels0, labels = _update_labels_neck_cut(labels0, labels1, good_cells) labels0, labels = nn_closer(img0, img1, labels0, -labels, DISPLACEMENT, MASSTHRES) return labels0, labels, good_cells
def laplacian_levelset(labels, img, NITER=100, CURVE=3, PROP=-1): return label(levelset_lap(img, labels, NITER, CURVE, PROP))