Пример #1
0
def segment_image(plate_image: ndarray,
                  plate_mask: ndarray = None,
                  plate_noise_mask: ndarray = None,
                  area_min: float = 1) -> ndarray:
    """
    Attempts to separate and label all colonies on a plate

    :param plate_image: an image containing colonies
    :param plate_mask: a boolean image mask to remove from the original image
    :param plate_noise_mask: a black and white image as a numpy array
    :param area_min: the minimum area for a colony, in pixels
    :returns: a segmented and labelled image as a numpy array
    """
    from numpy import unique, isin
    from skimage.measure import regionprops, label
    from skimage.morphology import remove_small_objects, binary_erosion
    from skimage.segmentation import clear_border

    plate_image = imaging.remove_background_mask(plate_image, smoothing=0.5)

    if plate_mask is not None:
        # Remove mask from image
        plate_image = plate_image & plate_mask
        # Remove objects touching the mask border
        plate_image = clear_border(plate_image,
                                   bgval=0,
                                   mask=binary_erosion(plate_mask))
    else:
        # Remove objects touching the image border
        plate_image = clear_border(plate_image, buffer_size=2, bgval=0)

    plate_image = label(plate_image, connectivity=2)

    # Remove background noise
    if len(unique(plate_image)) > 1:
        plate_image = remove_small_objects(plate_image, min_size=area_min)

    # Remove colonies that have grown on top of image artefacts or static objects
    if plate_noise_mask is not None:
        plate_noise_image = imaging.remove_background_mask(plate_noise_mask,
                                                           smoothing=0.5)
        if len(unique(plate_noise_mask)) > 1:
            noise_mask = remove_small_objects(plate_noise_image,
                                              min_size=area_min)
        # Remove all objects where there is an existing static object
        exclusion = unique(plate_image[noise_mask])
        exclusion_mask = isin(plate_image, exclusion[exclusion > 0])
        plate_image[exclusion_mask] = 0

    return plate_image
Пример #2
0
def segment_image(plate_image, plate_mask, plate_noise_mask, area_min = 5):
    """
    Finds all colonies on a plate and returns an array of co-ordinates

    If a co-ordinate is occupied by a colony, it contains that colonies labelled number

    :param plate_image: a black and white image as a numpy array
    :param mask: a black and white image as a numpy array
    :param plate_noise_mask: a black and white image as a numpy array
    :returns: a segmented and labelled image as a numpy array
    """
    from math import pi
    from scipy.ndimage.morphology import binary_fill_holes
    from skimage.morphology import remove_small_objects
    from skimage.measure import regionprops, label

    plate_image = imaging.remove_background_mask(plate_image, plate_mask)
    plate_noise_mask = imaging.remove_background_mask(plate_noise_mask, plate_mask)

    # Subtract an image of the first (i.e. empty) plate to remove static noise
    plate_image[plate_noise_mask] = 0

    # Fill any small gaps
    plate_image = binary_fill_holes(plate_image)

    # Remove background noise
    plate_image = remove_small_objects(plate_image, min_size = area_min)

    colonies = label(plate_image)

    # Remove colonies that are on the edge of the plate
    # versions <0.16 do not allow for a mask
    # colonies = clear_border(pl_th, buffer_size = 1, mask = plate_mask)

    # Exclude objects that are too eccentric
    rps = regionprops(colonies)
    for rp in rps:
        # Eccentricity of zero is a perfect circle
        # Circularity of 1 is a perfect circle
        circularity = (4 * pi * rp.area) / (rp.perimeter * rp.perimeter)

        if rp.eccentricity > 0.6 or circularity < 0.85:
            colonies[colonies == rp.label] = 0

    return colonies
Пример #3
0
    def test_remove_background(self, image_segmented_local, image_mask):
        image_ref = np.array([[0, 0, 0, 0, 0, 0, 0, 0, 0],
                              [0, 0, 0, 0, 1, 0, 0, 0, 0],
                              [0, 0, 0, 1, 0, 1, 0, 0, 0],
                              [0, 0, 0, 1, 1, 1, 1, 0, 0],
                              [0, 1, 1, 0, 1, 1, 1, 1, 0],
                              [0, 0, 0, 0, 0, 0, 0, 0, 0],
                              [0, 0, 0, 0, 0, 0, 0, 0, 0],
                              [0, 0, 0, 0, 0, 0, 0, 0, 0]])

        result = remove_background_mask(image_segmented_local, image_mask)

        assert result.shape == image_segmented_local.shape
        assert (result == image_ref).all()
Пример #4
0
 def test_mask_empty(self, image_segmented_local):
     with pytest.raises(ValueError):
         remove_background_mask(image_segmented_local, np.array([]))
Пример #5
0
 def test_image_empty(self, image_mask):
     with pytest.raises(ValueError):
         remove_background_mask(np.array([]), image_mask)
Пример #6
0
 def test_image_blank(self):
     image_blank = np.zeros((3, 3))
     result = remove_background_mask(image_blank, image_blank > 0)
     assert (result == image_blank).all()
Пример #7
0
 def test_size_mismatch(self):
     with pytest.raises(ValueError):
         remove_background_mask(np.ones((5, 5), dtype=np.uint8),
                                np.ones((3, 5), dtype=np.uint8))