Example #1
0
def run_nuclei_inst_stat(pred_dir,
                         true_dir,
                         print_img_stats=False,
                         ext=".mat"):
    # print stats of each image
    print(pred_dir)

    file_list = glob.glob("%s/*%s" % (pred_dir, ext))
    file_list.sort()  # ensure same order

    metrics = [[], [], [], [], [], []]
    for filename in file_list[:]:
        filename = os.path.basename(filename)
        basename = filename.split(".")[0]

        true = sio.loadmat(os.path.join(true_dir, basename + ".mat"))
        true = (true["inst_map"]).astype("int32")

        pred = sio.loadmat(os.path.join(pred_dir, basename + ".mat"))
        pred = (pred["inst_map"]).astype("int32")

        # to ensure that the instance numbering is contiguous
        pred = remap_label(pred, by_size=False)
        true = remap_label(true, by_size=False)

        pq_info = get_fast_pq(true, pred, match_iou=0.5)[0]
        metrics[0].append(get_dice_1(true, pred))
        metrics[1].append(get_fast_aji(true, pred))
        metrics[2].append(pq_info[0])  # dq
        metrics[3].append(pq_info[1])  # sq
        metrics[4].append(pq_info[2])  # pq
        metrics[5].append(get_fast_aji_plus(true, pred))

        if print_img_stats:
            print(basename, end="\t")
            for scores in metrics:
                print("%f " % scores[-1], end="  ")
            print()
    ####
    metrics = np.array(metrics)
    metrics_avg = np.mean(metrics, axis=-1)
    np.set_printoptions(formatter={"float": "{: 0.5f}".format})
    print(metrics_avg)
    metrics_avg = list(metrics_avg)
    return metrics
Example #2
0
def process():
    """
    Performs post processing for a list of images

    """

    cfg = Config()

    for data_dir in cfg.inf_data_list:

        proc_dir = cfg.inf_output_dir + '/processed/'
        pred_dir = cfg.inf_output_dir + '/raw/'
        file_list = glob.glob(pred_dir + '*.npy')
        file_list.sort()  # ensure same order

        if not os.path.isdir(proc_dir):
            os.makedirs(proc_dir)
        for filename in file_list:
            start = time.time()
            filename = os.path.basename(filename)
            basename = filename.split('.')[0]

            test_set = basename.split('_')[0]
            test_set = test_set[-1]

            print(pred_dir, basename, end=' ', flush=True)

            ##
            img = cv2.imread(data_dir + basename + cfg.inf_imgs_ext)
            img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

            pred_map = np.load(pred_dir + '/%s.npy' % basename)

            # get the instance level prediction
            pred_inst = process_utils(pred_map, cfg.model_mode)

            # ! remap label is slow - check to see whether it is needed!
            pred_inst = remap_label(pred_inst, by_size=True)

            overlaid_output = visualize_instances(pred_inst, img)
            overlaid_output = cv2.cvtColor(overlaid_output, cv2.COLOR_BGR2RGB)
            cv2.imwrite('%s/%s.png' % (proc_dir, basename), overlaid_output)

            # save segmentation mask
            np.save('%s/%s' % (proc_dir, basename), pred_inst)

            end = time.time()
            diff = str(round(end - start, 2))
            print('FINISH. TIME: %s' % diff)
    def run(self, data_dir, output_dir, model_path, ambi_path, img_ext='.png'):

        if (not data_dir):
            print('Using Config file path for data_dir.')
            data_dir = self.inf_data_dir
        if (not output_dir):
            print('Using Config file path for output_dir.')
            output_dir = self.inf_output_dir
        if (not model_path):
            print('Using placeholder path for model_dir.')
            model_path = '/home/dm1/shikhar/hover_net_modified/v2_multitask/np_hv/07/model-35854.index'
        if (not img_ext):
            print('Using Config img ext value img_ext.')
            img_ext = self.inf_imgs_ext
        if (not ambi_path):
            # Hard coding path here for single test run.
            ambi_path = '/home/dm1/shikhar/check_sandbox/testing_code/MoNuSAC_testing_data/MoNuSAC_testing_ambiguous_regions'

        model_constructor = self.get_model()
        pred_config = PredictConfig(
            model=model_constructor(),
            session_init=get_model_loader(model_path),
            input_names=self.eval_inf_input_tensor_names,
            output_names=self.eval_inf_output_tensor_names)
        predictor = OfflinePredictor(pred_config)

        #file_list = glob.glob('%s/*%s' % (data_dir, img_ext))
        #file_list.sort() # ensure same order
        #if(not file_list):
        # print('No Images found in data_dir! Check script arg-paths')
        # Create Output Directory
        #rm_n_mkdir(output_dir)
        # Expecting MoNuSAC's input data directory tree (Patient Name -> Image Name -> )

        if not os.path.isdir(output_dir):
            os.makedirs(output_dir)
        os.chdir(output_dir)
        patients = [x[0] for x in os.walk(data_dir)
                    ]  #Total patients in the data_path
        print(len(patients))

        for patient_loc in patients:
            patient_name = patient_loc[len(data_dir) + 1:]  #Patient name
            print(patient_name, flush=True)

            ## To make patient's name directory in the destination folder
            try:
                os.mkdir(patient_name)
            except OSError:
                print("\n Creation of the patient's directory %s failed" %
                      patient_name,
                      flush=True)

            sub_images = glob(str(patient_loc) + '/*' + str(img_ext))
            for sub_image_loc in sub_images:
                sub_image_name = sub_image_loc[len(data_dir) +
                                               len(patient_name) + 1:-4]
                print(sub_image_name)

                ## To make sub_image directory under the patient's folder
                sub_image = './' + patient_name + sub_image_name  #Destination path
                try:
                    os.mkdir(sub_image)
                except OSError:
                    print("\n Creation of the patient's directory %s failed" %
                          sub_image)

                image_name = sub_image_loc
                if (img_ext == '.svs'):
                    img = openslide.OpenSlide(image_name)
                    cv2.imwrite(
                        sub_image_loc[:-4] + '.png',
                        np.array(
                            img.read_region((0, 0), 0,
                                            img.level_dimensions[0])))
                    img = cv2.imread(sub_image_loc[:-4] + '.png')
                else:
                    img = cv2.imread(image_name)
                    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

                ## Generate Prediction Map
                pred_map = self.__gen_prediction(img, predictor)
                pred = pred_map
                # Process Prediction Map
                pred_inst = pred[..., self.nr_types:]
                pred_type = pred[..., :self.nr_types]
                pred_inst = np.squeeze(pred_inst)
                pred_type = np.argmax(pred_type, axis=-1)
                pred_inst = postproc.hover.proc_np_hv(pred_inst,
                                                      marker_mode=marker_mode,
                                                      energy_mode=energy_mode,
                                                      rgb=img)
                pred_inst = remap_label(pred_inst, by_size=True)

                # Read Ambiguous Region mask if any
                ambi_mask_final = None
                save_mask = None
                full_ambi_path = ambi_path + '/' + patient_name + '/' + sub_image_name + '/Ambiguous'
                ambi_masks = glob(full_ambi_path + '/*')
                if (ambi_masks):
                    try:
                        ambi_mask_final = cv2.imread(ambi_masks[0])
                        print('Ambiguous Mask Found: ', ambi_mask_final.shape)
                        save_mask = ambi_mask_final
                        gray = cv2.cvtColor(ambi_mask_final,
                                            cv2.COLOR_BGR2GRAY)
                        count, ambi = cv2.connectedComponents(gray)

                        match_iou = 0.01  # Modify parameter experimentally
                        # Remove Ambiguous region
                        pairwise_iou = get_iou(true=ambi, pred=pred_inst)
                        matched_regions = np.array(pairwise_iou >= match_iou,
                                                   np.uint8)
                        matched_region_list = np.nonzero(matched_regions)[1]
                        pred_inst_copy = pred_inst.copy()
                        for id in matched_region_list:
                            region_id = id + 1
                            pred_inst[pred_inst == region_id] = 0

                        # Re-Order Cleaned pred_inst
                        pred_inst = remap_label(pred_inst, by_size=True)

                    except Exception as e:
                        print('\n\t [Warn] Ambiguous Region not removed : ', e)
                else:
                    print('\n\t No Ambiguous Masks for this image: ',
                          full_ambi_path)

                # Map Instances to Labels for creating submission format
                pred_id_list = list(
                    np.unique(pred_inst))[1:]  # exclude background ID
                pred_inst_type = np.full(len(pred_id_list), 0, dtype=np.int32)
                for idx, inst_id in enumerate(pred_id_list):
                    inst_type = pred_type[pred_inst == inst_id]
                    type_list, type_pixels = np.unique(inst_type,
                                                       return_counts=True)
                    type_list = list(zip(type_list, type_pixels))
                    type_list = sorted(type_list,
                                       key=lambda x: x[1],
                                       reverse=True)
                    inst_type = type_list[0][0]
                    if inst_type == 0:  # ! pick the 2nd most dominant if exist
                        if len(type_list) > 1:
                            inst_type = type_list[1][0]
                        else:
                            print('[Warn] Instance has `background` type')
                    pred_inst_type[idx] = inst_type

                # Write Instance Maps based on their Classes/Labels to the folders
                for class_id in range(1, self.nr_types):
                    separated_inst = pred_inst.copy()
                    separated_inst[pred_inst_type[separated_inst -
                                                  1] != [class_id]] = 0
                    separated_inst = separated_inst.astype(np.uint8)
                    # Create directory for each label
                    label = class_id_mapping[class_id]
                    sub_path = sub_image + '/' + label
                    try:
                        os.mkdir(sub_path)
                    except OSError:
                        print("Creation of the directory %s failed" % label)
                    else:
                        print("Successfully created the directory %s " % label)

                    # Check if Mask is empty then write
                    check = np.unique(separated_inst)
                    if ((len(check) == 1) & (check[0] == 0)):
                        print('Empty inst. Not writing.', check)
                    else:
                        sio.savemat(sub_path + '/mask.mat',
                                    {'n_ary_mask': separated_inst})
Example #4
0
            if cfg.model_type == 'np_hv':
                pred_inst = postproc.hover.proc_np_hv(pred_inst,
                                                      marker_mode=marker_mode,
                                                      energy_mode=energy_mode,
                                                      rgb=img)
            elif cfg.model_type == 'np_dist':
                pred_inst = postproc.hover.proc_np_dist(pred_inst)
            elif cfg.model_type == 'dist':
                pred_inst = postproc.dist.process(pred_inst)
            else:
                pred_inst = postproc.other.process(pred_inst, cfg.model_type)

            # ! will be extremely slow on WSI/TMA so it's advisable to comment this out
            # * remap once so that further processing faster (metrics calculation, etc.)
            pred_inst = remap_label(pred_inst, by_size=True)
            overlaid_output = visualize_instances(pred_inst, img)
            overlaid_output = cv2.cvtColor(overlaid_output, cv2.COLOR_BGR2RGB)
            cv2.imwrite('%s/%s.png' % (proc_dir, basename), overlaid_output)

            # for instance segmentation only
            if cfg.type_classification:
                #### * Get class of each instance id, stored at index id-1
                pred_id_list = list(
                    np.unique(pred_inst))[1:]  # exclude background ID
                pred_inst_type = np.full(len(pred_id_list), 0, dtype=np.int32)
                for idx, inst_id in enumerate(pred_id_list):
                    inst_type = pred_type[pred_inst == inst_id]
                    type_list, type_pixels = np.unique(inst_type,
                                                       return_counts=True)
                    type_list = list(zip(type_list, type_pixels))
Example #5
0
        def process_image(filename):
            filename = os.path.basename(filename)
            basename = filename.split(".")[0]
            if jobs == 1:
                print(pred_dir, basename, flush=True)

            ##
            img = cv2.imread(
                os.path.join(data_dir, "{}{}".format(basename,
                                                     cfg.inf_imgs_ext)))
            img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

            pred = sio.loadmat(
                os.path.join(pred_dir, "{}.mat".format(basename)))
            pred = np.squeeze(pred["result"])

            if hasattr(cfg, "type_classification") and cfg.type_classification:
                pred_inst = pred[..., cfg.nr_types:]
                pred_type = pred[..., :cfg.nr_types]

                pred_inst = np.squeeze(pred_inst)
                pred_type = np.argmax(pred_type, axis=-1)

            else:
                pred_inst = pred

            if cfg.model_type == "np_hv" or cfg.model_type == "np_hv_opt":
                pred_inst = postproc.hover.proc_np_hv(pred_inst,
                                                      marker_mode=marker_mode,
                                                      energy_mode=energy_mode,
                                                      rgb=img)
            elif cfg.model_type == "np_dist":
                pred_inst = postproc.hover.proc_np_dist(pred_inst)

            # ! will be extremely slow on WSI/TMA so it's advisable to comment this out
            # * remap once so that further processing faster (metrics calculation, etc.)
            if cfg.remap_labels:
                pred_inst = remap_label(pred_inst, by_size=True)

            # for instance segmentation only
            if cfg.type_classification:
                #### * Get class of each instance id, stored at index id-1
                pred_id_list = list(
                    np.unique(pred_inst))[1:]  # exclude background ID
                pred_inst_type = np.full(len(pred_id_list), 0, dtype=np.int32)
                for idx, inst_id in enumerate(pred_id_list):
                    inst_type = pred_type[pred_inst == inst_id]
                    type_list, type_pixels = np.unique(inst_type,
                                                       return_counts=True)
                    type_list = list(zip(type_list, type_pixels))
                    type_list = sorted(type_list,
                                       key=lambda x: x[1],
                                       reverse=True)
                    inst_type = type_list[0][0]
                    if inst_type == 0:  # ! pick the 2nd most dominant if exist
                        if len(type_list) > 1:
                            inst_type = type_list[1][0]
                        else:
                            if jobs == 1:
                                pass  # print('[Warn] Instance has `background` type')
                    pred_inst_type[idx] = inst_type
                pred_inst_centroid = get_inst_centroid(pred_inst)

                ###### ad hoc just once for pannuke predictions
                # for key in ['type_map', 'inst_type']:
                # pred_type[(pred_type == 5)] = 4
                # pred_inst_type[(pred_inst_type == 5)] = 4

                sio.savemat(
                    os.path.join(proc_dir, "{}.mat".format(basename)),
                    {
                        "inst_map": pred_inst,
                        "type_map": pred_type,
                        "inst_type": pred_inst_type[:, None],
                        "inst_centroid": pred_inst_centroid,
                    },
                )
                overlaid_output = visualize_instances(
                    pred_inst,
                    img,
                    ((cfg.nuclei_type_dict, cfg.color_palete),
                     pred_inst_type[:, None]),
                    cfg.outline,
                    cfg.skip_types,
                )
                overlaid_output = cv2.cvtColor(overlaid_output,
                                               cv2.COLOR_BGR2RGB)
                cv2.imwrite(os.path.join(proc_dir, "{}.png".format(basename)),
                            overlaid_output)
                with open(os.path.join(proc_dir, f"{basename}.log"),
                          "w") as log_file:
                    unique, counts = np.unique(pred_inst_type[:, None],
                                               return_counts=True)
                    unique = list(unique)
                    if 0 in unique:  # remove backround entries
                        counts = np.delete(counts, unique.index(0))
                        unique.remove(0)
                    print(
                        f"{basename} : {dict(zip([{str(v): str(k) for k, v in cfg.nuclei_type_dict.items()}[str(item)] for item in unique], counts))}",
                        file=log_file,
                    )

            else:
                sio.savemat(
                    os.path.join(proc_dir, "{}.mat".format(basename)),
                    {"inst_map": pred_inst},
                )
                overlaid_output = visualize_instances(pred_inst, img)
                overlaid_output = cv2.cvtColor(overlaid_output,
                                               cv2.COLOR_BGR2RGB)
                cv2.imwrite(
                    os.path.join(proc_dir, "{}_uc.png".format(basename)),
                    overlaid_output,
                )

            ##
            if jobs == 1:
                print(
                    f"Finished for {basename} {datetime.now().strftime('%H:%M:%S.%f')}"
                )
        lrbridge = np.logical_and(
            instance_map == 0,
            np.logical_and(np.logical_and(rightmap != 0, leftmap != 0),
                           rightmap == leftmap))
        instance_map[lrbridge] = rightmap[lrbridge]
        splitmap[lrbridge] = 1
        splitinst = instance_map * splitmap
        upmap = np.pad(splitinst, ((0, 2), (0, 0)), mode='constant')[2:, :]
        downmap = np.pad(splitinst, ((2, 0), (0, 0)), mode='constant')[:-2, :]
        udbridge = np.logical_and(
            instance_map == 0,
            np.logical_and(np.logical_and(upmap != 0, downmap != 0),
                           upmap == downmap))
        instance_map[udbridge] = upmap[udbridge]

        instance_map = remap_label(
            instance_map, by_size=True)  # This resets instance number from 0
        type_map = np.zeros(instance_map.shape, np.int32)
        instance_list = list(np.unique(instance_map))[
            1:]  # Background 0 excluded from instance list
        inst_type = np.full(len(instance_list), 0, dtype=np.int32)
        inst_type2 = np.full(len(instance_list), 0, dtype=np.int32)
        inst_size = np.full(len(instance_list), 0, dtype=np.int32)
        inst_length = np.full(len(instance_list), 0, dtype=np.float32)
        inst_centroids = get_inst_centroid(instance_map)
        for point in region["points"]:
            annot = annotDict(point["type"])
            inst_id = instance_map[(point["coor"][1] -
                                    (region["bound"][0][1] + 1),
                                    point["coor"][0] -
                                    (region["bound"][0][0] + 1))]
            if inst_id > 0:
Example #7
0
from metrics.stats_utils import remap_label

ann_dir = '/home/test/GhulamMurtaza/panNuke/Test/Labels/'  # * directory contains .npy
filepath_list = glob.glob('%s/*.npy' % ann_dir)

save_dir = 'GroundTruth/dump/'  # directory to save summarized info about nuclei

rm_n_mkdir(save_dir)
for path in filepath_list:
    basename = os.path.basename(path).split('.')[0]

    true_map = np.load(path)
    true_inst = true_map[..., 0]
    true_type = true_map[..., 1]

    true_inst = remap_label(true_inst, by_size=True)
    true_inst_centroid = get_inst_centroid(true_inst)
    #### * Get class of each instance id, stored at index id-1
    # for ground truth instance blob
    true_id_list = list(np.unique(true_inst))[1:]  # exclude background
    true_inst_type = np.full(len(true_id_list), -1, dtype=np.int32)
    for idx, inst_id in enumerate(true_id_list):
        inst_type = true_type[true_inst == inst_id]
        type_list, type_pixels = np.unique(inst_type, return_counts=True)
        inst_type = type_list[np.argmax(type_pixels)]
        if inst_type != 0:  # there are artifact nuclei (background types)
            true_inst_type[idx] = inst_type

    sio.savemat(
        '%s/%s.mat' % (save_dir, basename), {
            'inst_type': true_inst_type[:, None],
Example #8
0
    def run(self, data_dir, output_dir, model_path, img_ext='.png'):

        if (not data_dir):
            print('Using Config file path for data_dir.')
            data_dir = self.inf_data_dir
        if (not output_dir):
            print('Using Config file path for output_dir.')
            output_dir = self.inf_output_dir
        if (not model_path):
            print('Using placeholder path for model_dir.')
            model_path = '/home/dm1/shikhar/hover_net_modified/v2_multitask/np_hv/07/model-35854.index'
        if (not img_ext):
            print('Using Config img ext value img_ext.')
            img_ext = self.inf_imgs_ext

        model_constructor = self.get_model()
        pred_config = PredictConfig(
            model=model_constructor(),
            session_init=get_model_loader(model_path),
            input_names=self.eval_inf_input_tensor_names,
            output_names=self.eval_inf_output_tensor_names)
        predictor = OfflinePredictor(pred_config)

        #file_list = glob.glob('%s/*%s' % (data_dir, img_ext))
        #file_list.sort() # ensure same order
        #if(not file_list):
        # print('No Images found in data_dir! Check script arg-paths')
        # Create Output Directory
        #rm_n_mkdir(output_dir)
        # Expecting MoNuSAC's input data directory tree (Patient Name -> Image Name -> )

        if not os.path.isdir(output_dir):
            os.makedirs(output_dir)
        os.chdir(output_dir)
        patients = [x[0] for x in os.walk(data_dir)
                    ]  #Total patients in the data_path
        print(len(patients))

        for patient_loc in patients:
            patient_name = patient_loc[len(data_dir) + 1:]  #Patient name
            print(patient_name, flush=True)

            ## To make patient's name directory in the destination folder
            try:
                os.mkdir(patient_name)
            except OSError:
                print("\n Creation of the patient's directory %s failed" %
                      patient_name,
                      flush=True)

            sub_images = glob(str(patient_loc) + '/*' + str(img_ext))
            for sub_image_loc in sub_images:
                sub_image_name = sub_image_loc[len(data_dir) +
                                               len(patient_name) + 1:-4]
                print(sub_image_name)

                ## To make sub_image directory under the patient's folder
                sub_image = './' + patient_name + sub_image_name  #Destination path
                try:
                    os.mkdir(sub_image)
                except OSError:
                    print("\n Creation of the patient's directory %s failed" %
                          sub_image)

                image_name = sub_image_loc
                if (img_ext == '.svs'):
                    img = openslide.OpenSlide(image_name)
                    cv2.imwrite(
                        sub_image_loc[:-4] + '.png',
                        np.array(
                            img.read_region((0, 0), 0,
                                            img.level_dimensions[0])))
                    img = cv2.imread(sub_image_loc[:-4] + '.png')
                else:
                    img = cv2.imread(image_name)
                    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

                ## Generate Prediction Map
                pred_map = self.__gen_prediction(img, predictor)
                pred = pred_map
                # Process Prediction Map
                pred_inst = pred[..., self.nr_types:]
                pred_type = pred[..., :self.nr_types]
                pred_inst = np.squeeze(pred_inst)
                pred_type = np.argmax(pred_type, axis=-1)
                pred_inst = postproc.hover.proc_np_hv(pred_inst,
                                                      marker_mode=marker_mode,
                                                      energy_mode=energy_mode,
                                                      rgb=img)
                pred_inst = remap_label(pred_inst, by_size=True)

                # Map Instances to Labels for creating submission format
                pred_id_list = list(
                    np.unique(pred_inst))[1:]  # exclude background ID
                pred_inst_type = np.full(len(pred_id_list), 0, dtype=np.int32)
                for idx, inst_id in enumerate(pred_id_list):
                    inst_type = pred_type[pred_inst == inst_id]
                    type_list, type_pixels = np.unique(inst_type,
                                                       return_counts=True)
                    type_list = list(zip(type_list, type_pixels))
                    type_list = sorted(type_list,
                                       key=lambda x: x[1],
                                       reverse=True)
                    inst_type = type_list[0][0]
                    if inst_type == 0:  # ! pick the 2nd most dominant if exist
                        if len(type_list) > 1:
                            inst_type = type_list[1][0]
                        else:
                            print('[Warn] Instance has `background` type')
                    pred_inst_type[idx] = inst_type

                # Write Instance Maps based on their Classes/Labels to the folders
                for class_id in range(1, self.nr_types):
                    separated_inst = pred_inst.copy()
                    separated_inst[pred_inst_type[separated_inst -
                                                  1] != [class_id]] = 0
                    # Create directory for each label
                    label = class_id_mapping[class_id]
                    sub_path = sub_image + '/' + label
                    try:
                        os.mkdir(sub_path)
                    except OSError:
                        print("Creation of the directory %s failed" % label)
                    else:
                        print("Successfully created the directory %s " % label)

                    sio.savemat(sub_path + '/maskorempty.mat',
                                {'n_ary_mask': separated_inst})
Example #9
0
file_list = glob.glob(pred_dir + '*.png')
file_list.sort()  # ensure same order [1]

metrics = [[], [], [], [], []]
for filename in file_list:
    filename = os.path.basename(filename)
    basename = filename.split('.')[0]

    true = np.load(true_dir + basename + '.npy')
    true = true.astype('int32')

    pred = sio.loadmat(pred_dir + basename + '_predicted_map.mat')
    pred = (pred['predicted_map']).astype('int32')

    pred = remap_label(pred, by_size=True)
    true = remap_label(true, by_size=True)
    panoptic_quality = get_fast_panoptic_quality(true, pred, match_iou=0.5)
    metrics[0].append(get_dice_1(true, pred))
    metrics[1].append(panoptic_quality[0])  # dq
    metrics[2].append(panoptic_quality[1])  # sq
    metrics[3].append(metrics[1][-1] * metrics[2][-1])
    metrics[4].append(get_fast_aji(true, pred))

    if print_img_stats:
        print(basename, end="\t")
        for scores in metrics:
            print("%f " % scores[-1], end="\t")
        print()
####
metrics = np.array(metrics)
Example #10
0
        def process_image(filename):
            filename = os.path.basename(filename)
            basename = filename.split('.')[0]
            if not parallel: print(pred_dir, basename, flush=True)

            ##
            img = cv2.imread(os.path.join(data_dir, '{}{}'.format(basename, cfg.inf_imgs_ext)))
            img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

            pred = sio.loadmat(os.path.join(pred_dir, '{}.mat'.format(basename)))
            pred = np.squeeze(pred['result'])

            if hasattr(cfg, 'type_classification') and cfg.type_classification:
                pred_inst = pred[...,cfg.nr_types:]
                pred_type = pred[...,:cfg.nr_types]

                pred_inst = np.squeeze(pred_inst)
                pred_type = np.argmax(pred_type, axis=-1)

                if cfg.model_type == 'micronet':
                    # dilate prediction of all type to match it with
                    # the instance segmentation post-proc code
                    kernel = np.array([[0, 1, 0],
                                    [1, 1, 1],
                                    [0, 1, 0]], np.uint8)
                    canvas = np.zeros_like(pred_type, dtype=np.int32)
                    for type_id in range(1, cfg.nr_classes):
                        type_map = (pred_type == type_id).astype('uint8')
                        type_map = cv2.dilate(type_map, kernel, iterations=1)
                        canvas[type_map > 0] = type_id
            else:
                pred_inst = pred

            if cfg.model_type == 'np_hv' or cfg.model_type == 'np_hv_opt':
                pred_inst = postproc.hover.proc_np_hv(pred_inst,
                                marker_mode=marker_mode,
                                energy_mode=energy_mode, rgb=img)
            elif cfg.model_type == 'np_dist':
                pred_inst = postproc.hover.proc_np_dist(pred_inst)
            elif cfg.model_type == 'dist':
                pred_inst = postproc.dist.process(pred_inst)
            else:
                pred_inst = postproc.other.process(pred_inst, cfg.model_type)

            # ! will be extremely slow on WSI/TMA so it's advisable to comment this out
            # * remap once so that further processing faster (metrics calculation, etc.)
            if (cfg.remap_labels):
                pred_inst = remap_label(pred_inst, by_size=True)

            # for instance segmentation only
            if cfg.type_classification:
                #### * Get class of each instance id, stored at index id-1
                pred_id_list = list(np.unique(pred_inst))[1:] # exclude background ID
                pred_inst_type = np.full(len(pred_id_list), 0, dtype=np.int32)
                for idx, inst_id in enumerate(pred_id_list):
                    inst_type = pred_type[pred_inst == inst_id]
                    type_list, type_pixels = np.unique(inst_type, return_counts=True)
                    type_list = list(zip(type_list, type_pixels))
                    type_list = sorted(type_list, key=lambda x: x[1], reverse=True)
                    inst_type = type_list[0][0]
                    if inst_type == 0: # ! pick the 2nd most dominant if exist
                        if len(type_list) > 1:
                            inst_type = type_list[1][0]
                        else:
                            if not parallel: 
                                pass # print('[Warn] Instance has `background` type')
                    pred_inst_type[idx] = inst_type
                pred_inst_centroid = get_inst_centroid(pred_inst)


                ###### ad hoc just once for pannuke predictions
                # for key in ['type_map', 'inst_type']:
                # pred_type[(pred_type == 5)] = 4
                # pred_inst_type[(pred_inst_type == 5)] = 4

                sio.savemat(os.path.join(proc_dir, '{}.mat'.format(basename)),
                            {'inst_map'  :     pred_inst,
                            'type_map'  :     pred_type,
                            'inst_type' :     pred_inst_type[:, None],
                            'inst_centroid' : pred_inst_centroid,
                            })
                overlaid_output = visualize_instances(pred_inst, img, ((cfg.nuclei_type_dict, cfg.color_palete), pred_inst_type[:, None]), cfg.outline, cfg.skip_types)
                overlaid_output = cv2.cvtColor(overlaid_output, cv2.COLOR_BGR2RGB)
                cv2.imwrite(os.path.join(proc_dir, '{}.png'.format(basename)), overlaid_output)
                with open(os.path.join(proc_dir, f'{basename}.log'), 'w') as log_file:
                    unique, counts = np.unique(pred_inst_type[:, None], return_counts=True)
                    unique = list(unique)
                    if 0 in unique: # remove backround entries
                        counts = np.delete(counts, unique.index(0))
                        unique.remove(0)
                    print(f'{basename} : {dict(zip([{str(v): str(k) for k, v in cfg.nuclei_type_dict.items()}[str(item)] for item in unique], counts))}', file = log_file)

            else:
                sio.savemat(os.path.join(proc_dir, '{}.mat'.format(basename)),
                            {'inst_map'  : pred_inst})
                overlaid_output = visualize_instances(pred_inst, img)
                overlaid_output = cv2.cvtColor(overlaid_output, cv2.COLOR_BGR2RGB)
                cv2.imwrite(os.path.join(proc_dir, '{}_uc.png'.format(basename)), overlaid_output)

            ##
            if not parallel: print(f"Finished for {basename} {datetime.now().strftime('%H:%M:%S.%f')}")