def imagenet2bb(annotations_path): ret = [] # Get annotation files in the path annotation_files = _get_annotation_files(annotations_path) # Loop through each file for file_path in annotation_files: if not validations.is_imagenet_format(file_path): continue # Open XML img_name = ET.parse(file_path).find('filename').text img_name = general_utils.get_file_name_only(img_name) img_width = int(ET.parse(file_path).find('size/width').text) img_height = int(ET.parse(file_path).find('size/height').text) img_size = (img_width, img_height) # Loop through the detections for box_info in ET.parse(file_path).iter('object'): obj_class = box_info.find('name').text x1 = int(float(box_info.find('bndbox/xmin').text)) y1 = int(float(box_info.find('bndbox/ymin').text)) x2 = int(float(box_info.find('bndbox/xmax').text)) y2 = int(float(box_info.find('bndbox/ymax').text)) bb = BoundingBox(image_name=img_name, class_id=obj_class, coordinates=(x1, y1, x2, y2), img_size=img_size, type_coordinates=CoordinatesType.ABSOLUTE, bb_type=BBType.GROUND_TRUTH, format=BBFormat.XYX2Y2) ret.append(bb) return ret
def cvat2bb(path): '''This format supports ground-truth only''' ret = [] # Get annotation files in the path annotation_files = _get_annotation_files(path) # Loop through each file for file_path in annotation_files: if not validations.is_cvat_format(file_path): continue # Loop through the images for image_info in ET.parse(file_path).iter('image'): img_size = (int(image_info.attrib['width']), int(image_info.attrib['height'])) img_name = image_info.attrib['name'] img_name = general_utils.get_file_name_only(img_name) # Loop through the boxes for box_info in image_info.iter('box'): x1, y1, x2, y2 = float(box_info.attrib['xtl']), float( box_info.attrib['ytl']), float( box_info.attrib['xbr']), float(box_info.attrib['ybr']) x1, y1, x2, y2 = int(x1), int(y1), int(x2), int(y2) bb = BoundingBox(image_name=img_name, class_id=box_info.attrib['label'], coordinates=(x1, y1, x2, y2), img_size=img_size, type_coordinates=CoordinatesType.ABSOLUTE, bb_type=BBType.GROUND_TRUTH, format=BBFormat.XYX2Y2) ret.append(bb) return ret
def yolo2bb(annotations_path, images_dir, file_obj_names, bb_type=BBType.GROUND_TRUTH): ret = [] if not os.path.isfile(file_obj_names): print(f'Warning: File with names of classes {file_obj_names} not found.') return ret # Load classes all_classes = [] with open(file_obj_names, "r") as f: all_classes = [line.replace('\n', '') for line in f] # Get annotation files in the path annotation_files = _get_annotation_files(annotations_path) # Loop through each file for file_path in annotation_files: if not validations.is_yolo_format(file_path, bb_types=[bb_type]): continue img_name = os.path.basename(file_path) img_file = general_utils.find_file(images_dir, img_name, match_extension=False) img_resolution = general_utils.get_image_resolution(img_file) if img_resolution is None: print(f'Warning: It was not possible to find the resolution of image {img_name}') continue img_size = (img_resolution['width'], img_resolution['height']) # Loop through lines with open(file_path, "r") as f: for line in f: splitted_line = line.split(' ') class_id = splitted_line[0] if not general_utils.is_str_int(class_id): print( f'Warning: Class id represented in the {file_path} is not a valid integer.') return [] class_id = int(class_id) if class_id not in range(len(all_classes)): print( f'Warning: Class id represented in the {file_path} is not in the range of classes specified in the file {file_obj_names}.' ) return [] if bb_type == BBType.GROUND_TRUTH: confidence = None x1 = float(splitted_line[1]) y1 = float(splitted_line[2]) w = float(splitted_line[3]) h = float(splitted_line[4]) elif bb_type == BBType.DETECTED: confidence = float(splitted_line[1]) x1 = float(splitted_line[2]) y1 = float(splitted_line[3]) w = float(splitted_line[4]) h = float(splitted_line[5]) bb = BoundingBox(image_name=general_utils.get_file_name_only(img_file), class_id=all_classes[class_id], coordinates=(x1, y1, w, h), img_size=img_size, confidence=confidence, type_coordinates=CoordinatesType.RELATIVE, bb_type=bb_type, format=BBFormat.XYWH) ret.append(bb) return ret
def openimage2bb(annotations_path, images_dir, bb_type=BBType.GROUND_TRUTH): ret = [] # Get annotation files in the path annotation_files = _get_annotation_files(annotations_path) # Loop through each file for file_path in annotation_files: if not validations.is_openimage_format(file_path): continue images_shapes = {} # Open csv csv = pd.read_csv(file_path, sep=',') for i, row in csv.iterrows(): # Get image resolution if it was not loaded yet if row['ImageID'] not in images_shapes: img_name = row['ImageID'] image_file = general_utils.find_file(images_dir, img_name) images_shapes[image_file] = general_utils.get_image_resolution( image_file) if images_shapes[image_file] is None: print( f'Warning: It was not possible to find the resolution of image {img_name}' ) continue # Three is no bounding box for the given image if pd.isna(row['LabelName']) or pd.isna(row['XMin']) or pd.isna( row['XMax']) or pd.isna(row['YMin']) or pd.isna( row['YMax']): continue # images_shapes[image_file] = general_utils.get_image_resolution(image_file) img_size = (images_shapes[image_file]['width'], images_shapes[image_file]['height']) x1, x2, y1, y2 = (row['XMin'], row['XMax'], row['YMin'], row['YMax']) x1 = x1.replace(',', '.') if isinstance(x1, str) else x1 x2 = x2.replace(',', '.') if isinstance(x2, str) else x2 y1 = y1.replace(',', '.') if isinstance(y1, str) else y1 y2 = y2.replace(',', '.') if isinstance(y2, str) else y2 x1, x2, y1, y2 = float(x1), float(x2), float(y1), float(y2) confidence = None if pd.isna(row['Confidence']) else float( row['Confidence']) if bb_type == BBType.DETECTED and confidence is None: print( f'Warning: Confidence value found in the CSV file for the image {img_name}' ) return ret bb = BoundingBox(image_name=general_utils.get_file_name_only( row['ImageID']), class_id=row['LabelName'], coordinates=(x1, y1, x2, y2), img_size=img_size, confidence=confidence, type_coordinates=CoordinatesType.RELATIVE, bb_type=bb_type, format=BBFormat.XYX2Y2) ret.append(bb) return ret
def coco2bb(path, bb_type=BBType.GROUND_TRUTH): ret = [] # Get annotation files in the path annotation_files = _get_annotation_files(path) # Loop through each file for file_path in annotation_files: if not validations.is_coco_format(file_path): continue with open(file_path, "r") as f: json_object = json.load(f) # COCO json file contains basically 3 lists: # categories: containing the classes # images: containing information of the images (width, height and filename) # annotations: containing information of the bounding boxes (x1, y1, bb_width, bb_height) classes = {} if 'categories' in json_object: classes = json_object['categories'] # into dictionary classes = {c['id']: c['name'] for c in classes} images = {} # into dictionary for i in json_object['images']: images[i['id']] = { 'file_name': i['file_name'], 'img_size': (int(i['width']), int(i['height'])) } annotations = [] if 'annotations' in json_object: annotations = json_object['annotations'] for annotation in annotations: img_id = annotation['image_id'] x1, y1, bb_width, bb_height = annotation['bbox'] if bb_type == BBType.DETECTED and 'score' not in annotation.keys(): print('Warning: Confidence not found in the JSON file!') return ret confidence = annotation[ 'score'] if bb_type == BBType.DETECTED else None # Make image name only the filename, without extension img_name = images[img_id]['file_name'] img_name = general_utils.get_file_name_only(img_name) # create BoundingBox object bb = BoundingBox(image_name=img_name, class_id=classes[annotation['category_id']], coordinates=(x1, y1, bb_width, bb_height), type_coordinates=CoordinatesType.ABSOLUTE, img_size=images[img_id]['img_size'], confidence=confidence, bb_type=bb_type, format=BBFormat.XYWH) ret.append(bb) return ret
def labelme2bb(annotations_path): ret = [] # Get annotation files in the path annotation_files = _get_annotation_files(annotations_path) # Loop through each file for file_path in annotation_files: if not validations.is_labelme_format(file_path): continue # Parse the JSON file with open(file_path, "r") as f: json_object = json.load(f) img_path = json_object['imagePath'] img_path = os.path.basename(img_path) img_path = general_utils.get_file_name_only(img_path) img_size = (int(json_object['imageWidth']), int(json_object['imageHeight'])) # If there are annotated objects if 'shapes' in json_object: # Loop through bounding boxes for obj in json_object['shapes']: obj_label = obj['label'] ((x1, y1), (x2, y2)) = obj['points'] # If there is no bounding box annotations, bb coordinates could have been set to None if x1 is None and y1 is None and x2 is None and y2 is None: continue x1, y1, x2, y2 = int(float(x1)), int(float(y1)), int( float(x2)), int(float(y2)) bb = BoundingBox(image_name=img_path, class_id=obj_label, coordinates=(x1, y1, x2, y2), img_size=img_size, confidence=None, type_coordinates=CoordinatesType.ABSOLUTE, bb_type=BBType.GROUND_TRUTH, format=BBFormat.XYX2Y2) ret.append(bb) return ret
def draw_bounding_boxes(self): # Load image to obtain a clean image (without BBs) img_path = os.path.join(self.dir_images, self.image_files[self.selected_image_index]) img = cv2.imread(img_path) img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # Get bounding boxes of the loaded image img_name = self.image_files[self.selected_image_index] img_name = general_utils.get_file_name_only(img_name) # Add bounding boxes depending if the item is checked if self.chb_gt_bb.isChecked() and self.gt_annotations is not None: bboxes = BoundingBox.get_bounding_boxes_by_image_name( self.gt_annotations, img_name) if len(bboxes) == 0: bboxes = BoundingBox.get_bounding_boxes_by_image_name( self.gt_annotations, img_name) # Draw bounding boxes for bb in bboxes: img = add_bb_into_image(img, bb, color=(0, 255, 0), thickness=2, label=None) if self.chb_det_bb.isChecked() and self.det_annotations is not None: bboxes = BoundingBox.get_bounding_boxes_by_image_name( self.det_annotations, img_name) if len(bboxes) == 0: bboxes = BoundingBox.get_bounding_boxes_by_image_name( self.det_annotations, img_name) # Draw bounding boxes for bb in bboxes: img = add_bb_into_image(img, bb, color=(0, 0, 255), thickness=2, label=None) return img