コード例 #1
0
def rgb_perturb_stain_concentration(im_rgb,
                                    stain_unmixing_routine_params=None,
                                    **kwargs):
    """Apply wrapper that calls perturb_stain_concentration() on RGB.

    Parameters
    ------------
    im_rgb : array_like
        An RGB image (m x n x 3) to color normalize

    stain_unmixing_routine_params : dict
        kwargs to pass as-is to the color_deconvolution_routine().

    kwargs : k,v pairs
        Passed as-is to perturb_stain_concentration()

    Returns
    --------
    array_like
        Color augmented RGB image (m x n x 3)

    """
    stain_unmixing_routine_params = {
        'stains': ['hematoxylin', 'eosin'],
        'stain_unmixing_method': 'macenko_pca',
    } if stain_unmixing_routine_params is None else stain_unmixing_routine_params

    _, StainsFloat, W_source = color_deconvolution_routine(
        im_rgb, W_source=None, **stain_unmixing_routine_params)

    return perturb_stain_concentration(StainsFloat, W_source, **kwargs)
コード例 #2
0
    def find_potentially_cellular_regions(self):
        """Find regions that are potentially cellular."""
        mask_out = self.labeled != self.cdt.GTcodes.loc["not_specified",
                                                        "GT_code"]

        # deconvolvve to ge hematoxylin channel (cellular areas)
        # hematoxylin channel return shows MINIMA so we invert
        self.tissue_htx, _, _ = color_deconvolution_routine(
            self.tissue_rgb,
            mask_out=mask_out,
            **self.cdt.stain_unmixing_routine_params)
        self.tissue_htx = 255 - self.tissue_htx[..., 0]

        # get cellular regions by threshold HTX stain channel
        self.maybe_cellular, _ = get_tissue_mask(
            self.tissue_htx.copy(),
            deconvolve_first=False,
            n_thresholding_steps=1,
            sigma=self.cdt.cellular_step1_sigma,
            min_size=self.cdt.cellular_step1_min_size)

        # Second, low-pass filter to dilate and smooth a bit
        self.maybe_cellular = gaussian(0 + (self.maybe_cellular > 0),
                                       sigma=self.cdt.cellular_step2_sigma,
                                       output=None,
                                       mode='nearest',
                                       preserve_range=True)

        # find connected components
        self.maybe_cellular, _ = ndimage.label(self.maybe_cellular)

        # restrict cellular regions to not-otherwise-specified
        self.maybe_cellular[mask_out] = 0

        # assign to mask
        self.labeled[self.maybe_cellular > 0] = self.cdt.GTcodes.loc[
            'maybe_cellular', 'GT_code']
コード例 #3
0
def get_maskrcnn_representations(fold: int,
                                 cfg,
                                 model_root: str,
                                 model_name: str,
                                 savedir: str,
                                 subset='train'):

    assert subset in ['train', 'test']

    # paths
    model_folder = opj(model_root, f'fold_{fold}')
    checkpoint_path = opj(model_folder, f'{model_name}.ckpt')
    p1 = opj(savedir, model_name)
    savepath = opj(p1, f'fold_{fold}_{subset}_FEATS')
    maybe_mkdir(p1)
    maybe_mkdir(savepath)

    # load model
    model = PartialMaskRCNN(**cfg.MaskRCNNConfigs.maskrcnn_params)
    ckpt = load_ckp(checkpoint_path=checkpoint_path, model=model)
    model = ckpt['model']
    model.eval()
    cpu_device = torch.device('cpu')
    model.transform.densify_mask = False

    # prep data loader
    slides = read_csv(opj(
        model_folder, f'fold_{fold}_{subset}.csv')).loc[:,
                                                        'slide_name'].tolist()
    dataset = NucleusDatasetMask(
        root=CoreSetQC.dataset_root,
        dbpath=CoreSetQC.dbpath,
        slides=slides,
        **cfg.MaskDatasetConfigs.test_dataset,
    )
    dataiter = iter(dataset)

    NUCLID = 0

    # go through fovs and fetch features
    nfovs = len(dataset)
    for fovno in range(nfovs):

        print(f'fov {fovno + 1} of {nfovs}')
        overwrite = NUCLID < 1

        # do inference
        imgtensor, target = next(dataiter)
        output = model([imgtensor])
        output = [{k: v.to(cpu_device) for k, v in t.items()} for t in output]
        output = output[0]
        n_nuclei = len(output['labels'])
        nuclidxs = [f'nucls_{i + NUCLID}' for i in range(1, n_nuclei + 1)]

        # metadata about each detection
        nmetas = _parse_nucleus_metas_df(nuclidxs=nuclidxs,
                                         dataset=dataset,
                                         target=target,
                                         output=output)
        nmetas.to_csv(opj(savepath, f'nucleus_metadata.csv'),
                      mode='w' if overwrite else 'a',
                      header=overwrite)

        # save box features (-> box regression)
        #    & cboxfeatures & class_logits (-> classif)
        fdescs = {
            'box_features': 'bfeat',
            'cbox_features': 'cbfeat',
            'clogits': 'clogits'
        }
        for ftype, fdesc in fdescs.items():
            bfeatures = DataFrame(output[ftype].numpy())
            bfeatures.columns = [f'{fdesc}_{i + 1}' for i in bfeatures.columns]
            bfeatures.index = nuclidxs
            bfeatures.to_csv(opj(savepath, f'{ftype}.csv'),
                             mode='w' if overwrite else 'a',
                             header=overwrite)

        # interpretation-friendly features
        rgb = np.uint8(imgtensor * 255.).transpose(1, 2, 0)
        stains, _, _ = color_deconvolution_routine(rgb)
        htx = 255 - stains[..., 0]
        masks = np.uint8(output['masks'].numpy() > 0.5)[:, 0, :, :]
        ifeatures = []
        for nid in range(n_nuclei):
            try:
                fdf = compute_nuclei_features(im_label=masks[nid, ...],
                                              im_nuclei=htx)
                fdf.index = [nuclidxs[nid]]
            except:
                fdf = DataFrame(index=[nuclidxs[nid]])
            ifeatures.append(fdf)
        ifeatures = concat(ifeatures, axis=0)
        ifeatures.to_csv(opj(savepath, f'interp_features.csv'),
                         mode='w' if overwrite else 'a',
                         header=overwrite)

        # dont forget
        NUCLID += n_nuclei