def test_converters_gts():
    # Defining paths with images and annotations
    images_dir = 'data/database/images'
    gts_dir = 'data/database/gts'
    assert os.path.isdir(images_dir)
    assert os.path.isdir(gts_dir)

    # COCO
    coco_dir = os.path.join(gts_dir, 'coco_format_v1')
    coco_bbs_v1 = converter.coco2bb(coco_dir)
    coco_bbs_v1.sort(key=lambda x: str(x), reverse=True)
    # COCO
    coco_dir = os.path.join(gts_dir, 'coco_format_v2')
    coco_bbs_v2 = converter.coco2bb(coco_dir)
    coco_bbs_v2.sort(key=lambda x: str(x), reverse=True)
    # CVAT
    cvat_dir = os.path.join(gts_dir, 'cvat_format')
    cvat_bbs = converter.cvat2bb(cvat_dir)
    cvat_bbs.sort(key=lambda x: str(x), reverse=True)
    # IMAGENET
    imagenet_dir = os.path.join(gts_dir, 'imagenet_format/Annotations')
    imagenet_bbs = converter.imagenet2bb(imagenet_dir)
    imagenet_bbs.sort(key=lambda x: str(x), reverse=True)
    # LABEL ME
    labelme_dir = os.path.join(gts_dir, 'labelme_format')
    labelme_bbs = converter.labelme2bb(labelme_dir)
    labelme_bbs.sort(key=lambda x: str(x), reverse=True)
    # OPEN IMAGE
    openimage_dir = os.path.join(gts_dir, 'openimages_format')
    openimage_bbs = converter.openimage2bb(openimage_dir, images_dir)
    openimage_bbs.sort(key=lambda x: str(x), reverse=True)
    # VOC PASCAL
    vocpascal_dir = os.path.join(gts_dir, 'pascalvoc_format')
    vocpascal_bbs = converter.vocpascal2bb(vocpascal_dir)
    vocpascal_bbs.sort(key=lambda x: str(x), reverse=True)
    # YOLO
    yolo_annotations_dir = os.path.join(gts_dir, 'yolo_format/obj_train_data')
    yolo_names_file = os.path.join(gts_dir, 'yolo_format/obj.names')
    yolo_bbs = converter.yolo2bb(yolo_annotations_dir,
                                 images_dir,
                                 yolo_names_file,
                                 bb_type=BBType.GROUND_TRUTH)
    yolo_bbs.sort(key=lambda x: str(x), reverse=True)

    assert len(coco_bbs_v1) == len(coco_bbs_v2) == len(cvat_bbs) == len(
        imagenet_bbs) == len(labelme_bbs) == len(openimage_bbs) == len(
            vocpascal_bbs) == len(yolo_bbs)

    for coco_bb_v1, coco_bb_v2, cvat_bb, imagenet_bb, labelme_bb, openimage_bb, vocpascal_bb, yolo_bb in zip(
            coco_bbs_v1, coco_bbs_v2, cvat_bbs, imagenet_bbs, labelme_bbs,
            openimage_bbs, vocpascal_bbs, yolo_bbs):
        assert coco_bb_v1 == coco_bb_v2 == cvat_bb == imagenet_bb == labelme_bb == openimage_bb == vocpascal_bb == yolo_bb
 def load_annotations_gt(self):
     ret = []
     if self.rad_gt_format_coco_json.isChecked():
         ret = converter.coco2bb(self.dir_annotations_gt)
     elif self.rad_gt_format_cvat_xml.isChecked():
         ret = converter.cvat2bb(self.dir_annotations_gt)
     elif self.rad_gt_format_openimages_csv.isChecked():
         ret = converter.openimage2bb(self.dir_annotations_gt,
                                      self.dir_images_gt,
                                      BBType.GROUND_TRUTH)
     elif self.rad_gt_format_labelme_xml.isChecked():
         ret = converter.labelme2bb(self.dir_annotations_gt)
     elif self.rad_gt_format_pascalvoc_xml.isChecked():
         ret = converter.vocpascal2bb(self.dir_annotations_gt)
     elif self.rad_gt_format_imagenet_xml.isChecked():
         ret = converter.imagenet2bb(self.dir_annotations_gt)
     elif self.rad_gt_format_abs_values_text.isChecked():
         ret = converter.text2bb(self.dir_annotations_gt,
                                 bb_type=BBType.GROUND_TRUTH)
     elif self.rad_gt_format_yolo_text.isChecked():
         ret = converter.yolo2bb(self.dir_annotations_gt,
                                 self.dir_images_gt,
                                 self.filepath_classes_gt,
                                 bb_type=BBType.GROUND_TRUTH)
     # Make all types as GT
     [bb.set_bb_type(BBType.GROUND_TRUTH) for bb in ret]
     return ret
def test_toy_example_gts():
    ############################################################################
    # Verify if all files in the toy example follow their expected format
    ############################################################################

    # PASCAL VOC
    dir_annots_gts_pascal = 'toyexample/gts_vocpascal_format'
    files = general_utils.get_files_recursively(dir_annots_gts_pascal)
    assert len(files) > 0
    for f in files:
        assert validations.is_pascal_format(
            f), 'File {f} does not follow the expected format (PASCAL VOC)'

    # COCO
    dir_annots_gts_coco = 'toyexample/gts_coco_format'
    files = general_utils.get_files_recursively(dir_annots_gts_coco)
    assert len(files) > 0
    for f in files:
        assert validations.is_coco_format(f), 'File {f} does not follow the expected format (COCO)'

    ############################################################################
    # Compare if all bounding boxes are the same
    ############################################################################
    pascal_bbs = converter.vocpascal2bb(dir_annots_gts_pascal)
    coco_bbs = converter.coco2bb(dir_annots_gts_coco)

    coco_bbs.sort(key=lambda x: str(x), reverse=True)
    pascal_bbs.sort(key=lambda x: str(x), reverse=True)

    assert len(coco_bbs) == len(pascal_bbs)

    for coco_bb, pascal_bb in zip(coco_bbs, pascal_bbs):
        assert coco_bb == pascal_bb
    def load_annotations_det(self):
        ret = []
        if not self.validate_det_choices():
            return ret, False

        if self.rad_det_format_coco_json.isChecked():
            ret = converter.coco2bb(self.dir_dets, bb_type=BBType.DETECTED)
        elif self.rad_det_ci_format_text_xywh_rel.isChecked(
        ) or self.rad_det_cn_format_text_xywh_rel.isChecked():
            ret = converter.text2bb(self.dir_dets,
                                    bb_type=BBType.DETECTED,
                                    bb_format=BBFormat.XYWH,
                                    type_coordinates=CoordinatesType.RELATIVE,
                                    img_dir=self.dir_images_gt)
        elif self.rad_det_ci_format_text_xyx2y2_abs.isChecked(
        ) or self.rad_det_cn_format_text_xyx2y2_abs.isChecked():
            ret = converter.text2bb(self.dir_dets,
                                    bb_type=BBType.DETECTED,
                                    bb_format=BBFormat.XYX2Y2,
                                    type_coordinates=CoordinatesType.ABSOLUTE,
                                    img_dir=self.dir_images_gt)
        elif self.rad_det_ci_format_text_xywh_abs.isChecked(
        ) or self.rad_det_cn_format_text_xywh_abs.isChecked():
            ret = converter.text2bb(self.dir_dets,
                                    bb_type=BBType.DETECTED,
                                    bb_format=BBFormat.XYWH,
                                    type_coordinates=CoordinatesType.ABSOLUTE,
                                    img_dir=self.dir_images_gt)
        # If detection requires class_id, replace the detection names (integers) by a class from the txt file
        if self.rad_det_ci_format_text_xywh_rel.isChecked(
        ) or self.rad_det_ci_format_text_xyx2y2_abs.isChecked(
        ) or self.rad_det_ci_format_text_xywh_abs.isChecked():
            ret = self.replace_id_with_classes(ret, self.filepath_classes_det)
        return ret, True
    def load_annotations_det(self):
        ret = []
        if not self.validate_det_choices():
            return ret, False

        if self.rad_det_format_coco_json.isChecked():
            ret = converter.coco2bb(self.dir_dets, bb_type=BBType.DETECTED)
        elif self.rad_det_ci_format_text_yolo_rel.isChecked(
        ) or self.rad_det_cn_format_text_yolo_rel.isChecked():
            ret = converter.text2bb(self.dir_dets,
                                    bb_type=BBType.DETECTED,
                                    bb_format=BBFormat.YOLO,
                                    type_coordinates=CoordinatesType.RELATIVE,
                                    img_dir=self.dir_images_gt)
        elif self.rad_det_ci_format_text_xyx2y2_abs.isChecked(
        ) or self.rad_det_cn_format_text_xyx2y2_abs.isChecked():
            ret = converter.text2bb(self.dir_dets,
                                    bb_type=BBType.DETECTED,
                                    bb_format=BBFormat.XYX2Y2,
                                    type_coordinates=CoordinatesType.ABSOLUTE,
                                    img_dir=self.dir_images_gt)
        elif self.rad_det_ci_format_text_xywh_abs.isChecked(
        ) or self.rad_det_cn_format_text_xywh_abs.isChecked():
            ret = converter.text2bb(self.dir_dets,
                                    bb_type=BBType.DETECTED,
                                    bb_format=BBFormat.XYWH,
                                    type_coordinates=CoordinatesType.ABSOLUTE,
                                    img_dir=self.dir_images_gt)
        # Verify if for the selected format, detections were found
        if len(ret) == 0:
            self.show_popup(
                'No file was found for the selected detection format in the annotations directory.',
                'No file was found',
                buttons=QMessageBox.Ok,
                icon=QMessageBox.Information)
            return ret, False

        # If detection requires class_id, replace the detection names (integers) by a class from the txt file
        if self.rad_det_ci_format_text_yolo_rel.isChecked(
        ) or self.rad_det_ci_format_text_xyx2y2_abs.isChecked(
        ) or self.rad_det_ci_format_text_xywh_abs.isChecked():
            ret = general_utils.replace_id_with_classes(
                ret, self.filepath_classes_det)
        return ret, True
def test_toy_example_dets_compatibility():
    # Checks if all different formats in the toyexample represent the same coordinates
    dir_img_dir = 'toyexample/images'
    filepath_classes_det = 'toyexample/voc.names'

    dir_dets_classid_abs_xywh = 'toyexample/dets_classid_abs_xywh'
    dets_classid_abs_xywh = converter.text2bb(dir_dets_classid_abs_xywh,
                                              bb_type=BBType.DETECTED,
                                              bb_format=BBFormat.XYWH,
                                              type_coordinates=CoordinatesType.ABSOLUTE)
    dets_classid_abs_xywh = general_utils.replace_id_with_classes(dets_classid_abs_xywh,
                                                                  filepath_classes_det)
    dets_classid_abs_xywh.sort(key=lambda x: str(x), reverse=True)

    dir_dets_classid_abs_xyx2y2 = 'toyexample/dets_classid_abs_xyx2y2'
    dets_classid_abs_xyx2y2 = converter.text2bb(dir_dets_classid_abs_xyx2y2,
                                                bb_type=BBType.DETECTED,
                                                bb_format=BBFormat.XYX2Y2,
                                                type_coordinates=CoordinatesType.ABSOLUTE)
    dets_classid_abs_xyx2y2 = general_utils.replace_id_with_classes(dets_classid_abs_xyx2y2,
                                                                    filepath_classes_det)
    dets_classid_abs_xyx2y2.sort(key=lambda x: str(x), reverse=True)

    dir_dets_classid_rel_xcycwh = 'toyexample/dets_classid_rel_xcycwh'
    dets_classid_rel_xcycwh = converter.text2bb(dir_dets_classid_rel_xcycwh,
                                                bb_type=BBType.DETECTED,
                                                bb_format=BBFormat.YOLO,
                                                type_coordinates=CoordinatesType.RELATIVE,
                                                img_dir=dir_img_dir)
    dets_classid_rel_xcycwh = general_utils.replace_id_with_classes(dets_classid_rel_xcycwh,
                                                                    filepath_classes_det)
    dets_classid_rel_xcycwh.sort(key=lambda x: str(x), reverse=True)

    dir_dets_classname_abs_xywh = 'toyexample/dets_classname_abs_xywh'
    dets_classname_abs_xywh = converter.text2bb(dir_dets_classname_abs_xywh,
                                                bb_type=BBType.DETECTED,
                                                bb_format=BBFormat.XYWH,
                                                type_coordinates=CoordinatesType.ABSOLUTE)
    dets_classname_abs_xywh.sort(key=lambda x: str(x), reverse=True)

    dir_dets_classname_abs_xyx2y2 = 'toyexample/dets_classname_abs_xyx2y2'
    dets_classname_abs_xyx2y2 = converter.text2bb(dir_dets_classname_abs_xyx2y2,
                                                  bb_type=BBType.DETECTED,
                                                  bb_format=BBFormat.XYX2Y2,
                                                  type_coordinates=CoordinatesType.ABSOLUTE)
    dets_classname_abs_xyx2y2.sort(key=lambda x: str(x), reverse=True)

    dir_dets_classname_rel_xcycwh = 'toyexample/dets_classname_rel_xcycwh'
    dets_classname_rel_xcycwh = converter.text2bb(dir_dets_classname_rel_xcycwh,
                                                  bb_type=BBType.DETECTED,
                                                  bb_format=BBFormat.YOLO,
                                                  type_coordinates=CoordinatesType.RELATIVE,
                                                  img_dir=dir_img_dir)
    dets_classname_rel_xcycwh.sort(key=lambda x: str(x), reverse=True)

    dir_dets_coco_format = 'toyexample/dets_coco_format'
    dets_coco_format = converter.coco2bb(dir_dets_coco_format, bb_type=BBType.DETECTED)
    dets_coco_format.sort(key=lambda x: str(x), reverse=True)

    for a, b, c, d, e, f, g in zip(dets_classid_abs_xywh, dets_classid_abs_xyx2y2,
                                   dets_classid_rel_xcycwh, dets_classname_abs_xywh,
                                   dets_classname_abs_xyx2y2, dets_classname_rel_xcycwh,
                                   dets_coco_format):
        assert a == b == c == d == e == f == g
Пример #7
0
    def load_annotations_det(self):
        ret = []
        # If relative format was required
        if self.rad_det_ci_format_text_xywh_rel.isChecked(
        ) or self.rad_det_cn_format_text_xywh_rel.isChecked():
            # Verify if directory with images was provided
            if self.dir_images_gt is None or not os.path.isdir(self.dir_images_gt):
                self.show_popup(
                    f'For the selected annotation type, it is necessary to inform a directory with the dataset images.\nDirectory is empty or does not have valid images.',
                    'Invalid image directory',
                    buttons=QMessageBox.Ok,
                    icon=QMessageBox.Information)
                return ret, False
        if self.rad_det_format_coco_json.isChecked():
            ret = converter.coco2bb(self.dir_dets, bb_type=BBType.DETECTED)
        elif self.rad_det_ci_format_text_xywh_rel.isChecked(
        ) or self.rad_det_cn_format_text_xywh_rel.isChecked():
            ret = converter.text2bb(self.dir_dets,
                                    bb_type=BBType.DETECTED,
                                    bb_format=BBFormat.XYWH,
                                    type_coordinates=CoordinatesType.RELATIVE,
                                    img_dir=self.dir_images_gt)
        elif self.rad_det_ci_format_text_xyx2y2_abs.isChecked(
        ) or self.rad_det_cn_format_text_xyx2y2_abs.isChecked():
            ret = converter.text2bb(self.dir_dets,
                                    bb_type=BBType.DETECTED,
                                    bb_format=BBFormat.XYX2Y2,
                                    type_coordinates=CoordinatesType.ABSOLUTE,
                                    img_dir=self.dir_images_gt)
        elif self.rad_det_ci_format_text_xywh_abs.isChecked(
        ) or self.rad_det_cn_format_text_xywh_abs.isChecked():
            ret = converter.text2bb(self.dir_dets,
                                    bb_type=BBType.DETECTED,
                                    bb_format=BBFormat.XYWH,
                                    type_coordinates=CoordinatesType.ABSOLUTE,
                                    img_dir=self.dir_images_gt)

        # if its format is in a format that requires class_id, replace the class_id by the class name
        if self.rad_det_ci_format_text_xywh_rel.isChecked(
        ) or self.rad_det_ci_format_text_xyx2y2_abs.isChecked(
        ) or self.rad_det_ci_format_text_xywh_abs.isChecked():
            if self.filepath_classes_det is None or os.path.isfile(
                    self.filepath_classes_det) is False or len(
                        general_utils.get_files_dir(
                            self.dir_images_gt,
                            extensions=['jpg', 'jpge', 'png', 'bmp', 'tiff', 'tif'])) == 0:
                self.show_popup(
                    f'For the selected annotation type, it is necessary to inform a directory with the dataset images.\nDirectory is empty or does not have valid images.',
                    'Invalid image directory',
                    buttons=QMessageBox.Ok,
                    icon=QMessageBox.Information)
                return ret, False
            ret = self.replace_id_with_classes(ret, self.filepath_classes_det)
        if len(ret) == 0:
            self.show_popup(
                f'No files was found in the selected directory for the selected annotation format.\nDirectory is empty or does not have valid annotation files.',
                'Invalid directory',
                buttons=QMessageBox.Ok,
                icon=QMessageBox.Information)
            return ret, False
        return ret, True
import json
from math import isclose

from src.bounding_box import BBFormat, BBType, BoundingBox
from src.evaluators.coco_evaluator import get_coco_summary
from src.utils.converter import coco2bb

# Load coco samples
gts = coco2bb('tests/test_coco_eval/gts', BBType.GROUND_TRUTH)
dts = coco2bb('tests/test_coco_eval/dets', BBType.DETECTED)

res = get_coco_summary(gts, dts)

# Compare results to those obtained with coco's official implementation
tol = 1e-6

assert abs(res["AP"] - 0.503647) < tol
assert abs(res["AP50"] - 0.696973) < tol
assert abs(res["AP75"] - 0.571667) < tol
assert abs(res["APsmall"] - 0.593252) < tol
assert abs(res["APmedium"] - 0.557991) < tol
assert abs(res["APlarge"] - 0.489363) < tol
assert abs(res["AR1"] - 0.386813) < tol
assert abs(res["AR10"] - 0.593680) < tol
assert abs(res["AR100"] - 0.595353) < tol
assert abs(res["ARsmall"] - 0.654764) < tol
assert abs(res["ARmedium"] - 0.603130) < tol
assert abs(res["ARlarge"] - 0.553744) < tol