def set_color_normalization_target(self,
                                       ref_image_path,
                                       color_normalization_method='macenko_pca'
                                       ):
        """Set color normalization values to use from target image.

        Arguments
        ref_image_path, str
        >    path to target (reference) image
        color_normalization_method, str
        >    color normalization method to use. Currently, only
        >    reinhard and macenko_pca are accepted.

        """
        # read input image
        ref_im = np.array(imread(ref_image_path, pilmode='RGB'))

        # assign target values

        color_normalization_method = color_normalization_method.lower()

        if color_normalization_method == 'reinhard':
            mu, sigma = lab_mean_std(ref_im)
            self.target_stats_reinhard['mu'] = mu
            self.target_stats_reinhard['sigma'] = sigma

        elif color_normalization_method == 'macenko_pca':
            self.target_W_macenko = _reorder_stains(
                rgb_separate_stains_macenko_pca(ref_im, I_0=None),
                stains=['hematoxylin', 'eosin'])
        else:
            raise ValueError("Unknown color_normalization_method: %s" %
                             (color_normalization_method))

        self.color_normalization_method = color_normalization_method
Пример #2
0
def reinhard_stats(slide_path, sample_fraction, magnification=None):
    """Samples a whole-slide-image to determine colorspace statistics (mean,
    variance) needed to perform global Reinhard color normalization.

    Normalizing individual tiles independently creates a significant bias
    in the results of segmentation and feature extraction, as the color
    statistics of each tile in a whole-slide image can vary significantly.
    To remedy this, we sample a subset of pixels from the entire whole-slide
    image in order to estimate the global mean and standard deviation of
    each channel in the Lab color space that are needed for reinhard color
    normalization.

    Parameters
    ----------
    slide_path : str
        path and filename of slide.
    sample_fraction : double
       Fraction of pixels to sample (range (0, 1]).
    magnification : scalar
        Desired magnification for sampling. Defaults to native scan
        magnification.

    Returns
    -------
    Mu : array_like
        A 3-element array containing the means of the target image channels
        in sample_pix_lab color space.
    Sigma : array_like
        A 3-element list containing the standard deviations of the target image
        channels in sample_pix_lab color space.

    Notes
    -----
    Returns a namedtuple.

    See Also
    --------
    histomicstk.preprocessing.color_conversion.lab_mean_std
    histomicstk.preprocessing.color_normalization.reinhard

    """

    # generate a sampling of sample_pixels_rgb pixels from whole-slide image
    sample_pixels_rgb = sample_pixels(slide_path, sample_fraction,
                                      magnification)

    # reshape the Nx3 pixel array into a 1 x N x 3 image for lab_mean_std
    sample_pixels_rgb = np.reshape(sample_pixels_rgb,
                                   (1, sample_pixels_rgb.shape[0], 3))

    # compute mean and stddev of sample pixels in Lab space
    Mu, Sigma = color_conversion.lab_mean_std(sample_pixels_rgb)

    # build named tuple for output
    ReinhardStats = collections.namedtuple('ReinhardStats', ['Mu', 'Sigma'])
    stats = ReinhardStats(Mu, Sigma)

    return stats
def reinhard_stats(slide_path, magnification, sample_percent):
    """Samples a whole-slide-image to determine colorspace statistics (mean,
    variance) needed to perform global Reinhard color normalization.

    Normalizing individual tiles independently creates a significant bias
    in the results of segmentation and feature extraction, as the color
    statistics of each tile in a whole-slide image can vary significantly.
    To remedy this, we sample a subset of pixels from the entire whole-slide
    image in order to estimate the global mean and standard deviation of
    each channel in the Lab color space that are needed for reinhard color
    normalization.

    Parameters
    ----------
    slide_path : str
        path and filename of slide.
    magnification : scalar
        Desired magnification for sampling. Defaults to native scan
        magnification.
    sample_percent : double
       Percentage of pixels to sample (range (0, 1]).

    Returns
    -------
    Mu : array_like
        A 3-element array containing the means of the target image channels
        in sample_pix_lab color space.
    Sigma : array_like
        A 3-element list containing the standard deviations of the target image
        channels in sample_pix_lab color space.

    Notes
    -----
    Returns a namedtuple.

    See Also
    --------
    histomicstk.preprocessing.color_conversion.lab_mean_std
    histomicstk.preprocessing.color_normalization.reinhard
    """

    # generate a sampling of sample_pixels_rgb pixels from whole-slide image
    sample_pixels_rgb = sample_pixels(slide_path, magnification,
                                      sample_percent)

    # reshape the Nx3 pixel array into a 1 x N x 3 image for lab_mean_std
    sample_pixels_rgb = np.reshape(sample_pixels_rgb,
                                   (1, sample_pixels_rgb.shape[0], 3))

    # compute mean and stddev of sample pixels in Lab space
    Mu, Sigma = color_conversion.lab_mean_std(sample_pixels_rgb)

    # build named tuple for output
    ReinhardStats = collections.namedtuple('ReinhardStats', ['Mu', 'Sigma'])
    stats = ReinhardStats(Mu, Sigma)

    return stats
Пример #4
0
    def set_color_normalization_values(
            self, mu=None, sigma=None, ref_image_path=None, what='main'):
        """Set color normalization values for thumbnail or main image."""
        assert (
            all([j is not None for j in (mu, sigma)])
            or ref_image_path is not None), \
            "You must provide mu & sigma values or ref. image to get them."
        assert what in ('thumbnail', 'main')

        if ref_image_path is not None:
            ref_im = np.array(imread(ref_image_path, pilmode='RGB'))
            mu, sigma = lab_mean_std(ref_im)

        self.cnorm_params[what] = {'mu': mu, 'sigma': sigma}
    def test_normalization(self):

        input_image_file = os.path.join(TEST_DATA_DIR, 'L1.png')

        ref_image_file = os.path.join(TEST_DATA_DIR, 'Easy1.png')

        # read input image
        im_input = skimage.io.imread(input_image_file)[:, :, :3]

        # read reference image
        im_reference = skimage.io.imread(ref_image_file)[:, :, :3]

        # get mean and stddev of reference image in lab space
        mean_ref, std_ref = htk_cvt.lab_mean_std(im_reference)

        # perform color normalization
        im_nmzd = htk_cn.reinhard(im_input, mean_ref, std_ref)

        # transform normalized image to LAB color space
        mean_nmzd, std_nmzd = htk_cvt.lab_mean_std(im_nmzd)

        # check if mean and stddev of normalized and reference images are equal
        np.testing.assert_allclose(mean_nmzd, mean_ref, atol=1e-1)
        np.testing.assert_allclose(std_nmzd, std_ref, atol=1e-1)
Пример #6
0
    def test_reinhard(self):
        """Test reinhard."""
        # # SANITY CHECK! normalize to LAB mean and std from SAME slide
        # mean_lab, std_lab = lab_mean_std(tissue_rgb)
        # tissue_rgb_normalized = reinhard(
        #     tissue_rgb, target_mu=mean_lab, target_sigma=std_lab)
        # # we expect the images to be (almost) exactly the same
        # assert np.mean(tissue_rgb - tissue_rgb_normalized) < 1

        # color norm. standard (from TCGA-A2-A3XS-DX1, Amgad et al, 2019)
        cnorm = {
            'mu': np.array([8.74108109, -0.12440419, 0.0444982]),
            'sigma': np.array([0.6135447, 0.10989545, 0.0286032]),
        }

        # Normalize to pre-set color standard (unmasked)
        tissue_rgb_normalized = reinhard(cfg.tissue_rgb,
                                         target_mu=cnorm['mu'],
                                         target_sigma=cnorm['sigma'])

        # check that it matches
        mean_lab, std_lab = lab_mean_std(tissue_rgb_normalized)
        assert all(np.abs(mean_lab - cnorm['mu']) < [0.1, 0.1, 0.1])
        assert all(np.abs(std_lab - cnorm['sigma']) < [0.1, 0.1, 0.1])

        # Do MASKED normalization to preset standard
        tissue_rgb_normalized = reinhard(cfg.tissue_rgb,
                                         target_mu=cnorm['mu'],
                                         target_sigma=cnorm['sigma'],
                                         mask_out=cfg.mask_out)

        # check that it matches
        mean_lab, std_lab = lab_mean_std(tissue_rgb_normalized,
                                         mask_out=cfg.mask_out)
        assert all(np.abs(mean_lab - cnorm['mu']) < [0.1, 0.1, 0.1])
        assert all(np.abs(std_lab - cnorm['sigma']) < [0.1, 0.1, 0.1])
    def test_normalization(self):

        input_image_file = os.path.join(TEST_DATA_DIR, 'L1.png')

        ref_image_file = os.path.join(TEST_DATA_DIR, 'Easy1.png')

        # read input image
        im_input = skimage.io.imread(input_image_file)[:, :, :3]

        # read reference image
        im_reference = skimage.io.imread(ref_image_file)[:, :, :3]

        # get mean and stddev of reference image in lab space
        mean_ref, std_ref = htk_cvt.lab_mean_std(im_reference)

        # perform color normalization
        im_nmzd = htk_cn.reinhard(im_input, mean_ref, std_ref)

        # transform normalized image to LAB color space
        mean_nmzd, std_nmzd = htk_cvt.lab_mean_std(im_nmzd)

        # check if mean and stddev of normalized and reference images are equal
        np.testing.assert_allclose(mean_nmzd, mean_ref, atol=1e-1)
        np.testing.assert_allclose(std_nmzd, std_ref, atol=1e-1)
Пример #8
0
    def test_segment_nuclei_kofahi(self):

        input_image_file = datastore.fetch('Easy1.png')

        ref_image_file = datastore.fetch('L1.png')

        # read input image
        im_input = skimage.io.imread(input_image_file)[:, :, :3]

        # read reference image
        im_reference = skimage.io.imread(ref_image_file)[:, :, :3]

        # get mean and stddev of reference image in lab space
        mean_ref, std_ref = htk_cvt.lab_mean_std(im_reference)

        # perform color normalization
        im_nmzd = htk_cnorm.reinhard(im_input, mean_ref, std_ref)

        # perform color decovolution
        stain_color_map = {
            'hematoxylin': [0.65, 0.70, 0.29],
            'eosin': [0.07, 0.99, 0.11],
            'dab': [0.27, 0.57, 0.78],
            'null': [0.0, 0.0, 0.0]
        }

        w = htk_cdeconv.rgb_separate_stains_macenko_pca(im_nmzd, im_nmzd.max())

        im_stains = htk_cdeconv.color_deconvolution(im_nmzd, w).Stains

        nuclei_channel = htk_cdeconv.find_stain_index(
            stain_color_map['hematoxylin'], w)

        im_nuclei_stain = im_stains[:, :, nuclei_channel].astype(np.float)

        # segment nuclei
        im_nuclei_seg_mask = htk_seg.nuclear.detect_nuclei_kofahi(
            im_nuclei_stain,
            im_nuclei_stain < 60,
            min_radius=20,
            max_radius=30,
            min_nucleus_area=80,
            local_max_search_radius=10)

        num_nuclei = len(np.unique(im_nuclei_seg_mask)) - 1

        # check if segmentation mask matches ground truth
        gtruth_mask_file = os.path.join(
            datastore.fetch('Easy1_nuclei_seg_kofahi.npy'))

        im_gtruth_mask = np.load(gtruth_mask_file)

        num_nuclei_gtruth = len(np.unique(im_gtruth_mask)) - 1

        assert num_nuclei == num_nuclei_gtruth

        np.testing.assert_allclose(im_nuclei_seg_mask, im_gtruth_mask)

        # check no nuclei case
        im_nuclei_seg_mask = htk_seg.nuclear.detect_nuclei_kofahi(
            255 * np.ones_like(im_nuclei_stain),
            np.ones_like(im_nuclei_stain),
            min_radius=20,
            max_radius=30,
            min_nucleus_area=80,
            local_max_search_radius=10)

        num_nuclei = len(np.unique(im_nuclei_seg_mask)) - 1

        assert num_nuclei == 0
def main(args):

    #
    # Read Input Image
    #
    print('>> Reading input image')

    imInput = skimage.io.imread(args.inputImageFile)[:, :, :3]

    #
    # Perform color normalization
    #
    print('>> Performing color normalization')

    # compute mean and stddev of input in LAB color space
    Mu, Sigma = htk_color_conversion.lab_mean_std(imInput)

    # perform reinhard normalization
    imNmzd = htk_color_normalization.reinhard(imInput, Mu, Sigma)

    #
    # Perform color deconvolution
    #
    print('>> Performing color deconvolution')

    stainColor_1 = stainColorMap[args.stain_1]
    stainColor_2 = stainColorMap[args.stain_2]
    stainColor_3 = stainColorMap[args.stain_3]

    W = np.array([stainColor_1, stainColor_2, stainColor_3]).T

    imDeconvolved = htk_color_deconvolution.ColorDeconvolution(imNmzd, W)

    imNucleiStain = imDeconvolved.Stains[:, :, 0].astype(np.float)

    #
    # Perform nuclei segmentation
    #
    print('>> Performing nuclei segmentation')

    # segment foreground
    imFgndMask = sp.ndimage.morphology.binary_fill_holes(
        imNucleiStain < args.foreground_threshold)

    # run adaptive multi-scale LoG filter
    imLog = htk_shape_filters.clog(imNucleiStain, imFgndMask,
                                   sigma_min=args.min_radius * np.sqrt(2),
                                   sigma_max=args.max_radius * np.sqrt(2))

    imNucleiSegMask, Seeds, Max = htk_seg.nuclear.max_clustering(
        imLog, imFgndMask, args.local_max_search_radius)

    # filter out small objects
    imNucleiSegMask = htk_seg.label.area_open(
        imNucleiSegMask, args.min_nucleus_area).astype(np.int)

    #
    # Generate annotations
    #
    objProps = skimage.measure.regionprops(imNucleiSegMask)

    print 'Number of nuclei = ', len(objProps)

    # create basic schema
    annotation = {
        "name":          "Nuclei",
        "description":   "Nuclei bounding boxes from a segmentation algorithm",
        "attributes": {
            "algorithm": {
                "color_normalization": "reinhard",
                "color_deconvolution": "ColorDeconvolution",
                "nuclei_segmentation": ["cLOG",
                                        "MaxClustering",
                                        "FilterLabel"]
            }
        },
        "elements": []
    }

    # add each nucleus as an element into the annotation schema
    for i in range(len(objProps)):

        c = [objProps[i].centroid[1], objProps[i].centroid[0], 0]
        width = objProps[i].bbox[3] - objProps[i].bbox[1] + 1
        height = objProps[i].bbox[2] - objProps[i].bbox[0] + 1

        cur_bbox = {
            "type":        "rectangle",
            "center":      c,
            "width":       width,
            "height":      height,
            "rotation":    0,
            "fillColor":   "rgba(255, 255, 255, 0)",
            "lineWidth":   2,
            "lineColor":   "rgb(34, 139, 34)"
        }

        annotation["elements"].append(cur_bbox)

    #
    # Save output segmentation mask
    #
    print('>> Outputting nuclei segmentation mask')

    skimage.io.imsave(args.outputNucleiMaskFile, imNucleiSegMask)

    #
    # Save output annotation
    #
    print('>> Outputting nuclei annotation')

    with open(args.outputNucleiAnnotationFile, 'w') as annotationFile:
        json.dump(annotation, annotationFile, indent=2, sort_keys=False)
Пример #10
0
def main(args):

    #
    # Read Input Image
    #
    print('>> Reading input image')

    im_input = skimage.io.imread(args.inputImageFile)[:, :, :3]

    #
    # Perform color normalization
    #
    print('>> Performing color normalization')

    # compute mean and stddev of input in LAB color space
    mu, sigma = htk_ccvt.lab_mean_std(im_input)

    # perform reinhard normalization
    im_nmzd = htk_cnorm.reinhard(im_input, mu, sigma)

    #
    # Perform color deconvolution
    #
    print('>> Performing color deconvolution')

    stain_color_1 = stain_color_map[args.stain_1]
    stain_color_2 = stain_color_map[args.stain_2]
    stain_color_3 = stain_color_map[args.stain_3]

    w = np.array([stain_color_1, stain_color_2, stain_color_3]).T

    im_stains = htk_cdeconv.color_deconvolution(im_nmzd, w).Stains

    im_nuclei_stain = im_stains[:, :, 0].astype(np.float)

    #
    # Perform nuclei segmentation
    #
    print('>> Performing nuclei segmentation')

    # segment foreground
    im_fgnd_mask = sp.ndimage.morphology.binary_fill_holes(
        im_nuclei_stain < args.foreground_threshold)

    # run adaptive multi-scale LoG filter
    im_log = htk_shape_filters.clog(im_nuclei_stain, im_fgnd_mask,
                                    sigma_min=args.min_radius * np.sqrt(2),
                                    sigma_max=args.max_radius * np.sqrt(2))

    im_nuclei_seg_mask, seeds, max = htk_seg.nuclear.max_clustering(
        im_log, im_fgnd_mask, args.local_max_search_radius)

    # filter out small objects
    im_nuclei_seg_mask = htk_seg.label.area_open(
        im_nuclei_seg_mask, args.min_nucleus_area).astype(np.int)

    #
    # Generate annotations
    #
    obj_props = skimage.measure.regionprops(im_nuclei_seg_mask)

    print 'Number of nuclei = ', len(obj_props)

    # create basic schema
    annotation = {
        "name":          "Nuclei",
        "description":   "Nuclei bounding boxes from a segmentation algorithm",
        "attributes": {
            "algorithm": {
                "color_normalization": "reinhard",
                "color_deconvolution": "ColorDeconvolution",
                "nuclei_segmentation": ["cLOG",
                                        "MaxClustering",
                                        "FilterLabel"]
            }
        },
        "elements": []
    }

    # add each nucleus as an element into the annotation schema
    for i in range(len(obj_props)):

        c = [obj_props[i].centroid[1], obj_props[i].centroid[0], 0]
        width = obj_props[i].bbox[3] - obj_props[i].bbox[1] + 1
        height = obj_props[i].bbox[2] - obj_props[i].bbox[0] + 1

        cur_bbox = {
            "type":        "rectangle",
            "center":      c,
            "width":       width,
            "height":      height,
            "rotation":    0,
            "fillColor":   "rgba(255, 255, 255, 0)",
            "lineWidth":   2,
            "lineColor":   "rgb(34, 139, 34)"
        }

        annotation["elements"].append(cur_bbox)

    #
    # Save output segmentation mask
    #
    print('>> Outputting nuclei segmentation mask')

    skimage.io.imsave(args.outputNucleiMaskFile, im_nuclei_seg_mask)

    #
    # Save output annotation
    #
    print('>> Outputting nuclei annotation')

    with open(args.outputNucleiAnnotationFile, 'w') as annotation_file:
        json.dump(annotation, annotation_file, indent=2, sort_keys=False)
Пример #11
0
    def test_reinhard(self):
        """Test reinhard."""
        # get RGB image at a small magnification
        slide_info = gc.get('item/%s/tiles' % SAMPLE_SLIDE_ID)
        getStr = "/item/%s/tiles/region?left=%d&right=%d&top=%d&bottom=%d" % (
            SAMPLE_SLIDE_ID, 0, slide_info['sizeX'], 0, slide_info['sizeY']
            ) + "&magnification=%.2f" % MAG
        tissue_rgb = get_image_from_htk_response(
            gc.get(getStr, jsonResp=False))

        # # SANITY CHECK! normalize to LAB mean and std from SAME slide
        # mean_lab, std_lab = lab_mean_std(tissue_rgb)
        # tissue_rgb_normalized = reinhard(
        #     tissue_rgb, target_mu=mean_lab, target_sigma=std_lab)
        #
        # # we expect the images to be (almost) exactly the same
        # assert np.mean(tissue_rgb - tissue_rgb_normalized) < 1

        # Normalize to pre-set color standard
        tissue_rgb_normalized = reinhard(
            tissue_rgb, target_mu=cnorm['mu'], target_sigma=cnorm['sigma'])

        # check that it matches
        mean_lab, std_lab = lab_mean_std(tissue_rgb_normalized)
        self.assertTrue(all(
            np.abs(mean_lab - cnorm['mu']) < [0.1, 0.1, 0.1]))
        self.assertTrue(all(
            np.abs(std_lab - cnorm['sigma']) < [0.1, 0.1, 0.1]))

        # get tissue mask
        thumbnail_rgb = get_slide_thumbnail(gc, SAMPLE_SLIDE_ID)
        labeled, mask = get_tissue_mask(
            thumbnail_rgb, deconvolve_first=True,
            n_thresholding_steps=1, sigma=1.5, min_size=30)

        # # visualize result
        # vals = np.random.rand(256, 3)
        # vals[0, ...] = [0.9, 0.9, 0.9]
        # cMap = ListedColormap(1 - vals)
        #
        # f, ax = plt.subplots(1, 3, figsize=(20, 20))
        # ax[0].imshow(thumbnail_rgb)
        # ax[1].imshow(labeled, cmap=cMap)
        # ax[2].imshow(mask, cmap=cMap)
        # plt.show()

        # Do MASKED normalization to preset standard
        mask_out = resize(
            labeled == 0, output_shape=tissue_rgb.shape[:2],
            order=0, preserve_range=True) == 1
        tissue_rgb_normalized = reinhard(
            tissue_rgb, target_mu=cnorm['mu'], target_sigma=cnorm['sigma'],
            mask_out=mask_out)

        # check that it matches
        mean_lab, std_lab = lab_mean_std(
            tissue_rgb_normalized, mask_out=mask_out)
        self.assertTrue(all(
            np.abs(mean_lab - cnorm['mu']) < [0.1, 0.1, 0.1]))
        self.assertTrue(all(
            np.abs(std_lab - cnorm['sigma']) < [0.1, 0.1, 0.1]))
    def test_segment_nuclei_kofahi(self):

        input_image_file = os.path.join(TEST_DATA_DIR, 'Easy1.png')

        ref_image_file = os.path.join(TEST_DATA_DIR, 'L1.png')

        # read input image
        im_input = skimage.io.imread(input_image_file)[:, :, :3]

        # read reference image
        im_reference = skimage.io.imread(ref_image_file)[:, :, :3]

        # get mean and stddev of reference image in lab space
        mean_ref, std_ref = htk_cvt.lab_mean_std(im_reference)

        # perform color normalization
        im_nmzd = htk_cnorm.reinhard(im_input, mean_ref, std_ref)

        # perform color decovolution
        stain_color_map = {
            'hematoxylin': [0.65, 0.70, 0.29],
            'eosin': [0.07, 0.99, 0.11],
            'dab': [0.27, 0.57, 0.78],
            'null': [0.0, 0.0, 0.0]
        }

        w = htk_cdeconv.rgb_separate_stains_macenko_pca(im_nmzd, im_nmzd.max())

        im_stains = htk_cdeconv.color_deconvolution(im_nmzd, w).Stains

        nuclei_channel = htk_cdeconv.find_stain_index(stain_color_map['hematoxylin'], w)

        im_nuclei_stain = im_stains[:, :, nuclei_channel].astype(np.float)

        # segment foreground (assumes nuclei are darker on a bright background)
        im_nuclei_fgnd_mask = sp.ndimage.morphology.binary_fill_holes(
            im_nuclei_stain < 60)

        # run adaptive multi-scale LoG filter
        im_log, im_sigma_max = htk_shape_filters.clog(
            im_nuclei_stain, im_nuclei_fgnd_mask,
            sigma_min=20 / np.sqrt(2), sigma_max=30 / np.sqrt(2))

        # apply local maximum clustering
        im_nuclei_seg_mask, seeds, maxima = htk_seg.nuclear.max_clustering(
            im_log, im_nuclei_fgnd_mask, 10)

        # filter out small objects
        im_nuclei_seg_mask = htk_seg.label.area_open(
            im_nuclei_seg_mask, 80).astype(np.uint8)

        # perform connected component analysis
        obj_props = skimage.measure.regionprops(im_nuclei_seg_mask)

        num_nuclei = len(obj_props)

        # check if segmentation mask matches ground truth
        gtruth_mask_file = os.path.join(TEST_DATA_DIR,
                                        'Easy1_nuclei_seg_kofahi_adaptive.npy')

        im_gtruth_mask = np.load(gtruth_mask_file)

        obj_props_gtruth = skimage.measure.regionprops(im_gtruth_mask)

        num_nuclei_gtruth = len(obj_props_gtruth)

        assert(num_nuclei == num_nuclei_gtruth)

        np.testing.assert_allclose(im_nuclei_seg_mask, im_gtruth_mask)
def main(args):

    #
    # Read Input Image
    #
    print('>> Reading input image')

    imInput = skimage.io.imread(args.inputImageFile)[:, :, :3]

    #
    # Perform color normalization
    #
    print('>> Performing color normalization')

    # compute mean and stddev of input in LAB color space
    Mu, Sigma = htk_color_conversion.lab_mean_std(imInput)

    # perform reinhard normalization
    imNmzd = htk_color_normalization.reinhard(imInput, Mu, Sigma)

    #
    # Perform color deconvolution
    #
    print('>> Performing color deconvolution')

    stainColor_1 = stainColorMap[args.stain_1]
    stainColor_2 = stainColorMap[args.stain_2]
    stainColor_3 = stainColorMap[args.stain_3]

    W = np.array([stainColor_1, stainColor_2, stainColor_3]).T

    imDeconvolved = htk_color_deconvolution.ColorDeconvolution(imNmzd, W)

    imNucleiStain = imDeconvolved.Stains[::2, ::2, 0].astype(np.float)

    #
    # Perform nuclei segmentation
    #
    print('>> Performing nuclei segmentation')

    # segment foreground
    imFgndMask = sp.ndimage.morphology.binary_fill_holes(
        imNucleiStain < args.foreground_threshold)

    # run adaptive multi-scale LoG filter
    imLog = htk_shape_filters.clog(imNucleiStain, imFgndMask,
                                   sigma_min=args.min_radius * np.sqrt(2),
                                   sigma_max=args.max_radius * np.sqrt(2))

    imNucleiSegMask, Seeds, Max = htk_seg.nuclear.max_clustering(
        imLog, imFgndMask, args.local_max_search_radius)

    # filter out small objects
    imNucleiSegMask = htk_seg.label.area_open(
        imNucleiSegMask, args.min_nucleus_area).astype(np.int)

    #
    # Perform feature extraction
    #
    print('>> Performing feature extraction')

    im_nuclei = imDeconvolved.Stains[::2, ::2, 0]

    if args.cytoplasm_features:
        im_cytoplasm = imDeconvolved.Stains[::2, ::2, 1]
    else:
        im_cytoplasm = None

    df = htk_features.ComputeNucleiFeatures(
        imNucleiSegMask, im_nuclei, im_cytoplasm,
        fsd_bnd_pts=args.fsd_bnd_pts,
        fsd_freq_bins=args.fsd_freq_bins,
        cyto_width=args.cyto_width,
        num_glcm_levels=args.num_glcm_levels,
        morphometry_features_flag=args.morphometry_features,
        fsd_features_flag=args.fsd_features,
        intensity_features_flag=args.intensity_features,
        gradient_features_flag=args.gradient_features,
    )

    #
    # Create HDF5 file
    #
    print('>> Writing HDF5 file')

    hdf = pd.HDFStore(args.outputFile)
    hdf.put('d1', df, format='table', data_columns=True)

    print '--- Object x Features = ', hdf['d1'].shape
Пример #14
0
def main(args):

    #
    # Read Input Image
    #
    print('>> Reading input image')

    im_input = skimage.io.imread(args.inputImageFile)[:, :, :3]

    #
    # Perform color normalization
    #
    print('>> Performing color normalization')

    # compute mean and stddev of input in LAB color space
    mu, sigma = htk_ccvt.lab_mean_std(im_input)

    # perform reinhard normalization
    im_nmzd = htk_cnorm.reinhard(im_input, mu, sigma)

    #
    # Perform color deconvolution
    #
    print('>> Performing color deconvolution')

    stain_color_1 = stain_color_map[args.stain_1]
    stain_color_2 = stain_color_map[args.stain_2]
    stain_color_3 = stain_color_map[args.stain_3]

    w = np.array([stain_color_1, stain_color_2, stain_color_3]).T

    im_stains = htk_cdeconv.color_deconvolution(im_nmzd, w).Stains

    im_nuclei_stain = im_stains[:, :, 0].astype(np.float)

    #
    # Perform nuclei segmentation
    #
    print('>> Performing nuclei segmentation')

    # segment foreground
    im_fgnd_mask = sp.ndimage.morphology.binary_fill_holes(
        im_nuclei_stain < args.foreground_threshold)

    # run adaptive multi-scale LoG filter
    im_log = htk_shape_filters.clog(im_nuclei_stain,
                                    im_fgnd_mask,
                                    sigma_min=args.min_radius * np.sqrt(2),
                                    sigma_max=args.max_radius * np.sqrt(2))

    im_nuclei_seg_mask, seeds, max = htk_seg.nuclear.max_clustering(
        im_log, im_fgnd_mask, args.local_max_search_radius)

    # filter out small objects
    im_nuclei_seg_mask = htk_seg.label.area_open(
        im_nuclei_seg_mask, args.min_nucleus_area).astype(np.int)

    #
    # Perform feature extraction
    #
    print('>> Performing feature extraction')

    im_nuclei = im_stains[:, :, 0]

    if args.cytoplasm_features:
        im_cytoplasm = im_stains[:, :, 1]
    else:
        im_cytoplasm = None

    df = htk_features.ComputeNucleiFeatures(
        im_nuclei_seg_mask,
        im_nuclei,
        im_cytoplasm,
        fsd_bnd_pts=args.fsd_bnd_pts,
        fsd_freq_bins=args.fsd_freq_bins,
        cyto_width=args.cyto_width,
        num_glcm_levels=args.num_glcm_levels,
        morphometry_features_flag=args.morphometry_features,
        fsd_features_flag=args.fsd_features,
        intensity_features_flag=args.intensity_features,
        gradient_features_flag=args.gradient_features,
    )

    #
    # Create HDF5 file
    #
    print('>> Writing HDF5 file')

    hdf = pd.HDFStore(args.outputFile)
    hdf.put('d1', df, format='table', data_columns=True)

    print '--- Object x Features = ', hdf['d1'].shape