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 test_case_1(): gts_dir = 'tests/test_case_1/gts' dets_dir = 'tests/test_case_1/dets' gts = converter.text2bb(gts_dir, BBType.GROUND_TRUTH) dets = converter.text2bb(dets_dir, BBType.DETECTED) assert (len(gts) > 0) assert (len(dets) > 0) testing_ious = [0.1, 0.3, 0.5, 0.75] # ELEVEN_POINT_INTERPOLATION expected_APs = {'object': {0.1: 0.3333333333, 0.3: 0.2683982683, 0.5: 0.0303030303, 0.75: 0.0}} for idx, iou in enumerate(testing_ious): results_dict = get_pascalvoc_metrics( gts, dets, iou_threshold=iou, method=MethodAveragePrecision.ELEVEN_POINT_INTERPOLATION) results = results_dict['per_class'] for c, res in results.items(): assert isclose(expected_APs[c][iou], res['AP']) # EVERY_POINT_INTERPOLATION expected_APs = {'object': {0.1: 0.3371980676, 0.3: 0.2456866804, 0.5: 0.0222222222, 0.75: 0.0}} for idx, iou in enumerate(testing_ious): results_dict = get_pascalvoc_metrics( gts, dets, iou_threshold=iou, method=MethodAveragePrecision.EVERY_POINT_INTERPOLATION) results = results_dict['per_class'] for c, res in results.items(): assert isclose(expected_APs[c][iou], res['AP'])
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 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
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
plt.ylabel('classes') else: plt.bar(dict_bbs_per_class.keys(), dict_bbs_per_class.values()) plt.xlabel('classes') plt.ylabel('amount of bounding boxes') plt.xticks(rotation=rotation) title = f'Distribution of bounding boxes per class {extra_title}' plt.title(title) if show: plt.tick_params(axis='x', labelsize=10) # Set the x-axis label size plt.show(block=True) return plt # Get annotations (ground truth and detections) gt_bbs = converter.vocpascal2bb(dir_gts) det_bbs = converter.text2bb(dir_dets, bb_type=BBType.DETECTED, bb_format=BBFormat.XYWH,type_coordinates=CoordinatesType.ABSOLUTE, img_dir=dir_imgs) # Leave only the annotations of cats gt_bbs = [bb for bb in gt_bbs if bb.get_class_id() == 'cat'] det_bbs = [bb for bb in det_bbs if bb.get_class_id() == 'cat'] # Uncomment to plot the distribution bounding boxes per classes # dict_gt = BoundingBox.get_amount_bounding_box_all_classes(gt_bbs, reverse=False) # plot_bb_per_classes(dict_gt, horizontally=True, rotation=0, show=True, extra_title=' (groundtruths)') # clases_gt = [b.get_class_id() for b in gt_bbs] # dict_det = BoundingBox.get_amount_bounding_box_all_classes(det_bbs, reverse=True) # general_utils.plot_bb_per_classes(dict_det, horizontally=False, rotation=80, show=True, extra_title=' (detections)') ############################################################# # EVALUATE WITH COCO METRICS #############################################################