Exemple #1
0
    def __init__(self, image_info, force_nuclei_load=False, parent=None):
        super(CriteriaSelection, self).__init__(parent)

        # nuclei selection?
        if not hasattr(self, 'is_nuclei_selection'):
            self.is_nuclei_selection = False

        # load image infos
        self.image_info = image_info

        # prepare criteria
        self.criteria = dict()

        # init segmentation
        self.segmentation = Segmentation(self.image_info)

        # load segmentation
        self.segmentation.load(force_nuclei_load=force_nuclei_load)

        # buttons
        self.btn_reset = QtGui.QPushButton(gui_labels.btn_reset)
        self.btn_load = QtGui.QPushButton(gui_labels.btn_load)
        self.btn_save = QtGui.QPushButton(gui_labels.btn_save)
        self.btn_close = QtGui.QPushButton(gui_labels.btn_close)

        # listeners
        self.btn_reset.clicked.connect(self.reset_criteria)
        self.btn_load.clicked.connect(self.load_criteria)
        self.btn_save.clicked.connect(self.save_criteria)
        self.btn_close.clicked.connect(self.close)
Exemple #2
0
    def create_train_target_from_ext_infos(self):
        """
        Create training and target vectors from the
        given extensions
        :return:
        """
        # store training and correction
        train_nuclei = list()
        corr_nuclei = list()

        # go through infos
        for info in self.ext_infos:
            # load segmentation
            seg = Segmentation(info)
            seg.load()

            # add to training nuclei
            train_nuclei += seg.nuclei.copy()

            # load correction
            corr = Correction(seg)
            corr.load_corrections()

            # add to correction
            corr_nuclei += corr.corr_nonuc.copy()

        # load train params
        train_params = cfg.clf_train_params

        # create data and target vectors
        train_data = np.zeros(shape=(len(train_nuclei), len(train_params)))
        train_target = np.zeros(shape=(len(train_nuclei)))

        # go through nuclei and build target vector
        for i, nucleus in enumerate(train_nuclei):
            # get relevant params from nucleus
            for j, key in enumerate(train_params):
                train_data[i][j] = nucleus[key]

            # set target
            nucleus_value = 0

            # is it a nucleus?
            if Correction.is_correction_nonuc_with_list(nucleus, corr_nuclei) is False:
                nucleus_value = 1  # yes - it is

            train_target[i] = nucleus_value

        return train_data, train_target
def get_instance():
    """
    Simulate singleton-like behaviour to enable access to the segmentation system wide

    :return:
    """
    global __seg_instance

    if __seg_instance is None:
        __seg_instance = Segmentation()

    return __seg_instance
Exemple #4
0
    def process_image(self):
        """
        Segment image with the saved parameters

        :return:
        """
        non_nuclei = False

        # is current image a revision?
        if Segmentation.is_revision_by_ID(self.image_info['ID']):
            # create a new segmentation
            non_nuclei = True

        seg = Segmentation(self.image_info, non_nuclei)

        # process stack
        seg.segment(process=True, merge=False, filter=False)

        # save results
        seg.save(force_labels_props_raw=True)
Exemple #5
0
#selected_info_IDs = ['N1-19-9', 'N1-19-23']

# open window to select nuclei criteria
loaded_infos = ImageHandler.load_image_infos()
infos = list()

# processing steps
processing_steps = [['DIL', 'y', 2], ['CONV_BIT', 16]]

for info in loaded_infos:
    info_ID = info['ID']
    if info_ID in selected_info_IDs:
        infos.append(info)

for info in infos:
    seg = Segmentation(info)
    seg.load()

    img_path = seg.get_results_dir().tmp + 'contact_surface.tif'

    print('LOAD', info['ID'])

    # go through nuclei and add to stack
    nIDs = seg.nuclei.get_nIDs(only_accepted=True)

    stack_contact_surface = np.zeros_like(seg.stacks.lamin)

    num_nIDs = len(nIDs)

    # go through nIDs
    for i, nID in enumerate(nIDs):
Exemple #6
0
"""

# import classes
from storage.image import ImageHandler
from processing.segmentation import Segmentation

# load image infos
image_infos = ImageHandler.load_image_infos()

# to skip parent for revisions
id_to_skip = None

# apply defined filters to images
for image_info in image_infos:
    # revision? then skip the initial segmentation and do the revisions
    if Segmentation.is_revision_by_ID(image_info['ID']):
        id_to_skip = Segmentation.extract_parent_from_ID(image_info['ID'])

        # create a new segmentation
        non_nuclei_seg = Segmentation(image_info, True)

        # segment stack
        non_nuclei_seg.segment()

        # save results
        non_nuclei_seg.save()
    else:
        # initial segmentation
        if id_to_skip != image_info['ID']:
            # initialise segmentation
            segmentation = Segmentation(image_info)
Exemple #7
0
infos = list()

# processing steps
processing_steps = [['DIL', 'y', 2],
                    ['CONV_BIT', 16]]

# calculate compactness?
calc_compactness = False

for info in loaded_infos:
    info_ID = info['ID']
    if info_ID in selected_info_IDs:
        infos.append(info)

for info in infos:
    seg = Segmentation(info)
    seg.load()

    img_path = seg.get_results_dir().tmp + 'compactness_examples.tif'

    voxel_size = float(info['voxel_size'])
    voxel_volume = voxel_size ** 3
    voxel_surface = voxel_size ** 2

    print('LOAD', info['ID'])

    # go through nuclei and add to stack
    nIDs = seg.nuclei.get_nIDs(only_accepted=True)

    example_counter = np.zeros((5 * 5)).astype(np.int8)
    stack_examples = list()
Exemple #8
0
plt.rcParams.update(params)

# select a specific info
selected_info_IDs = ['N1-19-9']

# open window to select nuclei criteria
loaded_infos = ImageHandler.load_image_infos()
infos = list()

for info in loaded_infos:
    info_ID = info['ID']
    if info_ID in selected_info_IDs:
        infos.append(info)

for info in infos:
    seg = Segmentation(info)
    seg.load()

    # go through nuclei and add them to a stack with
    # nuclei_in_direction as value
    nIDs = seg.nuclei.get_nIDs(only_accepted=True)

    layer_stack = np.zeros_like(seg.stacks.nuclei)

    for nID in nIDs:
        # get nuclei in direction
        apical = seg.nuclei.get_nucleus_apical_distance(nID)

        if np.isnan(apical):
            apical = 0
Exemple #9
0
plt.rcParams.update(params)
selected_info_IDs = ['N1-19-9', 'N1-19-22', 'N1-19-23', 'N1-19-24']
#selected_info_IDs = ['N1-19-9']

# open window to select nuclei criteria
loaded_infos = ImageHandler.load_image_infos()
infos = list()

for info in loaded_infos:
    info_ID = info['ID']
    if info_ID in selected_info_IDs:
        infos.append(info)

for info in infos:
    seg = Segmentation(info)
    seg.load()

    print('LOAD', info['ID'])

    # go through nuclei and add to stack
    nIDs = seg.nuclei.get_nIDs(only_accepted=True)

    stack_apical_dist = np.zeros_like(seg.stacks.lamin)
    stack_pseudo_layer = np.zeros_like(seg.stacks.lamin)

    # get average nuclei height
    all_depths = seg.nuclei.data_frames['data_params'].get_vals_from_col('depth', only_accepted=True)

    # get average
    avg_depth = np.mean(all_depths)
Exemple #10
0
# lists
density_list = dict()
volume_list = dict()

min_den = -1
max_den = -1
min_vol = -1
max_vol = -1

# resolution
dim = 100

for info in infos:
    if info['ID'] in selected_info_IDs:
        selected_infos[info['ID']] = info
        segs[info['ID']] = Segmentation(info)
        segs[info['ID']].load()

        # prepare maps
        density_map[info['ID']] = np.zeros_like(
            segs[info['ID']].stacks.lamin[0])
        volume_map[info['ID']] = np.zeros_like(
            segs[info['ID']].stacks.lamin[0])

        # prepare lists
        density_list[info['ID']] = list()
        volume_list[info['ID']] = list()

for info_ID, seg in segs.items():
    # tile image
    for y in range(int(density_map[info_ID].shape[0] / dim)):
Exemple #11
0
"""
Using pandas to store nuclei in csv instead of pickling the whole list
"""
import numpy as np
import pandas as pd
import re

# import classes
from storage.image import ImageHandler
from processing.segmentation import Segmentation
from storage.struct import Struct

import storage.config as cfg

# open window to select nuclei criteria
infos = ImageHandler.load_image_infos()

# select a specific info
selected_info_ID = 'N1-19-9'
selected_info = None

for info in infos:
    if info['ID'] == selected_info_ID:
        selected_info = info

# process segmentation
seg = Segmentation(selected_info)
#seg.segment(process=True, merge=True, filter=False)
#seg.save()
seg.load()
Exemple #12
0
import matplotlib.pylab as plt
params = {'axes.titlesize': cfg.fontsdict_plot['fontsize'],
          'xtick.labelsize': cfg.fontsdict_plot['fontsize'],
          'ytick.labelsize': cfg.fontsdict_plot['fontsize']}

plt.rcParams.update(params)

# open window to select nuclei criteria
infos = ImageHandler.load_image_infos()

# select a specific info
selected_info_IDs = ['N1-19-24']

for info in infos:
    if info['ID'] in selected_info_IDs:
        seg = Segmentation(info)
        seg.load()

processing_steps = [
    ['EQU'],
    ['THR', 'OTSU', 100, 'no3D'],
    ['CLS', 'bin', 2],
    ['FILL'],
    ['OPN', 'bin', 2],
    ['CONV_BIT', 16, '3D']
]

# apply processing steps
seg.stacks.membin = ImageProcessing.apply_filters(
    processing_steps, seg.stacks.membrane, verbose=cfg.general_verbose)
Exemple #13
0
Merge initial and revision segmentation to a final segmentation
"""

# import classes
from storage.image import ImageHandler
from processing.segmentation import Segmentation

# load image infos
image_infos = ImageHandler.load_image_infos()

revs_to_merge = list()

# apply defined filters to images
for image_info in image_infos:
    # revision? then skip
    if Segmentation.is_revision_by_ID(image_info['ID']):
        revs_to_merge.append(Segmentation.extract_rev_from_ID(image_info['ID']))
    else:
        # initialise segmentation
        segmentation = Segmentation(image_info)

        # load results
        segmentation.load()

        # merge
        for rev in revs_to_merge:
            segmentation.merge_parent_with_rev(rev)

        # save merge
        segmentation.save_merge_segmentation()
Exemple #14
0
# import classes
from storage.image import ImageHandler
from processing.segmentation import Segmentation
from frontend.gui.nuc_select import NucleoSelect

# load image infos
image_infos = ImageHandler.load_image_infos()

# to skip parent for revisions
id_to_skip = None

# apply defined filters to images
for image_info in image_infos:
    # revision? then skip the initial segmentation and do the revisions
    if Segmentation.is_revision_by_ID(image_info['ID']):
        id_to_skip = Segmentation.extract_parent_from_ID(image_info['ID'])

    if id_to_skip != image_info['ID']:
        # initialise segmentation
        segmentation = Segmentation(image_info)

        # load results
        segmentation.load()

        # cycle through the nuclei and correct their start and stop planes if necessary
        app = QtGui.QApplication(sys.argv)

        nuc_selector = NucleoSelect(segmentation)
        nuc_selector.show()
        nuc_selector.raise_()
Exemple #15
0
class CriteriaSelection(QtGui.QDialog):

    def __init__(self, image_info, force_nuclei_load=False, parent=None):
        super(CriteriaSelection, self).__init__(parent)

        # nuclei selection?
        if not hasattr(self, 'is_nuclei_selection'):
            self.is_nuclei_selection = False

        # load image infos
        self.image_info = image_info

        # prepare criteria
        self.criteria = dict()

        # init segmentation
        self.segmentation = Segmentation(self.image_info)

        # load segmentation
        self.segmentation.load(force_nuclei_load=force_nuclei_load)

        # buttons
        self.btn_reset = QtGui.QPushButton(gui_labels.btn_reset)
        self.btn_load = QtGui.QPushButton(gui_labels.btn_load)
        self.btn_save = QtGui.QPushButton(gui_labels.btn_save)
        self.btn_close = QtGui.QPushButton(gui_labels.btn_close)

        # listeners
        self.btn_reset.clicked.connect(self.reset_criteria)
        self.btn_load.clicked.connect(self.load_criteria)
        self.btn_save.clicked.connect(self.save_criteria)
        self.btn_close.clicked.connect(self.close)

    def prep_ctn_criteria_select(self, lookup_nucleus):
        """
        Prepare main container for criteria selection

        :return:
        """
        container = QtGui.QGridLayout()

        # select criteria
        criteria = cfg.filter_criteria_labels

        if lookup_nucleus is True:
            criteria = cfg.filter_criteria_nuclei

        counter = 0
        for param in criteria:
            # get container
            param_ctn = self.prep_criteria(param.lower(), lookup_nucleus=lookup_nucleus)

            # add container
            if param_ctn is not None:
                container.addLayout(param_ctn, counter, 0)

                counter += 1

        # submit buttons
        container.addLayout(self.prep_ctn_submit(), counter, 0)

        return container

    def reset_criteria(self):
        """
        Reset edit boxes

        :return:
        """
        # go through edit boxes and empty
        for criteria_raw in self.criteria:
            self.criteria[criteria_raw]['edt_min'].setText('')
            self.criteria[criteria_raw]['edt_max'].setText('')

    def load_criteria(self):
        """
        Load selection criteria

        :return:
        """
        # load criteria
        self.loaded_criteria = self.segmentation.get_nuclei_criteria(True)

        # set min/max fields for critieria
        for criteria_raw in self.criteria:
            # edit boxes
            if self.loaded_criteria is not None and criteria_raw in self.loaded_criteria.keys():
                # set value in edit box
                if self.loaded_criteria[criteria_raw]['MIN'] is not None:
                    self.criteria[criteria_raw]['edt_min'].setText(str(self.loaded_criteria[criteria_raw]['MIN']))

                if self.loaded_criteria[criteria_raw]['MAX'] is not None:
                    self.criteria[criteria_raw]['edt_max'].setText(str(self.loaded_criteria[criteria_raw]['MAX']))

    def save_criteria(self):
        """
        Save selection criteria for labels

        :return:
        """
        # create criteria mapping
        criteria = dict()

        # go through criteria and get the values
        for param in self.loaded_criteria.keys():

            # is criteria on mask?
            if param.lower() in self.criteria.keys():
                # get min and max
                min_input = self.criteria[param.lower()]['edt_min'].text()
                max_input = self.criteria[param.lower()]['edt_max'].text()

                min_value = None
                if min_input:
                    min_value = '%.1f' % float(min_input)

                max_value = None
                if max_input:
                    max_value = '%.1f' % float(max_input)
            else:
                min_value = self.loaded_criteria[param]['MIN']
                max_value = self.loaded_criteria[param]['MAX']

            # write to mapping
            criteria[param] = dict()
            criteria[param]['MIN'] = min_value
            criteria[param]['MAX'] = max_value

        # set criteria
        self.loaded_criteria = criteria

        # save to file
        self.segmentation.save_nuclei_criteria(criteria)

    def close(self):
        """
        Close criteria selection and show the main window again

        :return:
        """
        # show parent
        self.parent().showNormal()

        # close processing
        super(QtGui.QDialog, self).close()

    def prep_criteria(self, param, lookup_nucleus):
        """
        Prepare a container with the parameter

        :param param:
        :return:
        """
        container = None

        prep_ctn = True

        # is param part of the nuclei?
        if lookup_nucleus is True:
            if self.segmentation.nuclei.is_param_in_nuclei(param) is False:
                prep_ctn = False

        if prep_ctn is True:
            # prepare dictionary
            self.prep_criteria_dict(param)

            # prepare container
            container = self.prep_criteria_ctn(param)

        return container

    def prep_criteria_dict(self, param):
        """
        Prepare dictionary for param

        :param param:
        :return:
        """
        self.criteria[param] = dict()

        # edit boxes
        self.criteria[param]['edt_min'] = QtGui.QLineEdit()
        self.criteria[param]['edt_max'] = QtGui.QLineEdit()

        # figures
        self.criteria[param]['fig_hist'] = plt.figure(figsize=(5, 2))
        self.criteria[param]['fig_example'] = plt.figure(figsize=(5, 2))

        # canvases
        self.criteria[param]['cnv_hist'] = FigureCanvas(self.criteria[param]['fig_hist'])
        self.criteria[param]['cnv_example'] = FigureCanvas(self.criteria[param]['fig_example'])

        # misc widgets
        self.criteria[param]['sld_hist'] = QtGui.QSlider(QtCore.Qt.Horizontal, self)

    def prep_criteria_ctn(self, param):
        """
        Container to set criteria param

        :return:
        """
        container = QtGui.QGridLayout()

        # labels
        container.addWidget(QtGui.QLabel(getattr(gui_labels, 'crit_sel_label_' + param)), 0, 0)
        container.addWidget(QtGui.QLabel(gui_labels.crit_sel_min), 1, 0)
        container.addWidget(QtGui.QLabel(gui_labels.crit_sel_max), 2, 0)
        container.setRowStretch(3, 1)

        # edit boxes
        container.addWidget(self.criteria[param]['edt_min'], 1, 1)
        container.addWidget(self.criteria[param]['edt_max'], 2, 1)

        # sort nuclei
        if self.is_nuclei_selection:
            # sort nuclei
            self.segmentation.nuclei.sort_nuclei(param)

            # get sorted list
            # TODO transform the props into a dict
            self.criteria[param]['sorted_labels'] = self.segmentation.nuclei.get_param_list_from_nuclei(param)
            self.criteria[param]['sorted_props'] = self.segmentation.nuclei.get_param_list_from_nuclei(create_dict=True)
        else:
            # sort labels
            self.criteria[param]['sorted_labels'] = self.segmentation.get_sorted_prop_list(param)
            self.criteria[param]['sorted_props'] = self.segmentation.sorted_probs.copy()

        # show histogram
        Plot.view_histogram_of_value_list(self.criteria[param]['fig_hist'],
                                          self.criteria[param]['sorted_labels'],
                                          cfg.criteria_select_hist_bins)

        # add to container
        container.addWidget(self.criteria[param]['cnv_hist'], 0, 2, 3, 1)
        container.addWidget(self.criteria[param]['cnv_example'], 0, 3, 4, 1)

        # slider
        self.criteria[param]['sld_hist'].valueChanged[int].connect(self.make_change_criteria_example(param))
        self.criteria[param]['sld_hist'].setMinimum(0)
        self.criteria[param]['sld_hist'].setMaximum(len(self.criteria[param]['sorted_props']))
        container.addWidget(self.criteria[param]['sld_hist'], 3, 2)

        return container

    def make_change_criteria_example(self, param):
        """
        Make function to call change criteria

        :param param:
        :return:
        """
        def change_criteria_example_param(example_selected):
            self.change_criteria_example(param, example_selected)

        return change_criteria_example_param

    def change_criteria_example(self, param, example_selected):
        """
        Change example in +/- range

        :param param:
        :param example_selected:
        :return:
        """
        min_range = example_selected - cfg.criteria_select_eg_range

        if min_range < 0:
            min_range = 0

        max_range = example_selected + cfg.criteria_select_eg_range

        if max_range > len(self.criteria[param]['sorted_props']):
            max_range = len(self.criteria[param]['sorted_props'])

        # prepare examples
        examples = list()

        # show examples from each part
        for i in range(min_range, max_range):
            example_title = '%i\n%.2f' % (self.criteria[param]['sorted_props'][i]['nID'],
                                            self.criteria[param]['sorted_props'][i][param])

            # prepare image
            examples = Plot.prepare_output(examples,
                                           self.criteria[param]['sorted_props'][i]['img'],
                                           example_title,
                                           cfg.criteria_select_eg_colour)

        # clear figure
        if len(examples[0]) < (cfg.criteria_select_eg_range * 2):
            self.criteria[param]['fig_example'].clear()

        # show examples
        Plot.show_images(self.criteria[param]['fig_example'], examples, cols=cfg.criteria_select_eg_cols)

        # update canvas
        self.criteria[param]['cnv_example'].draw()
Exemple #16
0
    view_image(cropped, img_name="Pre-processed image")


# ------ SEGMENTATION ------
# Apply the image segmentation for separating significant elements (casting surfaces)
# from negligible ones (sandy background, upper metal frame, outer image background)
# with respect to the casting surfaces area computation

# De-noise the pre-processed image according to the config file parameters
first = cv2.fastNlMeansDenoising(cropped.copy(), h=FRAME_PARAMS['h'],
                                 templateWindowSize=FRAME_PARAMS['template_window_size'],
                                 searchWindowSize=FRAME_PARAMS['search_window_size'])
# Convert the de-noised image to grayscale and smooth it by blurring
blurred = gray_and_blur(first, blur=True, ksize=7)
# Init a Segmentation class object with the config.py segmentation parameters
sgm = Segmentation(SEGMENTATION_PARAMS)
# Adjust brightness/contrast and threshold the blurred image based on the configuration settings
thresh = sgm.scale_abs_convert_thresh(blurred)
# Apply a sequence of morphological transformations to simplify the thresholded image
# in order to better detect contours
transformed = sgm.transform_morphology(
    thresh, TRANSFORMATION_SEQ, SEGMENTATION_PARAMS['morph_ops_params'])

# Show the segmentation step output image if required
if args["steps"]:
    print(f"Sequence of transformations: {TRANSFORMATION_SEQ}")
    view_image(
        np.hstack([thresh, transformed]),
        img_name=f"Thresholding | {TRANSFORMATION_SEQ[0].capitalize()} and \
        {TRANSFORMATION_SEQ[1].capitalize()}")
        test_window = NucleoSegment(exp_id=exp_id)
        test_window.show()
        test_window.raise_()
        test_window.activateWindow()
        sys.exit(app.exec_())

    # process
    if processing['process'] == 1:
        test_window = NucleoProcess(selected_info)
        test_window.show()
        test_window.raise_()
        test_window.activateWindow()
        sys.exit(app.exec_())
    elif processing['process'] == 2:
        print('=== Process ===')
        seg = Segmentation(selected_info)
        seg.segment(process=True, merge=False, filter=False)
        seg.get_label_props()
        seg.save(force_labels_props_raw=True)
        del(seg)

    # merge
    if processing['merge'] == 1:
        test_window = MergeCriteria(selected_info)
        test_window.show()
        test_window.raise_()
        test_window.activateWindow()
        sys.exit(app.exec_())
    elif processing['merge'] >= 2:
        force_reload = False
        if processing['merge'] == 3:
Exemple #18
0
for info in loaded_infos:
    info_ID = info['ID']
    if info_ID in selected_info_IDs:
        infos.append(info)
        print('TEST APPEND', info)

img_maps = dict()
val_maps = dict()
tiling_count_map = dict()
tiling_maps = dict()
limits = dict()
limit_lists = dict()

for info in infos:
    seg = Segmentation(info)
    seg.load()

    # preparations for params
    if 'between_space' in params_to_get:
        # get binary stack without nuclei
        filled_minus_nuclei = ImageHandler.load_tiff_as_stack(
            seg.get_results_dir().tmp + 'filled_minus_nuclei.tif')

        if filled_minus_nuclei is None:
            filled_stack = np.full(
                (seg.stacks.lamin.shape[0], seg.stacks.lamin.shape[1],
                 seg.stacks.lamin.shape[2]),
                1,
                dtype=np.uint8)
Exemple #19
0
plt.rcParams.update(params)
selected_info_IDs = ['N1-19-9', 'N1-19-22', 'N1-19-23', 'N1-19-24']
#selected_info_IDs = ['N1-19-9']

# open window to select nuclei criteria
loaded_infos = ImageHandler.load_image_infos()
infos = list()

for info in loaded_infos:
    info_ID = info['ID']
    if info_ID in selected_info_IDs:
        infos.append(info)

for info in infos:
    seg = Segmentation(info)
    seg.load()

    print('LOAD', info['ID'])

    # go through nuclei and add to stack
    nIDs = seg.nuclei.get_nIDs(only_accepted=True)

    stack_volume = np.zeros_like(seg.stacks.lamin).astype(np.int8)

    all_volumes = seg.nuclei.data_frames['data_params'].get_vals_from_col(
        'volume', only_accepted=True)

    min_val = float(max(all_volumes))
    max_val = float(min(all_volumes))