def find_angle(image): image = equalize_adaptive_clahe(image) image = threshold_otsu(image) image = erosion_binary(image, selem=skimage.morphology.disk(3)) image = remove_small_objects(image, min_size=5000) segmentation = connected_components(image, background=0) properties = skimage.measure.regionprops(segmentation) angles = [p["orientation"] for p in properties] return sum(angles) / len(angles)
def create_mask(image): """Return a mask for the region of interest.""" selem = skimage.morphology.disk(2) im = equalize_adaptive_clahe(image) im = threshold_otsu(im) im = erosion_binary(im, selem) mask = np.ones(im.shape, dtype=bool) segmentation = connected_components(im, background=0) for i in segmentation.identifiers: region = segmentation.region_by_identifier(i) if region.area > 5000: mask[np.where(region.convex_hull)] = False return Image.from_array(mask)
def segment(image): """Return a segmented image and rotation angle.""" angle = find_angle(image) image = rotate(image, angle) mask = create_mask(image) watershed_mask = equalize_adaptive_clahe(image) watershed_mask = smooth_gaussian(watershed_mask, sigma=(1, 0)) watershed_mask = threshold_otsu(watershed_mask) watershed_mask = apply_mask(watershed_mask, mask) n = 20 selem = np.array([0, 1, 0] * n).reshape((n, 3)) seeds = erosion_binary(watershed_mask, selem=selem) seeds = apply_mask(seeds, vertical_cuts(watershed_mask)) seeds = remove_small_objects(seeds) seeds = connected_components(seeds, connectivity=1, background=0) segmentation = watershed_with_seeds(image, seeds, mask=watershed_mask) segmentation = remove_cells_touching_border(segmentation, image) segmentation = remove_cells_touching_border(segmentation, mask) segmentation = remove_tilted_cells(segmentation) return segmentation, angle