Example #1
0
    def test_clog(self):

        im_nuclei_stain = np.load(
            os.path.join(TEST_DATA_DIR, 'Easy1_nuclei_stain.npy'))

        im_nuclei_fgnd_mask = np.load(
            os.path.join(TEST_DATA_DIR, 'Easy1_nuclei_fgnd_mask.npy'))

        sigma_min = 10.0 / np.sqrt(2.0)
        sigma_max = 40.0 / np.sqrt(2.0)

        im_log_max, im_sigma_max = clog(im_nuclei_stain, im_nuclei_fgnd_mask,
                                        sigma_min, sigma_max)

        im_log_max_gtruth = np.load(
            os.path.join(TEST_DATA_DIR, 'Easy1_clog_max.npy'))

        np.testing.assert_array_almost_equal(im_log_max.astype('float16'),
                                             im_log_max_gtruth,
                                             decimal=4)

        im_sigma_max_gtruth = np.load(
            os.path.join(TEST_DATA_DIR, 'Easy1_clog_sigma_max.npy'))

        np.testing.assert_array_almost_equal(im_sigma_max.astype(np.float16),
                                             im_sigma_max_gtruth,
                                             decimal=4)
Example #2
0
    def test_clog(self):

        im_nuclei_stain_data = np.load(
            os.path.join(TEST_DATA_DIR, 'Easy1_nuclei_stain.npz'))
        im_nuclei_stain = im_nuclei_stain_data['Easy1_nuclei_stain']

        im_nuclei_fgnd_mask_data = np.load(
            os.path.join(TEST_DATA_DIR, 'Easy1_nuclei_fgnd_mask.npz'))
        im_nuclei_fgnd_mask = im_nuclei_fgnd_mask_data[
            'Easy1_nuclei_fgnd_mask']

        sigma_min = 10.0 / np.sqrt(2.0)
        sigma_max = 40.0 / np.sqrt(2.0)

        im_log_max, im_sigma_max = clog(im_nuclei_stain, im_nuclei_fgnd_mask,
                                        sigma_min, sigma_max)

        im_log_max_gtruth_data = np.load(
            os.path.join(TEST_DATA_DIR, 'Easy1_clog_max.npz'))
        im_log_max_gtruth = im_log_max_gtruth_data['Easy1_clog_max']
        assert_array_almost_equal_neighborhood_lines(im_log_max,
                                                     im_log_max_gtruth,
                                                     decimal=4)
        compare_maxima(im_log_max, im_log_max_gtruth)

        im_sigma_max_gtruth_data = np.load(
            os.path.join(TEST_DATA_DIR, 'Easy1_clog_sigma_max.npz'))
        im_sigma_max_gtruth = im_sigma_max_gtruth_data['Easy1_clog_sigma_max']
        assert_array_almost_equal_neighborhood_lines(im_sigma_max,
                                                     im_sigma_max_gtruth,
                                                     decimal=4)
Example #3
0
    def test_clog(self):

        im_nuclei_stain_data = np.load(
            utilities.externaldata('data/Easy1_nuclei_stain.npz.sha512'))
        im_nuclei_stain = im_nuclei_stain_data['Easy1_nuclei_stain']

        im_nuclei_fgnd_mask_data = np.load(
            utilities.externaldata('data/Easy1_nuclei_fgnd_mask.npz.sha512'))
        im_nuclei_fgnd_mask = im_nuclei_fgnd_mask_data['Easy1_nuclei_fgnd_mask']

        sigma_min = 10.0 / np.sqrt(2.0)
        sigma_max = 40.0 / np.sqrt(2.0)

        im_log_max, im_sigma_max = clog(
            im_input=im_nuclei_stain, im_mask=im_nuclei_fgnd_mask,
            sigma_min=sigma_min, sigma_max=sigma_max)

        im_log_max_gtruth_data = np.load(os.path.join(utilities.externaldata(
            'data/Easy1_clog_max.npz.sha512')))
        im_log_max_gtruth = im_log_max_gtruth_data['Easy1_clog_max']
        assert_array_almost_equal_neighborhood_lines(im_log_max, im_log_max_gtruth, decimal=4)
        compare_maxima(im_log_max, im_log_max_gtruth)

        im_sigma_max_gtruth_data = np.load(os.path.join(utilities.externaldata(
            'data/Easy1_clog_sigma_max.npz.sha512')))
        im_sigma_max_gtruth = im_sigma_max_gtruth_data['Easy1_clog_sigma_max']
        assert_array_almost_equal_neighborhood_lines(im_sigma_max, im_sigma_max_gtruth, decimal=4)
Example #4
0
def detect_nuclei_kofahi(im_input, args):

    # perform color normalization
    im_nmzd = htk_cnorm.reinhard(im_input, args.reference_mu_lab,
                                 args.reference_std_lab)

    # perform color decovolution
    w = np.array([
        stain_color_map[args.stain_1], stain_color_map[args.stain_2],
        stain_color_map[args.stain_3]
    ]).T

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

    im_nuclei_stain = im_stains[:, :, 0].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 < args.foreground_threshold)

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

    # apply local maximum clustering
    im_nuclei_seg_mask, seeds, max = htk_seg.nuclear.max_clustering(
        im_log, im_nuclei_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)

    return im_nuclei_seg_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[:, :, 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)
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)
    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
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