Exemple #1
0
    def object_init_data(self, frame_num=None) -> dict:
        """

        :param frame_num: 0
        :return: {'init_object_ids', 'init_mask', 'object_ids', 'sequence_object_ids'}
        """
        if frame_num is None:
            frame_num = 0
        if frame_num not in self.init_data:
            # 不是第0帧就返回空dictionary
            return dict()

        init_data = dict()
        # 把self.init_data的东西移到init_data中,keys以'init_'开头
        for key, val in self.init_data[frame_num].items():
            if val is None:
                continue
            init_data['init_' + key] = val

        if 'init_mask' in init_data and init_data['init_mask'] is not None:
            # read mask image to numpy array
            anno = imread_indexed(init_data['init_mask'])
            if not self.multiobj_mode and self.object_ids is not None:
                assert len(self.object_ids) == 1
                anno = (anno == int(self.object_ids[0])).astype(np.uint8)
            init_data['init_mask'] = anno

        if self.object_ids is not None:
            # self.object_ids = sequence_info['object_ids']
            init_data['object_ids'] = self.object_ids
            init_data['sequence_object_ids'] = self.object_ids

        # init_object_ids == object_ids == sequence_object_ids
        return init_data
Exemple #2
0
    def get_image_info(self, im_id):
        mask = imread_indexed(
            os.path.join(self.root, 'Imgs',
                         '{}.png'.format(self.image_list[im_id])))
        mask = torch.Tensor(mask == 255)
        bbox = masks_to_bboxes(mask, fmt='t').view(4, )

        valid = (bbox[2] > 0) & (bbox[3] > 0)
        visible = valid.clone().byte()

        return {'bbox': bbox, 'mask': mask, 'valid': valid, 'visible': visible}
Exemple #3
0
    def _load_dataset(self, min_area=None):
        files_list = os.listdir(os.path.join(self.root, 'Imgs'))
        image_list = [f[:-4] for f in files_list if f[-3:] == 'jpg']

        images = []

        for f in image_list:
            a = imread_indexed(
                os.path.join(self.root, 'Imgs', '{}.png'.format(f)))

            if min_area is None or (a > 0).sum() > min_area:
                images.append(f)

        return images
Exemple #4
0
    def _load_dataset(self, min_area=None):
        files_list = os.listdir(os.path.join(self.root, 'imgs'))
        image_list = [f[:-4] for f in files_list]

        images = []
        annos = []

        for f in image_list:
            a = imread_indexed(
                os.path.join(self.root, 'gt', '{}.png'.format(f)))

            if min_area is None or (a > 0).sum() > min_area:
                im = opencv_loader(
                    os.path.join(self.root, 'imgs', '{}.png'.format(f)))
                images.append(im)
                annos.append(a)

        return images, annos
Exemple #5
0
    def object_init_data(self, frame_num=None) -> dict:
        if frame_num is None:
            frame_num = 0
        if frame_num not in self.init_data:
            return dict()

        init_data = dict()
        for key, val in self.init_data[frame_num].items():
            if val is None:
                continue
            init_data['init_' + key] = val

        if 'init_mask' in init_data and init_data['init_mask'] is not None:
            anno = imread_indexed(init_data['init_mask'])
            if not self.multiobj_mode and self.object_ids is not None:
                assert len(self.object_ids) == 1
                anno = (anno == int(self.object_ids[0])).astype(np.uint8)
            init_data['init_mask'] = anno

        if self.object_ids is not None:
            init_data['object_ids'] = self.object_ids
            init_data['sequence_object_ids'] = self.object_ids

        return init_data
Exemple #6
0
    def generate(cls, dset_name: str, dset_images_path: Path,
                 dset_annos_path: Path):
        """
        Count the annotation mask pixels per object, per frame, in all sequences in a dataset
        :param dset_name:        Dataset name, for printing the progress bar.
        :param dset_annos_path:  Path to annotations directory, containing sequence directories,
                                 with annotation frames in them.

        :return: Dataset meta dict:

        {'sequence0':
            {
             'shape': (height, width)

             'obj_sizes':  # Object pixels per frame
                {'frame0': {'object0': px_count, 'object1': px_count, ...},
                 'frame1': {'object0': px_count, 'object1': px_count, ...},
                ... },

             'bboxes':  # Bounding boxes per frame
                {'frame0': {'object0': bbox, 'object1': bbox, ...},
                 'frame1': {'object0': bbox, 'object1': bbox, ...},
                ... },
            ...
        }
        """
        assert (dset_annos_path.exists())

        dset_meta = OrderedDict()
        sequences = [
            p.stem for p in sorted(dset_annos_path.glob("*")) if p.is_dir()
        ]

        try:
            from tqdm import tqdm
        except:

            def tqdm(x, *args, **kwargs):
                return x

        for seq in tqdm(sequences, desc=dset_name, unit="seq"):

            obj_sizes2 = defaultdict(OrderedDict)
            bboxes = defaultdict(OrderedDict)
            shape = None
            frame_names = [
                file.stem
                for file in sorted((dset_images_path / seq).glob("*.jpg"))
            ]
            anno_paths = list(sorted((dset_annos_path / seq).glob("*.png")))

            # Extract information from the given label frames
            for path in anno_paths:
                f_id = path.stem

                # Count label-pixels per frame
                labels = imread_indexed(path)
                # labels = np.array(Image.open(path))
                obj_ids, obj_sizes = np.unique(labels, return_counts=True)
                obj_ids = [str(oid) for oid in obj_ids]
                obj_sizes = obj_sizes.tolist()

                if '0' in obj_ids:  # Remove background id
                    obj_ids = obj_ids[1:]
                    obj_sizes = obj_sizes[1:]
                obj_sizes2[f_id] = OrderedDict(zip(obj_ids, obj_sizes))

                # Generate per-label bounding boxes
                for obj_id in obj_ids:
                    bboxes[f_id][obj_id] = cls._mask_to_bbox(
                        labels == int(obj_id))

                if shape is None:
                    shape = labels.shape[:2]

            # Format result

            dset_meta[seq] = dict(shape=shape,
                                  obj_sizes=obj_sizes2,
                                  bboxes=bboxes,
                                  frame_names=frame_names)

        return VOSMeta(dset_meta)
Exemple #7
0
 def _load_anno(path):
     if not path.exists():
         return None
     # im = np.atleast_3d(np.array(Image.open(path)))
     im = imread_indexed(path)
     return im
Exemple #8
0
def evaluate_dataset(results_path,
                     dset_name,
                     measure='J',
                     to_file=True,
                     scores=False,
                     sequences=None,
                     quiet=False):
    dset = get_dataset(dset_name)
    results = OrderedDict()
    dset_scores = []
    dset_decay = []
    dset_recall = []

    if to_file:
        f = open(results_path / ("evaluation-%s.txt" % measure), "w")

    def _print(msg):
        if not quiet:
            print(msg)
        if to_file:
            print(msg, file=f)

    if sequences is not None:
        sequences = [sequences] if not isinstance(sequences,
                                                  (list, tuple)) else sequences

    target_names = []
    for j, sequence in enumerate(dset):
        if (sequences is not None) and (sequence.name not in sequences):
            continue

        # Load all frames
        frames = sequence.ground_truth_seg

        annotations = OrderedDict()
        segmentations = OrderedDict()

        for f in frames:
            if f is None:
                continue

            file = Path(f)
            annotations[file.name] = imread_indexed(file)
            if not scores:
                segmentations[file.name] = imread_indexed(
                    os.path.join(results_path, sequence.name, file.name))
            else:
                raise NotImplementedError
        # Find object ids and starting frames

        object_info = dict()

        for f_id, d in sequence.init_data.items():
            for obj_id in d['object_ids']:
                object_info[int(obj_id)] = Path(d['mask']).name

        if 0 in object_info:  # Remove background
            object_info.pop(0)

        # Evaluate
        n_seqs = len(dset)
        n_objs = len(object_info)
        seq_name = sequence.name

        _print("%d/%d: %s: %d object%s" %
               (j + 1, n_seqs, seq_name, n_objs, "s" if n_objs > 1 else ""))
        r = evaluate_sequence(seq_name,
                              segmentations,
                              annotations,
                              object_info,
                              measure=measure)
        results[seq_name] = r

        # Print scores, per frame and object, ignoring NaNs

        per_obj_score = []  # Per-object accuracies, averaged over the sequence
        per_frame_score = []  # Per-frame accuracies, averaged over the objects

        for obj_id, score in r['raw'].items():
            target_names.append('{}_{}'.format(seq_name, obj_id))
            per_frame_score.append(score)
            s = utils.mean(score)  # Sequence average for one object
            per_obj_score.append(s)
            if n_objs > 1:
                _print("joint {obj}: acc {score:.3f} ┊{apf}┊".format(
                    obj=obj_id, score=s, apf=utils.text_bargraph(score)))

        # Print mean object score per frame and final score
        dset_decay.extend(r['decay'])
        dset_recall.extend(r['recall'])
        dset_scores.extend(per_obj_score)

        seq_score = utils.mean(per_obj_score)  # Final score
        seq_mean_score = utils.nanmean(np.array(per_frame_score),
                                       axis=0)  # Mean object score per frame

        # Print sequence results
        _print("final  : acc {seq:.3f} ({dset:.3f}) ┊{apf}┊".format(
            seq=seq_score,
            dset=np.mean(dset_scores),
            apf=utils.text_bargraph(seq_mean_score)))

    _print("%s: %.3f, recall: %.3f, decay: %.3f" %
           (measure, utils.mean(dset_scores), utils.mean(dset_recall),
            utils.mean(dset_decay)))

    if to_file:
        f.close()

    return target_names, dset_scores, dset_recall, dset_decay