cytometer/utils.py
def correct_segmentation(im, seg, correction_model, model_type='-1_1', smoothing=11, batch_size=16):
    """
    Correct histology segmentation using a fully convolutional neural network.

    This methods follows the following steps:
        * Use keras model to estimate which pixels have been underestimated/overestimated in the segmentation, and
          correct segmentation accordingly.
        * Fill holes.
        * Keep only the largest component in each segmentation.
        * Smooth segmentation using binary closing.

    :param im: (n, row, col, 3) np.array with the histology patches.
    :param seg: (n, row, col) np.array with the corresponding segmentation candidates.
    :param correction_model: keras fully convolutional neural network, or file path to it.
    :param model_type: (def '-1_1') How the segmentation and histology are combined for the model. E.g. '-1_1' means
    that outside of the segmentation the histology intensity values are multiplied by -1, and by 1 inside. A list of
    all types can be found in the help for quality_model_mask().
    :param smoothing: (def 11) Size of the smoothing kernel for each corrected segmentation.
    :param batch_size: (def None) Scalar batch_size passed to keras correction model. Maximum number of images processed
    at the same time by the GPUs. A larger number produces faster processing, but it also requires larger GPU memory. If
    batch_size is None, then batch_size is the number of images for the correction model.
    :return:
    * corrected_seg: (n, row, col) Corrected segmentations.
    """

    # if needed, load correction model
    if isinstance(correction_model, six.string_types):
        correction_model = keras.models.load_model(correction_model)

    # adapt model input size to size of image
    correction_model = change_input_size(correction_model, batch_shape=im.shape)

    # correct dimensions
    seg_out = seg.copy()  # to avoid changes by reference to the input segmentation
    if seg_out.ndim == 3:
        seg_out = np.expand_dims(seg_out, axis=3)

    # we assume that black pixels = (0,0,0) belong to outside the image, and we are going to ignore them
    background_mask = np.all(im == 0, axis=3)

    # multiply image by mask
    im = quality_model_mask(seg_out, im=im, quality_model_type=model_type)

    # process (histology * mask) to estimate which pixels are underestimated and which overestimated in the segmentation
    im = correction_model.predict(im, batch_size=batch_size)

    # compute the correction to be applied to the segmentation
    correction = (im[:, :, :, 0].copy() * 0).astype(np.int8)
    correction[im[:, :, :, 0] >= 0.5] = 1  # the segmentation went too far
    correction[im[:, :, :, 0] <= -0.5] = -1  # the segmentation fell short

    # ignore background pixels
    correction[background_mask] = 0

    # correct segmentation
    seg_out[correction == 1] = 0
    seg_out[correction == -1] = 1

    # fill holes, but only image by image
    seg_out = seg_out[:, :, :, 0].astype(np.bool)
    structure = generate_binary_structure(2, 1)  # structure element for 2D
    structure = np.expand_dims(structure, axis=0)  # add dummy dimension
    seg_out = binary_fill_holes(seg_out, structure=structure).astype(np.uint8)

    # keep only the corrected component with the largest overlap with the input segmentation
    for j in range(seg_out.shape[0]):
        # connected components of corrected segmentation
        _, labels_aux, stats_aux, _ = cv2.connectedComponentsWithStats(seg_out[j, :, :], connectivity=4)

        # connected component labels within the input segmentation
        lab, counts = np.unique(labels_aux[seg[j, ...] == 1], return_counts=True)

        # remove background label, if present
        idx = lab != 0
        lab = lab[idx]
        counts = counts[idx]

        if len(counts) > 0:

            # connected component label with maximum overlap with input segmentation
            lab_max = lab[np.argmax(counts)]

            # keep only the connected component with maximum overlap
            seg_out[j, ...] = labels_aux == lab_max

        else:

            seg_out[j, ...] = seg[j, ...]

    # smooth segmentation
    selem = np.ones((smoothing, smoothing))
    for j in range(seg_out.shape[0]):
        seg_out[j, :, :] = binary_closing(seg_out[j, :, :], selem=selem)

    # fill holes, but only image by image
    seg_out = binary_fill_holes(seg_out, structure=structure).astype(np.uint8)

    return seg_out

    Correct histology segmentation using a fully convolutional neural network.

    This methods follows the following steps:
        * Use keras model to estimate which pixels have been underestimated/overestimated in the segmentation, and
          correct segmentation accordingly.
        * Fill holes.
        * Keep only the largest component in each segmentation.
        * Smooth segmentation using binary closing.

    :param im: (n, row, col, 3) np.array with the histology patches.
    :param seg: (n, row, col) np.array with the corresponding segmentation candidates.
    :param correction_model: keras fully convolutional neural network, or file path to it.
    :param model_type: (def '-1_1') How the segmentation and histology are combined for the model. E.g. '-1_1' means
    that outside of the segmentation the histology intensity values are multiplied by -1, and by 1 inside. A list of
    all types can be found in the help for quality_model_mask().
    :param smoothing: (def 11) Size of the smoothing kernel for each corrected segmentation.
    :param batch_size: (def None) Scalar batch_size passed to keras correction model. Maximum number of images processed
    at the same time by the GPUs. A larger number produces faster processing, but it also requires larger GPU memory. If
    batch_size is None, then batch_size is the number of images for the correction model.
    :return:
    * corrected_seg: (n, row, col) Corrected segmentations.
    
Correct histology segmentation using a fully convolutional neural network.
This methods follows the following steps:
Use keras model to estimate which pixels have been underestimated/overestimated in the segmentation, and
correct segmentation accordingly.
Fill holes.
Keep only the largest component in each segmentation.
Smooth segmentation using binary closing.
Correct histology segmentation using a fully convolutional neural network . This methods follows the following steps : Use keras model to estimate which pixels have been underestimated / overestimated in the segmentation and correct segmentation accordingly . Fill holes . Keep only the largest component in each segmentation . Smooth segmentation using binary closing .
def correct_segmentation(im, seg, correction_model, model_type='-1_1', smoothing=11, batch_size=16):
    if isinstance(correction_model, six.string_types):
        correction_model = keras.models.load_model(correction_model)
    correction_model = change_input_size(correction_model, batch_shape=im.shape)
    seg_out = seg.copy()  
    if seg_out.ndim == 3:
        seg_out = np.expand_dims(seg_out, axis=3)
    background_mask = np.all(im == 0, axis=3)
    im = quality_model_mask(seg_out, im=im, quality_model_type=model_type)
    im = correction_model.predict(im, batch_size=batch_size)
    correction = (im[:, :, :, 0].copy() * 0).astype(np.int8)
    correction[im[:, :, :, 0] >= 0.5] = 1  
    correction[im[:, :, :, 0] <= -0.5] = -1  
    correction[background_mask] = 0
    seg_out[correction == 1] = 0
    seg_out[correction == -1] = 1
    seg_out = seg_out[:, :, :, 0].astype(np.bool)
    structure = generate_binary_structure(2, 1)  
    structure = np.expand_dims(structure, axis=0)  
    seg_out = binary_fill_holes(seg_out, structure=structure).astype(np.uint8)
    for j in range(seg_out.shape[0]):
        _, labels_aux, stats_aux, _ = cv2.connectedComponentsWithStats(seg_out[j, :, :], connectivity=4)
        lab, counts = np.unique(labels_aux[seg[j, ...] == 1], return_counts=True)
        idx = lab != 0
        lab = lab[idx]
        counts = counts[idx]
        if len(counts) > 0:
            lab_max = lab[np.argmax(counts)]
            seg_out[j, ...] = labels_aux == lab_max
        else:
            seg_out[j, ...] = seg[j, ...]
    selem = np.ones((smoothing, smoothing))
    for j in range(seg_out.shape[0]):
        seg_out[j, :, :] = binary_closing(seg_out[j, :, :], selem=selem)
    seg_out = binary_fill_holes(seg_out, structure=structure).astype(np.uint8)
    return seg_out
def correct_segmentation ( im , seg , correction_model , model_type = '-1_1' , smoothing = 11 , batch_size = 16 ) : if isinstance ( correction_model , six . string_types ) : correction_model = keras . models . load_model ( correction_model ) correction_model = change_input_size ( correction_model , batch_shape = im . shape ) seg_out = seg . copy ( ) if seg_out . ndim == 3 : seg_out = np . expand_dims ( seg_out , axis = 3 ) background_mask = np . all ( im == 0 , axis = 3 ) im = quality_model_mask ( seg_out , im = im , quality_model_type = model_type ) im = correction_model . predict ( im , batch_size = batch_size ) correction = ( im [ : , : , : , 0 ] . copy ( ) * 0 ) . astype ( np . int8 ) correction [ im [ : , : , : , 0 ] >= 0.5 ] = 1 correction [ im [ : , : , : , 0 ] <= - 0.5 ] = - 1 correction [ background_mask ] = 0 seg_out [ correction == 1 ] = 0 seg_out [ correction == - 1 ] = 1 seg_out = seg_out [ : , : , : , 0 ] . astype ( np . bool ) structure = generate_binary_structure ( 2 , 1 ) structure = np . expand_dims ( structure , axis = 0 ) seg_out = binary_fill_holes ( seg_out , structure = structure ) . astype ( np . uint8 ) for j in range ( seg_out . shape [ 0 ] ) : _ , labels_aux , stats_aux , _ = cv2 . connectedComponentsWithStats ( seg_out [ j , : , : ] , connectivity = 4 ) lab , counts = np . unique ( labels_aux [ seg [ j , ... ] == 1 ] , return_counts = True ) idx = lab != 0 lab = lab [ idx ] counts = counts [ idx ] if len ( counts ) > 0 : lab_max = lab [ np . argmax ( counts ) ] seg_out [ j , ... ] = labels_aux == lab_max else : seg_out [ j , ... ] = seg [ j , ... ] selem = np . ones ( ( smoothing , smoothing ) ) for j in range ( seg_out . shape [ 0 ] ) : seg_out [ j , : , : ] = binary_closing ( seg_out [ j , : , : ] , selem = selem ) seg_out = binary_fill_holes ( seg_out , structure = structure ) . astype ( np . uint8 ) return seg_out
Correct histology segmentation using a fully convolutional neural network.
Correct histology segmentation using a fully convolutional neural network .
"""
    Correct histology segmentation using a fully convolutional neural network.

    This methods follows the following steps:
        * Use keras model to estimate which pixels have been underestimated/overestimated in the segmentation, and
          correct segmentation accordingly.
        * Fill holes.
        * Keep only the largest component in each segmentation.
        * Smooth segmentation using binary closing.

    :param im: (n, row, col, 3) np.array with the histology patches.
    :param seg: (n, row, col) np.array with the corresponding segmentation candidates.
    :param correction_model: keras fully convolutional neural network, or file path to it.
    :param model_type: (def '-1_1') How the segmentation and histology are combined for the model. E.g. '-1_1' means
    that outside of the segmentation the histology intensity values are multiplied by -1, and by 1 inside. A list of
    all types can be found in the help for quality_model_mask().
    :param smoothing: (def 11) Size of the smoothing kernel for each corrected segmentation.
    :param batch_size: (def None) Scalar batch_size passed to keras correction model. Maximum number of images processed
    at the same time by the GPUs. A larger number produces faster processing, but it also requires larger GPU memory. If
    batch_size is None, then batch_size is the number of images for the correction model.
    :return:
    * corrected_seg: (n, row, col) Corrected segmentations.
    """ # if needed, load correction model # adapt model input size to size of image # correct dimensions # to avoid changes by reference to the input segmentation # we assume that black pixels = (0,0,0) belong to outside the image, and we are going to ignore them # multiply image by mask # process (histology * mask) to estimate which pixels are underestimated and which overestimated in the segmentation # compute the correction to be applied to the segmentation # the segmentation went too far # the segmentation fell short # ignore background pixels # correct segmentation # fill holes, but only image by image # structure element for 2D # add dummy dimension # keep only the corrected component with the largest overlap with the input segmentation # connected components of corrected segmentation # connected component labels within the input segmentation # remove background label, if present # connected component label with maximum overlap with input segmentation # keep only the connected component with maximum overlap # smooth segmentation # fill holes, but only image by image
(n, row, col) Corrected segmentations.
( n row col ) Corrected segmentations .
im
(n, row, col, 3) np.array with the histology patches.
( n row col 3 ) np . array with the histology patches .
seg
(n, row, col) np.array with the corresponding segmentation candidates.
( n row col ) np . array with the corresponding segmentation candidates .
correction_model
keras fully convolutional neural network, or file path to it.
keras fully convolutional neural network or file path to it .
model_type
(def '-1_1') How the segmentation and histology are combined for the model. E.g. '-1_1' means
that outside of the segmentation the histology intensity values are multiplied by -1, and by 1 inside. A list of
all types can be found in the help for quality_model_mask().
( def ' - 1_1 ' ) How the segmentation and histology are combined for the model . E . g . ' - 1_1 ' means that outside of the segmentation the histology intensity values are multiplied by - 1 and by 1 inside . A list of all types can be found in the help for quality_model_mask () .
smoothing
(def 11) Size of the smoothing kernel for each corrected segmentation.
( def 11 ) Size of the smoothing kernel for each corrected segmentation .
batch_size
(def None) Scalar batch_size passed to keras correction model. Maximum number of images processed
at the same time by the GPUs. A larger number produces faster processing, but it also requires larger GPU memory. If
batch_size is None, then batch_size is the number of images for the correction model.
( def None ) Scalar batch_size passed to keras correction model . Maximum number of images processed at the same time by the GPUs . A larger number produces faster processing but it also requires larger GPU memory . If batch_size is None then batch_size is the number of images for the correction model .