예제 #1
0
def cellpose_predict(data, config, path_save, callback_log=None):
    """ Perform prediction with CellPose. 

    Parameters
    ----------
    data : dict
        Contains data on which prediction should be performed. 
    config : dict
        Configuration of CellPose prediction. 
    path_save : pathline Path object
        Path where results will be saved. 
    """

    # Get data
    imgs = data['imgs']
    file_names = data['file_names']
    sizes_orginal = data['sizes_orginal']
    channels = data['channels']
    new_size = data['new_size']
    obj_name = data['obj_name']

    # Get config
    model_type = config['model_type']
    obj_size = config['obj_size']
    device = config['device']

    log_message(f'\nPerforming segmentation of {obj_name}\n',
                callback_fun=callback_log)

    start_time = time.time()

    if not path_save.is_dir():
        path_save.mkdir()

    # Perform segmentation with CellPose
    model = models.Cellpose(
        device, model_type=model_type)  # model_type can be 'cyto' or 'nuclei'
    masks, flows, styles, diams = model.eval(imgs,
                                             diameter=obj_size,
                                             channels=channels)

    # Display and save results
    log_message(f'\n Creating outputs ...\n', callback_fun=callback_log)
    n_img = len(imgs)

    for idx in tqdm(range(n_img)):
        file_name = file_names[idx]
        maski = masks[idx]
        flowi = flows[idx][0]
        imgi = imgs[idx]

        # Rescale each channel separately
        imgi_rescale = imgi.copy()

        for idim in range(3):
            imgdum = imgi[:, :, idim]
            pa, pb = np.percentile(imgdum, (0.1, 99.9))
            imgi_rescale[:, :, idim] = rescale_intensity(
                imgdum, in_range=(pa, pb), out_range=np.uint8).astype('uint8')

        # Save overview image
        fig = plt.figure(figsize=(12, 3))
        plot.show_segmentation(fig,
                               imgi_rescale.astype('uint8'),
                               maski,
                               flowi,
                               channels=channels)
        plt.tight_layout()

        plt.savefig(path_save / f'{file_name.stem}__segment__{obj_name}.png',
                    dpi=600)
        plt.close()

        # Save mask and flow images
        imsave(path_save / f'{file_name.stem}__flow__{obj_name}.png',
               flowi,
               check_contrast=False)

        if new_size:
            mask_full = resize_mask(maski, sizes_orginal[idx])

            imsave(path_save / f'{file_name.stem}__mask__{obj_name}.png',
                   mask_full.astype('uint16'),
                   check_contrast=False)
            imsave(path_save /
                   f'{file_name.stem}__mask_resize__{obj_name}.png',
                   maski.astype('uint16'),
                   check_contrast=False)

        else:
            imsave(path_save / f'{file_name.stem}__mask__{obj_name}.png',
                   maski.astype('uint16'),
                   check_contrast=False)

    log_message(
        f"\nSegmentation of provided images finished ({(time.time() - start_time)}s)",
        callback_fun=callback_log)
예제 #2
0
    gpu = True
elif gpu == 'n':
    gpu = False
'''

files = os.listdir(img_path)
imgs = [
    skimage.io.imread(os.path.join(img_path, f)) for f in files if ".tif" in f
]
nimg = len(imgs)

from cellpose import models

# DEFINE CELLPOSE MODEL
# model_type='cyto' or model_type='nuclei'
model = models.Cellpose(gpu=get_available_gpus(), model_type='cyto')

# define CHANNELS to run segementation on
# grayscale=0, R=1, G=2, B=3
# channels = [cytoplasm, nucleus]
# if NUCLEUS channel does not exist, set the second channel to 0
# channels = [0,0]
# IF ALL YOUR IMAGES ARE THE SAME TYPE, you can give a list with 2 elements
channels = [0, 0]  # IF YOU HAVE GRAYSCALE
# channels = [2,3] # IF YOU HAVE G=cytoplasm and B=nucleus
# channels = [2,1] # IF YOU HAVE G=cytoplasm and R=nucleus

# or if you have different types of channels in each image
#channels = [[2,3], [0,0], [0,0]]

# if diameter is set to None, the size of the cells is estimated on a per image basis
예제 #3
0
if any(shapes) == False:
    exit('Some or all images are NOT stacks')

if split == True: #split 3D image in several stacks (or not)

    #list of images, each being a list of 2D stacks
    list_of_images = []
    for i,im in enumerate(imgs):
        sublist = []
        for j,im in enumerate(imgs[i]):
            sublist.append(imgs[i][j])
        list_of_images.append(sublist)

    #execute cellpose
    model = models.Cellpose(device, model_type=mod) #model_type='cyto' or model_type='nuclei'
    for i, im in enumerate(list_of_images):
        imlist3D = [os.path.splitext(imlist[i])[0] + '_z' + str(n) for n in range(1, len(im) + 1)]
        masks, flows, styles, diams = model.eval(im, diameter=diam, channels=chan)
        utils.masks_flows_to_seg(im, masks, flows, diams, chan, imlist3D)

        imlist3Dtif = [imlist3D[n] + '.tif' for n in range(len(imlist3D))] #saving single-Z plan pictures
        for ind, imag in enumerate(im):
            skimage.io.imsave(imlist3Dtif[ind],imag)

else:
    # execute cellpose
    model = models.Cellpose(device, model_type=mod)  # model_type='cyto' or model_type='nuclei'
    masks, flows, styles, diams = model.eval(imgs, diameter=diam, channels=chan, do_3D=True)
    io.masks_flows_to_seg(imgs, masks, flows, diams, chan, imlist)
예제 #4
0
def main():
    parser = argparse.ArgumentParser(description='cellpose parameters')
    parser.add_argument('--check_mkl',
                        action='store_true',
                        help='check if mkl working')
    parser.add_argument(
        '--mkldnn',
        action='store_true',
        help='for mxnet, force MXNET_SUBGRAPH_BACKEND = "MKLDNN"')
    parser.add_argument('--train',
                        action='store_true',
                        help='train network using images in dir')
    parser.add_argument('--dir',
                        required=False,
                        default=[],
                        type=str,
                        help='folder containing data to run or train on')
    parser.add_argument('--mxnet', action='store_true', help='use mxnet')
    parser.add_argument('--img_filter',
                        required=False,
                        default=[],
                        type=str,
                        help='end string for images to run on')
    parser.add_argument('--use_gpu',
                        action='store_true',
                        help='use gpu if mxnet with cuda installed')
    parser.add_argument(
        '--fast_mode',
        action='store_true',
        help="make code run faster by turning off 4 network averaging")
    parser.add_argument(
        '--resample',
        action='store_true',
        help=
        "run dynamics on full image (slower for images with large diameters)")
    parser.add_argument(
        '--no_interp',
        action='store_true',
        help='do not interpolate when running dynamics (was default)')
    parser.add_argument(
        '--do_3D',
        action='store_true',
        help='process images as 3D stacks of images (nplanes x nchan x Ly x Lx'
    )
    # settings for running cellpose
    parser.add_argument('--pretrained_model',
                        required=False,
                        default='cyto',
                        type=str,
                        help='model to use')
    parser.add_argument(
        '--unet',
        required=False,
        default=0,
        type=int,
        help='run standard unet instead of cellpose flow output')
    parser.add_argument(
        '--nclasses',
        required=False,
        default=3,
        type=int,
        help='if running unet, choose 2 or 3, otherwise not used')
    parser.add_argument(
        '--chan',
        required=False,
        default=0,
        type=int,
        help='channel to segment; 0: GRAY, 1: RED, 2: GREEN, 3: BLUE')
    parser.add_argument(
        '--chan2',
        required=False,
        default=0,
        type=int,
        help=
        'nuclear channel (if cyto, optional); 0: NONE, 1: RED, 2: GREEN, 3: BLUE'
    )
    parser.add_argument('--invert',
                        required=False,
                        action='store_true',
                        help='invert grayscale channel')
    parser.add_argument(
        '--all_channels',
        action='store_true',
        help=
        'use all channels in image if using own model and images with special channels'
    )
    parser.add_argument(
        '--diameter',
        required=False,
        default=30.,
        type=float,
        help='cell diameter, if 0 cellpose will estimate for each image')
    parser.add_argument(
        '--flow_threshold',
        required=False,
        default=0.4,
        type=float,
        help='flow error threshold, 0 turns off this optional QC step')
    parser.add_argument('--cellprob_threshold',
                        required=False,
                        default=0.0,
                        type=float,
                        help='cell probability threshold, centered at 0.0')
    parser.add_argument(
        '--save_png',
        action='store_true',
        help='save masks as png and outlines as text file for ImageJ')
    parser.add_argument(
        '--save_tif',
        action='store_true',
        help='save masks as tif and outlines as text file for ImageJ')
    parser.add_argument('--no_npy',
                        action='store_true',
                        help='suppress saving of npy')

    # settings for training
    parser.add_argument('--train_size',
                        action='store_true',
                        help='train size network at end of training')
    parser.add_argument('--mask_filter',
                        required=False,
                        default='_masks',
                        type=str,
                        help='end string for masks to run on')
    parser.add_argument('--test_dir',
                        required=False,
                        default=[],
                        type=str,
                        help='folder containing test data (optional)')
    parser.add_argument('--learning_rate',
                        required=False,
                        default=0.2,
                        type=float,
                        help='learning rate')
    parser.add_argument('--n_epochs',
                        required=False,
                        default=500,
                        type=int,
                        help='number of epochs')
    parser.add_argument('--batch_size',
                        required=False,
                        default=8,
                        type=int,
                        help='batch size')
    parser.add_argument('--residual_on',
                        required=False,
                        default=1,
                        type=int,
                        help='use residual connections')
    parser.add_argument('--style_on',
                        required=False,
                        default=1,
                        type=int,
                        help='use style vector')
    parser.add_argument(
        '--concatenation',
        required=False,
        default=0,
        type=int,
        help=
        'concatenate downsampled layers with upsampled layers (off by default which means they are added)'
    )

    args = parser.parse_args()

    if args.check_mkl:
        mkl_enabled = models.check_mkl((not args.mxnet))
    else:
        mkl_enabled = True

    if not args.train and (mkl_enabled and args.mkldnn):
        os.environ["MXNET_SUBGRAPH_BACKEND"] = "MKLDNN"
    else:
        os.environ["MXNET_SUBGRAPH_BACKEND"] = ""

    if len(args.dir) == 0:
        if not GUI_ENABLED:
            print('ERROR: %s' % GUI_ERROR)
            if GUI_IMPORT:
                print(
                    'GUI FAILED: GUI dependencies may not be installed, to install, run'
                )
                print('     pip install cellpose[gui]')
        else:
            gui.run()

    else:
        use_gpu = False
        channels = [args.chan, args.chan2]

        # find images
        if len(args.img_filter) > 0:
            imf = args.img_filter
        else:
            imf = None

        device, gpu = models.assign_device((not args.mxnet), args.use_gpu)
        model_dir = models.model_dir

        if not args.train and not args.train_size:
            tic = time.time()
            if not (args.pretrained_model == 'cyto'
                    or args.pretrained_model == 'nuclei'):
                cpmodel_path = args.pretrained_model
                if not os.path.exists(cpmodel_path):
                    print('model path does not exist, using cyto model')
                    args.pretrained_model = 'cyto'

            image_names = io.get_image_files(args.dir,
                                             args.mask_filter,
                                             imf=imf)
            nimg = len(image_names)
            if args.diameter == 0:
                if args.pretrained_model == 'cyto' or args.pretrained_model == 'nuclei':
                    diameter = None
                    print('>>>> estimating diameter for each image')
                else:
                    print(
                        '>>>> using user-specified model, no auto-diameter estimation available'
                    )
                    diameter = model.diam_mean
            else:
                diameter = args.diameter
                print('>>>> using diameter %0.2f for all images' % diameter)

            cstr0 = ['GRAY', 'RED', 'GREEN', 'BLUE']
            cstr1 = ['NONE', 'RED', 'GREEN', 'BLUE']
            print(
                '>>>> running cellpose on %d images using chan_to_seg %s and chan (opt) %s'
                % (nimg, cstr0[channels[0]], cstr1[channels[1]]))

            if args.pretrained_model == 'cyto' or args.pretrained_model == 'nuclei':
                model = models.Cellpose(gpu=gpu,
                                        device=device,
                                        model_type=args.pretrained_model,
                                        torch=(not args.mxnet))
            else:
                if args.all_channels:
                    channels = None
                model = models.CellposeModel(gpu=gpu,
                                             device=device,
                                             pretrained_model=cpmodel_path,
                                             torch=(not args.mxnet))

            for image_name in tqdm(image_names):
                image = io.imread(image_name)
                out = model.eval(image,
                                 channels=channels,
                                 diameter=diameter,
                                 do_3D=args.do_3D,
                                 net_avg=(not args.fast_mode),
                                 augment=False,
                                 resample=args.resample,
                                 flow_threshold=args.flow_threshold,
                                 cellprob_threshold=args.cellprob_threshold,
                                 invert=args.invert,
                                 batch_size=args.batch_size,
                                 interp=(not args.no_interp))
                masks, flows = out[:2]
                if len(out) > 3:
                    diams = out[-1]
                else:
                    diams = diameter
                if not args.no_npy:
                    io.masks_flows_to_seg(image, masks, flows, diams,
                                          image_name, channels)
                if args.save_png or args.save_tif:
                    io.save_masks(image,
                                  masks,
                                  flows,
                                  image_name,
                                  png=args.save_png,
                                  tif=args.save_tif)
            print('>>>> completed in %0.3f sec' % (time.time() - tic))
        else:
            if args.pretrained_model == 'cyto' or args.pretrained_model == 'nuclei':
                torch_str = ['torch', '']
                cpmodel_path = os.fspath(
                    model_dir.joinpath(
                        '%s%s_0' %
                        (args.pretrained_model, torch_str[args.mxnet])))
                if args.pretrained_model == 'cyto':
                    szmean = 30.
                else:
                    szmean = 17.
            else:
                cpmodel_path = os.fspath(args.pretrained_model)
                szmean = 30.

            if args.all_channels:
                channels = None

            test_dir = None if len(args.test_dir) == 0 else args.test_dir
            output = io.load_train_test_data(args.dir, test_dir, imf,
                                             args.mask_filter, args.unet)
            images, labels, image_names, test_images, test_labels, image_names_test = output

            # model path
            if not os.path.exists(cpmodel_path):
                if not args.train:
                    raise ValueError(
                        'ERROR: model path missing or incorrect - cannot train size model'
                    )
                cpmodel_path = False
                print('>>>> training from scratch')
                if args.diameter == 0:
                    rescale = False
                    print(
                        '>>>> median diameter set to 0 => no rescaling during training'
                    )
                else:
                    rescale = True
                    szmean = args.diameter
            else:
                rescale = True
                args.diameter = szmean
                print('>>>> pretrained model %s is being used' % cpmodel_path)
                args.residual_on = 1
                args.style_on = 1
                args.concatenation = 0
            if rescale and args.train:
                print(
                    '>>>> during training rescaling images to fixed diameter of %0.1f pixels'
                    % args.diameter)

            # initialize model
            if args.unet:
                model = core.UnetModel(device=device,
                                       pretrained_model=cpmodel_path,
                                       diam_mean=szmean,
                                       residual_on=args.residual_on,
                                       style_on=args.style_on,
                                       concatenation=args.concatenation,
                                       nclasses=args.nclasses)
            else:
                model = models.CellposeModel(device=device,
                                             torch=(not args.mxnet),
                                             pretrained_model=cpmodel_path,
                                             diam_mean=szmean,
                                             residual_on=args.residual_on,
                                             style_on=args.style_on,
                                             concatenation=args.concatenation)

            # train segmentation model
            if args.train:
                cpmodel_path = model.train(images,
                                           labels,
                                           train_files=image_names,
                                           test_data=test_images,
                                           test_labels=test_labels,
                                           test_files=image_names_test,
                                           learning_rate=args.learning_rate,
                                           channels=channels,
                                           save_path=os.path.realpath(
                                               args.dir),
                                           rescale=rescale,
                                           n_epochs=args.n_epochs,
                                           batch_size=args.batch_size)
                model.pretrained_model = cpmodel_path
                print('>>>> model trained and saved to %s' % cpmodel_path)

            # train size model
            if args.train_size:
                sz_model = models.SizeModel(cp_model=model, device=device)
                sz_model.train(images,
                               labels,
                               test_images,
                               test_labels,
                               channels=channels,
                               batch_size=args.batch_size)
                if test_images is not None:
                    predicted_diams, diams_style = sz_model.eval(
                        test_images, channels=channels)
                    if test_labels[0].ndim > 2:
                        tlabels = [lbl[0] for lbl in test_labels]
                    else:
                        tlabels = test_labels
                    ccs = np.corrcoef(
                        diams_style,
                        np.array([utils.diameters(lbl)[0]
                                  for lbl in tlabels]))[0, 1]
                    cc = np.corrcoef(
                        predicted_diams,
                        np.array([utils.diameters(lbl)[0]
                                  for lbl in tlabels]))[0, 1]
                    print(
                        'style test correlation: %0.4f; final test correlation: %0.4f'
                        % (ccs, cc))
                    np.save(
                        os.path.join(
                            args.test_dir, '%s_predicted_diams.npy' %
                            os.path.split(cpmodel_path)[1]), {
                                'predicted_diams': predicted_diams,
                                'diams_style': diams_style
                            })
예제 #5
0
                os.path.join(cp_path, 'models/',
                             'size_%s_0.npy' % args.pretrained_model))
            if args.pretrained_model == 'cyto':
                szmean = 27.
            else:
                szmean = 15.
        else:
            cpmodel_path = args.pretrained_model
            szmodel_path = None
            szmean = 27.
            if args.all_channels:
                channels = None

        if not args.train:
            model = models.Cellpose(device=device,
                                    pretrained_model=cpmodel_path,
                                    pretrained_size=szmodel_path,
                                    diam_mean=szmean)
            if args.diameter == 0:
                diameter = None
                if args.pretrained_model == 'cyto' or args.pretrained_model == 'nuclei':
                    print('>>>> estimating diameter for each image')
                else:
                    print(
                        '>>>> using user-specified model, no auto-diameter estimation available'
                    )
            else:
                diameter = args.diameter
                print('using diameter %0.2f for all images' % diameter)
            cstr0 = ['GRAY', 'RED', 'GREEN', 'BLUE']
            cstr1 = ['NONE', 'RED', 'GREEN', 'BLUE']
            print(
예제 #6
0
# create a img_list
img_list = [f for f in os.listdir(img_path) if '.tif' in f]
imgs = [skimage.io.imread(os.path.join(img_path,f)) for f in img_list]





# RUN CELLPOSE

from cellpose import models

# DEFINE CELLPOSE MODEL
# model_type='cyto' or model_type='nuclei'
model = models.Cellpose(gpu=gpu , model_type=model_type) # If there is no GPU, this will automatically go to CPU mode.

# define CHANNELS to run segementation on
# grayscale=0, R=1, G=2, B=3
# channels = [cytoplasm, nucleus]
# if NUCLEUS channel does not exist, set the second channel to 0
# channels = [0,0]
# IF ALL YOUR IMAGES ARE THE SAME TYPE, you can give a list with 2 elements
# channels = [0,0] # IF YOU HAVE GRAYSCALE
# channels = [2,3] # IF YOU HAVE G=cytoplasm and B=nucleus
# channels = [2,1] # IF YOU HAVE G=cytoplasm and R=nucleus

# or if you have different types of channels in each image
channels = [channel_type]*len(img_list)

# if diameter is set to None, the size of the cells is estimated on a per image basis
    def run(self, workspace):
        if self.mode.value != MODE_CUSTOM:
            model = models.Cellpose(model_type='cyto' if self.mode.value
                                    == MODE_CELLS else 'nuclei',
                                    gpu=self.use_gpu.value)
        else:
            model_file = self.model_file_name.value
            model_directory = self.model_directory.get_absolute_path()
            model_path = os.path.join(model_directory, model_file)
            model = models.CellposeModel(pretrained_model=model_path,
                                         gpu=self.use_gpu.value)

        x_name = self.x_name.value
        y_name = self.y_name.value
        images = workspace.image_set
        x = images.get_image(x_name)
        dimensions = x.dimensions
        x_data = x.pixel_data

        if x.multichannel:
            raise ValueError(
                "Color images are not currently supported. Please provide greyscale images."
            )

        if self.mode.value != "Nuclei" and self.supply_nuclei.value:
            nuc_image = images.get_image(self.nuclei_image.value)
            # CellPose expects RGB, we'll have a blank red channel, cells in green and nuclei in blue.
            if x.volumetric:
                x_data = numpy.stack(
                    (numpy.zeros_like(x_data), x_data, nuc_image.pixel_data),
                    axis=1)
            else:
                x_data = numpy.stack(
                    (numpy.zeros_like(x_data), x_data, nuc_image.pixel_data),
                    axis=-1)
            channels = [2, 3]
        else:
            channels = [0, 0]

        diam = self.expected_diameter.value if self.expected_diameter.value > 0 else None

        try:
            y_data, flows, *_ = model.eval(
                x_data,
                channels=channels,
                diameter=diam,
                net_avg=self.use_averaging.value,
                do_3D=x.volumetric,
                flow_threshold=self.flow_threshold.value,
                cellprob_threshold=self.dist_threshold.value)
        finally:
            if self.use_gpu.value and model.torch:
                # Try to clear some GPU memory for other worker processes.
                try:
                    from torch import cuda
                    cuda.empty_cache()
                except Exception as e:
                    print(
                        f"Unable to clear GPU memory. You may need to restart CellProfiler to change models. {e}"
                    )

        y = Objects()
        y.segmented = y_data
        y.parent_image = x.parent_image
        objects = workspace.object_set
        objects.add_objects(y, y_name)

        if self.save_probabilities.value:
            # Flows come out sized relative to CellPose's inbuilt model size.
            # We need to slightly resize to match the original image.
            size_corrected = resize(flows[2], y_data.shape)
            prob_image = Image(
                size_corrected,
                parent_image=x.parent_image,
                convert=False,
                dimensions=len(size_corrected.shape),
            )

            workspace.image_set.add(self.probabilities_name.value, prob_image)

            if self.show_window:
                workspace.display_data.probabilities = size_corrected

        self.add_measurements(workspace)

        if self.show_window:
            if x.volumetric:
                # Can't show CellPose-accepted colour images in 3D
                workspace.display_data.x_data = x.pixel_data
            else:
                workspace.display_data.x_data = x_data
            workspace.display_data.y_data = y_data
            workspace.display_data.dimensions = dimensions
예제 #8
0
is_norm_provided = False
if ((args.min is not None) & (args.max is not None)):
    min = args.min
    max = args.max
    is_norm_provided = True

if (args.model is not None):
    model = args.model

# Check if we have GPU Available
use_GPU = models.use_gpu()
print('CellPose: GPU activated? %d' % use_GPU)

# Prepare CellPose Model
model = models.Cellpose(gpu=use_GPU, model_type=model)

# Read All Images
image_files = sorted(image_folder.glob('*.tif'))

# Normalize Images and predict
images = []

# Because CellPose can process multiple images in batch on its own,
# we will be faster if we open and process all images though a single
# cellpose call
for image_file in image_files:
    print('Opening Image: ', str(image_file.name), '...')

    image = imread(str(image_file))
    if (is_norm_provided):
예제 #9
0
def run_cellpose(probs,
                 masks,
                 model_type='nuclei',
                 diameter=0,
                 min_size=-1,
                 gpu=True):
    'Run cellpose on deepflash2 predictions'
    check_cellpose_installation()

    if diameter == 0:
        diameter = get_diameters(masks)
    print(f'Using diameter of {diameter}')

    from cellpose import models, dynamics, utils

    @patch
    def _compute_masks(self: models.CellposeModel,
                       dP,
                       cellprob,
                       p=None,
                       niter=200,
                       flow_threshold=0.4,
                       interp=True,
                       do_3D=False,
                       min_size=15,
                       resize=None,
                       **kwargs):
        """ compute masks using dynamics from dP and cellprob """
        if p is None:
            p = dynamics.follow_flows(-1 * dP * mask / 5.,
                                      niter=niter,
                                      interp=interp,
                                      use_gpu=self.gpu)
        maski = dynamics.get_masks(
            p,
            iscell=mask,
            flows=dP,
            threshold=flow_threshold if not do_3D else None)
        maski = utils.fill_holes_and_remove_small_masks(maski,
                                                        min_size=min_size)
        if resize is not None:
            maski = transforms.resize_image(maski,
                                            resize[0],
                                            resize[1],
                                            interpolation=cv2.INTER_NEAREST)
        return maski, p

    model = models.Cellpose(gpu=gpu, model_type=model_type)
    cp_masks = []
    for prob, mask in progress_bar(zip(probs, masks),
                                   total=len(probs),
                                   leave=False):
        cp_pred, _, _, _ = model.eval(prob,
                                      net_avg=True,
                                      augment=True,
                                      diameter=diameter,
                                      normalize=False,
                                      min_size=min_size,
                                      resample=True,
                                      channels=[0, 0])
        cp_masks.append(cp_pred)
    return cp_masks
def image_processing_function(image_loc, config):
    # Read the image into a numpy array of format ZCYX
    if isinstance(image_loc, str):
        image_name = pathlib.Path(image_loc).stem
        image = tifffile.imread(image_loc)
    else:
        # Establish connection with OMERO and actually connect
        conn = omero.gateway.BlitzGateway(
            host="omero1.bioch.ox.ac.uk",
            port=4064,
            # group=config["OMERO_group"],
            username=config["OMERO_user"],
            passwd=config["password"],
        )
        conn.connect()
        conn.SERVICE_OPTS.setOmeroGroup(-1)
        # Create a thread to keep the connection alive
        ka_thread = threading.Thread(target=keep_connection_alive,
                                     args=(conn, ))
        ka_thread.daemon = True
        ka_thread.start()
        # Derive image and its name
        image_name = pathlib.Path(image_loc[0]).stem
        remote_image = conn.getObject("Image", image_loc[1])
        image = np.array(
            list(remote_image.getPrimaryPixels().getPlanes([
                (z, c, 0) for z in range(0, remote_image.getSizeZ())
                for c in range(0, remote_image.getSizeC())
            ])))
        image = image.reshape(
            image.shape[0] // remote_image.getSizeC(),
            remote_image.getSizeC(),
            image.shape[1],
            image.shape[2],
        )

    # segment with cellpose
    seg_img = np.max(image[:, config["seg_ch"], :, :], 0)
    if config["cp_search_string"] in image_name:
        seg_img = np.clip(seg_img, 0, config["cp_clip"])
    seg_img = scipy.ndimage.median_filter(seg_img,
                                          size=config["median_filter"])
    model = models.Cellpose(gpu=config["gpu"], model_type="cyto")
    channels = [0, 0]  # greyscale segmentation
    masks = model.eval(
        seg_img,
        channels=channels,
        diameter=config["diameter"],
        do_3D=config["do_3D"],
        flow_threshold=config["flow_threshold"],
        cellprob_threshold=config["cellprob_threshold"],
    )[0]

    # Calculate PSF
    psf_z, psf_yx = calculate_psf(
        config["voxel_size_z"],
        config["voxel_size_yx"],
        config["ex"],
        config["em"],
        config["NA"],
        config["RI"],
        config["microscope"],
    )
    sigma = detection.get_sigma(config["voxel_size_z"],
                                config["voxel_size_yx"], psf_z, psf_yx)

    for image_channel in config["channels"]:
        # detect spots
        rna = image[:, image_channel, :, :]
        # subtract background
        rna_no_bg = []
        for z in rna:
            z_no_bg = subtract_background(z, config["bg_radius"])
            rna_no_bg.append(z_no_bg)
        rna = np.array(rna_no_bg)

        # LoG filter
        rna_log = stack.log_filter(rna, sigma)

        # local maximum detection
        mask = detection.local_maximum_detection(rna_log, min_distance=sigma)

        # tresholding
        if image_channel == config["smFISH_ch1"]:
            threshold = config["smFISH_ch1_thresh"]
        elif image_channel == config["smFISH_ch2"]:
            threshold = config["smFISH_ch2_thresh"]
        else:
            print("smFISH channel and threshold not correctly defined!")

        spots, _ = detection.spots_thresholding(rna_log, mask, threshold)

        # detect and decompose clusters
        spots_post_decomposition = detection.decompose_cluster(
            rna,
            spots,
            config["voxel_size_z"],
            config["voxel_size_yx"],
            psf_z,
            psf_yx,
            alpha=config["alpha"],  # impacts number of spots per cluster
            beta=config["beta"],  # impacts the number of detected clusters
        )[0]

        # separate spots from clusters
        spots_post_clustering, foci = detection.detect_foci(
            spots_post_decomposition,
            config["voxel_size_z"],
            config["voxel_size_yx"],
            config["bf_radius"],
            config["nb_min_spots"],
        )

        # extract cell level results
        image_contrasted = stack.rescale(rna, channel_to_stretch=0)
        image_contrasted = stack.maximum_projection(image_contrasted)
        rna_mip = stack.maximum_projection(rna)

        fov_results = stack.extract_cell(
            cell_label=masks.astype(np.int64),
            ndim=3,
            rna_coord=spots_post_clustering,
            others_coord={"foci": foci},
            image=image_contrasted,
            others_image={"smfish": rna_mip},
        )

        # save bigfish results
        for i, cell_results in enumerate(fov_results):
            output_path = pathlib.Path(config["output_dir"]).joinpath(
                f"{image_name}_ch{image_channel + 1}_results_cell_{i}.npz")
            stack.save_cell_extracted(cell_results, str(output_path))

        # save reference spot for each image
        # (Using undenoised image! not from denoised!)
        reference_spot_undenoised = detection.build_reference_spot(
            rna,
            spots,
            config["voxel_size_z"],
            config["voxel_size_yx"],
            psf_z,
            psf_yx,
            alpha=config["alpha"],
        )
        spot_output_path = pathlib.Path(config["output_refspot_dir"]).joinpath(
            f"{image_name}_reference_spot_ch{image_channel + 1}")
        stack.save_image(reference_spot_undenoised, str(spot_output_path),
                         "tif")

    # Close the OMERO connection
    conn.close()
예제 #11
0
def main(inputs, img_path, img_format, output_dir):
    """
    Parameter
    ---------
    inputs : str
        File path to galaxy tool parameter
    img_path : str
        File path for the input image
    img_format : str
        One of the ['ome.tiff', 'tiff', 'png', 'jpg']
    output_dir : str
        Folder to save the outputs.
    """
    warnings.simplefilter('ignore')

    with open(inputs, 'r') as param_handler:
        params = json.load(param_handler)

    gpu = params['use_gpu']
    model_selector = params['model_selector']
    model_type = model_selector['model_type']
    chan = model_selector['chan']
    chan2 = model_selector['chan2']
    if chan is None:
        channels = None
    else:
        channels = [int(chan), int(chan2) if chan2 is not None else None]

    options = params['options']

    img = skimage.io.imread(img_path)

    print(f"Image shape: {img.shape}")
    # transpose to Ly x Lx x nchann and reshape based on channels
    if img_format.endswith('tiff') and params['channel_first']:
        img = np.transpose(img, (1, 2, 0))
        img = transforms.reshape(img, channels=channels)
        channels = [1, 2]

    print(f"Image shape: {img.shape}")
    model = models.Cellpose(gpu=gpu,
                            model_type=model_type,
                            net_avg=options['net_avg'])
    masks, flows, styles, diams = model.eval(img, channels=channels, **options)

    # save masks to tiff
    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        skimage.io.imsave(os.path.join(output_dir, 'cp_masks.tif'),
                          masks.astype(np.uint16))

    # make segmentation show #
    # show 3d not working thus set show_seg always to false
    #show_seg = params['show_segmentation']
    show_seg = False
    if show_seg:
        img = skimage.io.imread(img_path)
        # uniform image
        if img_format.endswith('tiff') and params['channel_first']:
            img = np.transpose(img, (1, 2, 0))
            img = transforms.reshape(img, channels=channels)
            channels = [1, 2]

        maski = masks
        flowi = flows[0]
        fig = plt.figure(figsize=(12, 3))
        # can save images (set save_dir=None if not)
        plot.show_segmentation(fig, img, maski, flowi, channels=channels)
        fig.savefig(os.path.join(output_dir, 'segm_show.png'), dpi=300)
        plt.close(fig)
import numpy as np
import matplotlib.pyplot as plt
import skimage.io
from cellpose import models, io
import glob
import os
import pickle, pprint
import pandas


# In[7]:


# model_type='cyto' or model_type='nuclei'
model = models.Cellpose(gpu=True, model_type='cyto')

# list of files
# PUT PATH TO YOUR FILES HERE!
dir = 'D:\Mirindra\subsampling_cfos_ventral'
os.chdir(dir)
filelist = glob.glob('*.tif')

imgs = [skimage.io.imread(f) for f in filelist]
nimg = len(imgs)

# define CHANNELS to run segmentation on
# channels = [cytoplasm, nucleus]

# if NUCLEUS channel does not exist, set the second channel to 0
channels = [[0,0]]*nimg
예제 #13
0
 def initalize_cellpose(self):
     if self.verbose:
         i = [i for i in tqdm([], desc='Initialize Cellpose')]
     self.model = models.Cellpose(
         model_type=self.cellpose_inputs['model_type'],
         gpu=self.cellpose_inputs['gpu'])  #,
예제 #14
0
def cellpose_predict(data, config, path_save, callback_log=None):
    """ Perform prediction with CellPose. 

    Parameters
    ----------
    data : dict
        Contains data on which prediction should be performed. 
    config : dict
        Configuration of CellPose prediction. 
    path_save : pathline Path object
        Path where results will be saved. 
    """

    # Get data
    imgs = data['imgs']
    file_names = data['file_names']
    channels = data['channels']
    obj_name = data['obj_name']
    sizes_orginal = data['sizes_orginal']
    new_size = data['new_size']

    # Get config
    model_type = config['model_type']
    diameter = config['diameter']
    net_avg = config['net_avg']
    resample = config['resample']

    log_message(f'\nPerforming segmentation of {obj_name}\n',
                callback_fun=callback_log)

    start_time = time.time()

    if not path_save.is_dir():
        path_save.mkdir()

    # Perform segmentation with CellPose
    model = models.Cellpose(
        gpu=False,
        model_type=model_type)  # model_type can be 'cyto' or 'nuclei'
    masks, flows, styles, diams = model.eval(imgs,
                                             diameter=diameter,
                                             channels=channels,
                                             net_avg=net_avg,
                                             resample=resample)

    # Display and save results
    log_message(f'\n Creating outputs ...\n', callback_fun=callback_log)
    n_img = len(imgs)

    for idx in tqdm(range(n_img)):

        # Get images and file-name
        file_name = file_names[idx]
        maski = masks[idx]
        flowi = flows[idx][0]
        imgi = imgs[idx]

        # Rescale each channel separately
        imgi_norm = imgi.copy()
        for idim in range(3):
            imgdum = imgi[:, :, idim]

            # Renormalize to 8bit between 1 and 99 percentile
            pa = np.percentile(imgdum, 0.5)
            pb = np.percentile(imgdum, 99.5)

            if pb > pa:
                imgi_norm[:, :, idim] = 255 * (imgdum - pa) / (pb - pa)

        # Save flow
        io.imsave(str(path_save / f'{file_name.stem}__flow__{obj_name}.png'),
                  flowi)

        # Resize masks if necessary
        if new_size:
            mask_full = resize_mask(maski, sizes_orginal[idx])

            io.imsave(
                str(path_save / f'{file_name.stem}__mask__{obj_name}.png'),
                mask_full)
            io.imsave(
                str(path_save /
                    f'{file_name.stem}__mask_resize__{obj_name}.png'), maski)

        else:
            io.imsave(
                str(path_save / f'{file_name.stem}__mask__{obj_name}.png'),
                maski)

        # Save mask and flow images
        #f_mask = str(path_save / f'{file_name.stem}__mask__{obj_name}.png')
        #log_message(f'\nMask saved to file: {f_mask}\n', callback_fun=callback_log)

        #io.imsave(str(path_save / f'{file_name.stem}__mask__{obj_name}.png'), maski)

        # Save overview image
        fig = plt.figure(figsize=(12, 3))
        plot.show_segmentation(fig, imgi_norm.astype('uint8'), maski, flowi)
        plt.tight_layout()
        fig.savefig(str(path_save / f'{file_name.stem}__seg__{obj_name}.png'),
                    dpi=300)
        plt.close(fig)

    log_message(
        f"\nSegmentation of provided images finished ({(time.time() - start_time)}s)",
        callback_fun=callback_log)