Beispiel #1
0
    def parse_param(self, roi_settings):
        """ Parse parameters to extract roi info. """

        if lab_tools.is_lab_format(roi_settings):
            rois = roi_settings["annotations"]
        elif "roi" in roi_settings.keys():
            rois = roi_settings["roi"]
        else:
            self.logger.warning("No valid ROI found")
            return False

        self.rois = []
        for roi in rois:
            try:
                bb = tinycv.Rect([
                    max(0, roi['top']), roi['bottom'],
                    max(0, roi['left']), roi['right']
                ])
                if bb.b == -1 or bb.r == -1:
                    self.rois.append(None)
                else:
                    self.rois.append(bb)

            except BaseException:
                return False
        return True
Beispiel #2
0
 def __init__(self, dyda_config_path='', param=None):
     super(YTECDataConverter, self).__init__(
         dyda_config_path=dyda_config_path
     )
     class_name = self.__class__.__name__
     self.set_param(class_name, param=param)
     self.results = {}
     self.rect = tinycv.Rect()
Beispiel #3
0
    def parse_param(self):
        """ Parse parameters to extract roi info. """

        if self.use_external_meta:
            if isinstance(self.external_metadata, list) \
                    and len(self.external_metadata) == 1:
                if 'roi' not in self.external_metadata[0].keys():
                    self.logger.warning(
                        "No roi given and skip roi determinator")
                    return True
                rois = self.external_metadata[0]['roi']
            elif isinstance(self.external_metadata, dict):
                if 'roi' not in self.external_metadata.keys():
                    self.logger.warning(
                        "No roi given and skip roi determinator")
                    return True
                rois = self.external_metadata['roi']
            else:
                self.logger.error("Wrong external_metadata type")
                self.terminate_flag = True
                return False
            self.rois = []
            for roi in rois:
                bb = tinycv.Rect(
                    [roi['top'], roi['bottom'], roi['left'], roi['right']])
                if bb.r == -1 or bb.l == -1 or \
                        bb.t == -1 or bb.b == -1:
                    return True
                bb.th = roi['overlap_threshold']
                self.rois.append(bb)
        else:
            self.rois = []
            bb = tinycv.Rect([
                self.param['top'], self.param['bottom'], self.param['left'],
                self.param['right']
            ])
            if bb.r == -1 or bb.l == -1 or \
                    bb.t == -1 or bb.b == -1:
                return True
            bb.th = self.param['threshold']
            self.rois.append(bb)
        return False
Beispiel #4
0
    def __init__(self, dyda_config_path='', param=None):
        """ Initialization function of dyda component. """

        super(CropBoxProcessor,
              self).__init__(dyda_config_path=dyda_config_path)
        class_name = self.__class__.__name__
        self.set_param(class_name, param=param)
        self.roi = tinycv.Rect([
            self.param['top'], self.param['bottom'], self.param['left'],
            self.param['right']
        ])
Beispiel #5
0
    def crop_bb(self, data):
        """ Crop bounding boxes to roi given by config. """

        # check if roi exceeds image size
        width = data['size']['width']
        height = data['size']['height']
        if not (isinstance(width, int) and isinstance(height, int)):
            self.logger.warning("Can not check boundary "
                                "since no image size is given.")
        else:
            if self.roi.r >= width or self.roi.b >= height:
                self.terminate_flag = True
                self.logger.error("Roi exceeds image size.")
        data['size']['width'] = self.roi.w
        data['size']['height'] = self.roi.h

        # crop bounding boxes
        for idx in range(len(data['annotations']) - 1, -1, -1):
            obj = data['annotations'][idx]
            bb = tinycv.Rect(
                [obj['top'], obj['bottom'], obj['left'], obj['right']])

            # check if object in roi
            overlap_ratio = lab_tools.calculate_overlap_ratio(
                [self.roi.t, self.roi.b, self.roi.l, self.roi.r],
                [bb.t, bb.b, bb.l, bb.r],
                denominator_type='area_2')
            if overlap_ratio < self.param['overlap_threshold']:
                data['annotations'].pop(idx)
                continue

            # update bounding box of object
            obj['top'] = tinycv.check_boundary_limit(bb.t - self.roi.t,
                                                     self.roi.h)
            obj['left'] = tinycv.check_boundary_limit(bb.l - self.roi.l,
                                                      self.roi.w)
            obj['bottom'] = tinycv.check_boundary_limit(
                bb.b - self.roi.t, self.roi.h)
            obj['right'] = tinycv.check_boundary_limit(bb.r - self.roi.l,
                                                       self.roi.w)

        return (data)
Beispiel #6
0
    def main_process(self):
        """ Main function of dyda component. """

        self.reset_output()
        input_data = self.uniform_input(self.input_data)

        for data in input_data:
            img_h = data['size']['height']
            img_w = data['size']['width']
            for anno in data['annotations']:
                bb = tinycv.Rect(
                    [anno['top'], anno['bottom'], anno['left'], anno['right']])
                self.get_extension(bb.h, bb.w)
                anno['top'] = max(0, bb.t - self.top_extension)
                anno['bottom'] = min(img_h, bb.b + self.bottom_extension)
                anno['left'] = max(0, bb.l - self.left_extension)
                anno['right'] = min(img_w, bb.r + self.right_extension)
            self.results.append(data)

        self.uniform_output()
Beispiel #7
0
    def transform_anno(self, data, trans_info):
        """ Transform annotations. """

        for anno in data['annotations']:
            bb = tinycv.Rect(
                [anno['top'], anno['bottom'], anno['left'], anno['right']])
            lt = self.transform_point(bb.l, bb.t, trans_info)
            lb = self.transform_point(bb.l, bb.b, trans_info)
            rt = self.transform_point(bb.r, bb.t, trans_info)
            rb = self.transform_point(bb.r, bb.b, trans_info)
            anno['left'] = min(max(min([lt[0], lb[0], rt[0], rb[0]]), 0),
                               trans_info['size']['width'] - 1)
            anno['right'] = min(max(max([lt[0], lb[0], rt[0], rb[0]]), 1),
                                trans_info['size']['width'])
            anno['top'] = min(max(min([lt[1], lb[1], rt[1], rb[1]]), 0),
                              trans_info['size']['height'] - 1)
            anno['bottom'] = min(max(max([lt[1], lb[1], rt[1], rb[1]]), 1),
                                 trans_info['size']['height'])
        data['size'] = trans_info['size']
        return data
Beispiel #8
0
    def main_process(self):
        """ define main_process of dyda component """

        if len(self.input_data) != 2:
            self.terminate_flag = True
            self.logger.error(
                "Length of input_data is not 2 but %i." % len(self.input_data)
            )
            return False
        l1 = len(self.input_data[0])
        l2 = len(self.input_data[1])
        if l1 != l2:
            self.terminate_flag = True
            self.logger.error(
                "Lengths of two input lists are not the same."
            )
            return False

        conf_thre = 0.0
        if "conf_thre" in self.param.keys():
            conf_thre = self.param["conf_thre"]

        self.results = {
            "true_pos": 0,
            "false_pos": 0,
            "gt_number": 0,
            "mAP": 0,
            "lab_info": {}}

        predictions_data_all = self.input_data[0]
        ground_truth_data_all = self.input_data[1]

        nd = 0
        for data in predictions_data_all:
            nd += len(data['annotations'])

        gt_classes = []
        for data in ground_truth_data_all:
            for anno in data['annotations']:
                label = anno['label']
                if label not in gt_classes:
                    self.add_key_to_results(label)
                    gt_classes.append(label)
                lab_info = self.results["lab_info"]
                lab_info[label]['gt_number'] += 1

        lab_info = self.results["lab_info"]
        for class_index, class_name in enumerate(gt_classes):
            tp = [0] * nd
            fp = [0] * nd
            idx_obj = -1
            for idx, pred in enumerate(predictions_data_all):
                pred = lab_tools.extract_target_class(
                    copy.deepcopy(pred),
                    class_name
                )
                pred_anno = pred['annotations']
                pred_anno.sort(
                    key=lambda x: float(x['confidence']),
                    reverse=True)
                gt_anno = ground_truth_data_all[idx]['annotations']
                for obj in pred_anno:
                    idx_obj += 1
                    ovmax = -1
                    gt_match = -1
                    bb = tinycv.Rect([
                        obj['top'],
                        obj['bottom'],
                        obj['left'],
                        obj['right']])
                    for obj_gt in gt_anno:
                        if obj_gt["label"] != class_name:
                            continue
                        bbgt = tinycv.Rect(
                            [obj_gt['top'],
                             obj_gt['bottom'],
                             obj_gt['left'],
                             obj_gt['right']])
                        bi = [max(bb.l, bbgt.l),
                              max(bb.t, bbgt.t),
                              min(bb.r, bbgt.r),
                              min(bb.b, bbgt.b)]
                        iw = bi[2] - bi[0] + 1
                        ih = bi[3] - bi[1] + 1
                        if iw <= 0 or ih <= 0:
                            continue
                        ua = (bb.r - bb.l + 1) * \
                            (bb.b - bb.t + 1) + \
                            (bbgt.r - bbgt.l + 1) * \
                            (bbgt.b - bbgt.t + 1) - \
                            iw * ih
                        ov = iw * ih / ua
                        if ov <= ovmax:
                            continue
                        ovmax = ov
                        gt_match = obj_gt
                    min_overlap = self.param['min_overlap']
                    if ovmax >= min_overlap:
                        if "used" not in gt_match.keys(
                        ) or not bool(gt_match["used"]):
                            # true positive
                            tp[idx_obj] = 1
                            gt_match["used"] = True
                            lab_info[class_name]['true_pos'] += 1
                        else:
                            # false positive
                            lab_info[class_name]['false_pos'] += 1
                            fp[idx_obj] = 1
                    else:
                        # false positive
                        lab_info[class_name]['false_pos'] += 1
                        fp[idx_obj] = 1
                        if ovmax > 0:
                            status = "insufficient overlap"

            # get precision and recall
            data = lab_info[class_name]
            self.get_prec_and_recall(data)
            self.results['true_pos'] += data['true_pos']
            self.results['false_pos'] += data['false_pos']
            self.results['gt_number'] += data['gt_number']

            # get voc average precision
            cumsum = 0
            for idx, val in enumerate(fp):
                fp[idx] += cumsum
                cumsum += val
            cumsum = 0
            for idx, val in enumerate(tp):
                tp[idx] += cumsum
                cumsum += val
            rec = tp[:]
            for idx, val in enumerate(tp):
                rec[idx] = self.div(
                    tp[idx],
                    lab_info[class_name]['true_pos'])
            prec = tp[:]
            for idx, val in enumerate(tp):
                prec[idx] = self.div(
                    tp[idx],
                    fp[idx] + tp[idx])

            lab_info[class_name]['ap'] = self.get_voc_ap(rec, prec)
            self.results['mAP'] += lab_info[class_name]['ap']

        self.get_prec_and_recall(self.results)
        self.results['mAP'] = self.div(
            self.results['mAP'],
            len(gt_classes))