def get_instances(self, preds, gts, ignore_mask=None):
        """
        In this method, we create two dicts of list
        - pred_instances: contains all predictions and their associated gt.
        - gtInstances:   contains all gt instances and their associated predictions.

        Args:
            preds (list): Prediction of image.
            gts (list): Ground truth of image.
            ignore_mask (np.ndarray, optional): Ignore mask. Default: None.

        Returns:
            dict: pred_instances, the type is dict(list(dict))), e.g. {0: [{'pred_id':0, 'label':0',
                'pixel_count':100, 'confidence': 0.9, 'void_intersection': 0,
                'matched_gt': [gt_instance0, gt_instance1, ...]}, ], 1: }
            dict: gt_instances,  the type is dict(list(dict))), e.g. {0: [{'inst_id':0, 'label':0',
                'pixel_count':100, 'mask': np.ndarray, 'matched_pred': [pred_instance0, pred_instance1, ...]}, ], 1: }
        """

        pred_instances = defaultdict(list)
        gt_instances = defaultdict(list)

        gt_inst_count = 0
        for gt in gts:
            label, mask = gt
            gt_instance = defaultdict(list)
            gt_instance['inst_id'] = gt_inst_count
            gt_instance['label'] = label
            gt_instance['pixel_count'] = np.count_nonzero(mask)
            gt_instance['mask'] = mask
            gt_instances[label].append(gt_instance)
            gt_inst_count += 1

        pred_inst_count = 0
        for pred in preds:
            label, conf, mask = pred
            pred_instance = defaultdict(list)
            pred_instance['label'] = label
            pred_instance['pred_id'] = pred_inst_count
            pred_instance['pixel_count'] = np.count_nonzero(mask)
            pred_instance['confidence'] = conf
            if ignore_mask is not None:
                pred_instance['void_intersection'] = np.count_nonzero(
                    np.logical_and(mask, ignore_mask))

            # Loop through all ground truth instances with matching label
            matched_gt = []
            for gt_num, gt_instance in enumerate(gt_instances[label]):
                intersection = np.count_nonzero(
                    np.logical_and(mask, gt_instances[label][gt_num]['mask']))
                if intersection > 0:
                    gt_copy = gt_instance.copy()
                    pred_copy = pred_instance.copy()

                    gt_copy['intersection'] = intersection
                    pred_copy['intersection'] = intersection

                    matched_gt.append(gt_copy)
                    gt_instances[label][gt_num]['matched_pred'].append(
                        pred_copy)

            pred_instance['matched_gt'] = matched_gt
            pred_inst_count += 1
            pred_instances[label].append(pred_instance)

        return pred_instances, gt_instances

        In this method, we create two dicts of list
        - pred_instances: contains all predictions and their associated gt.
        - gtInstances:   contains all gt instances and their associated predictions.

        Args:
            preds (list): Prediction of image.
            gts (list): Ground truth of image.
            ignore_mask (np.ndarray, optional): Ignore mask. Default: None.

        Returns:
            dict: pred_instances, the type is dict(list(dict))), e.g. {0: [{'pred_id':0, 'label':0',
                'pixel_count':100, 'confidence': 0.9, 'void_intersection': 0,
                'matched_gt': [gt_instance0, gt_instance1, ...]}, ], 1: }
            dict: gt_instances,  the type is dict(list(dict))), e.g. {0: [{'inst_id':0, 'label':0',
                'pixel_count':100, 'mask': np.ndarray, 'matched_pred': [pred_instance0, pred_instance1, ...]}, ], 1: }
        
contrib/PanopticSeg/paddlepanseg/utils/evaluation/ins_seg_evaluator.py