def _extract_box2d( path: str, sequence: str, box2d_catalog: Box2DSubcatalog) -> Dict[int, List[LabeledBox2D]]: attributes = box2d_catalog.attributes category_names = box2d_catalog.categories.keys() out_of_view_level = attributes["out_of_view"].enum occlusion_level = attributes["occlusion"].enum ground_truth_path = os.path.join(path, "UAV-benchmark-MOTD_v1.0", "GT") frame_id_ground_truth_map = defaultdict(list) with open(os.path.join(ground_truth_path, f"{sequence}_gt_whole.txt"), encoding="utf-8") as fp: for elements in csv.DictReader(fp, fieldnames=_FIELDNAMES): box2d = LabeledBox2D.from_xywh( *(int(elements[key]) for key in _XYWH_KEYS), category=category_names[int(elements["object_category"]) - 1], attributes={ "out_of_view": out_of_view_level[int(elements["out_of_view"]) - 1], "occlusion": occlusion_level[int(elements["occlusion"]) - 1], }, instance=elements["target_id"], ) frame_id = int(elements["frame_index"]) frame_id_ground_truth_map[frame_id].append(box2d) return frame_id_ground_truth_map
def _parse_xml(xml_path: str) -> Dict[int, List[LabeledBox2D]]: dom = parse(xml_path) frames = dom.documentElement.getElementsByTagName("frame") labels = defaultdict(list) for frame in frames: index = int(frame.getAttribute("number")) objects = frame.getElementsByTagName("objectlist")[0] for obj in objects.getElementsByTagName("object"): box = obj.getElementsByTagName("box")[0] box_h = int(box.getAttribute("h")) box_w = int(box.getAttribute("w")) box_xc = int(box.getAttribute("xc")) box_yc = int(box.getAttribute("yc")) labels[index].append( LabeledBox2D.from_xywh( x=box_xc - box_w // 2, y=box_yc - box_h // 2, width=box_w, height=box_h, category=obj.getElementsByTagName("subtype") [0].firstChild.data, )) return labels
def _get_data(mat: Any, name: Any, bbox: Any, file_path: str) -> Data: image_path = "".join(chr(v[0]) for v in mat[name[0]]) data = Data(os.path.join(file_path, image_path), target_remote_path=image_path.zfill(10)) data.label.box2d = [] mat_bbox = mat[bbox[0]] labeled_box = ({key: [value[0][0]] for key, value in mat_bbox.items()} if mat_bbox["label"].shape[0] == 1 else { key: [mat[value[0]][0][0] for value in values] for key, values in mat_bbox.items() }) for x, y, w, h, e in zip( labeled_box["left"], labeled_box["top"], labeled_box["width"], labeled_box["height"], labeled_box["label"], ): data.label.box2d.append( LabeledBox2D.from_xywh(x, y, w, h, category="0" if e == 10 else str(int(e)))) return data
def _get_instance_label(instances_annotations: Dict[int, Any], image_id: int, categories: Dict[int, str]) -> Label: label: Label = Label() label.box2d = [] label.multi_polygon = [] label.rle = [] if image_id not in instances_annotations: return label for annotation in instances_annotations[image_id]: category = categories[annotation["category_id"]] label.box2d.append( LabeledBox2D.from_xywh(*annotation["bbox"], category=category)) if annotation["iscrowd"] == 0: points = [ chunked(coordinates, 2) for coordinates in annotation["segmentation"] ] label.multi_polygon.append( LabeledMultiPolygon(points, category=category)) else: label.rle.append( LabeledRLE(annotation["segmentation"]["counts"], category=category)) return label
def _get_data_part1(root_path: str, aniamls: Iterable[str]) -> Iterator[Data]: try: import xmltodict # pylint: disable=import-outside-toplevel except ModuleNotFoundError as error: raise ModuleImportError(module_name=error.name) from error for animal in aniamls: for image_path in glob( os.path.join(root_path, "keypoint_image_part1", animal, "*.jpg")): data = Data( image_path, target_remote_path=f"{animal}/{os.path.basename(image_path)}") for annotation_path in glob( os.path.join( root_path, "PASCAL2011_animal_annotation", animal, f"{os.path.splitext(os.path.basename(image_path))[0]}_*.xml", )): with open(annotation_path, encoding="utf-8") as fp: labels: Any = xmltodict.parse(fp.read()) box2d = labels["annotation"]["visible_bounds"] data.label.box2d = [ LabeledBox2D.from_xywh( x=float(box2d["@xmin"]), y=float(box2d["@ymin"]), width=float(box2d["@width"]), height=float(box2d["@height"]), category=animal, ) ] keypoints2d: List[Tuple[float, float, int]] = [ () ] * 20 # type: ignore[list-item] for keypoint in labels["annotation"]["keypoints"]["keypoint"]: keypoints2d[_KEYPOINT_TO_INDEX[keypoint["@name"]]] = ( float(keypoint["@x"]), float(keypoint["@y"]), int(keypoint["@visible"]), ) data.label.keypoints2d = [ LabeledKeypoints2D(keypoints2d, category=animal) ] yield data
def _load_box_labels(file_path: str) -> List[LabeledBox2D]: box_labels = [] with open(file_path, encoding="utf-8") as fp: for line in fp: center_x, center_y, width, height, occlusion, blur = map(int, line.strip().split()) attributes = {"occlusion-level": _OCCLUSION_MAP[occlusion], "blur-level": bool(blur)} box_labels.append( LabeledBox2D.from_xywh( x=center_x - width / 2, y=center_y - height / 2, width=width, height=height, attributes=attributes, ) ) return box_labels
def _get_panoptic_box2d(panoptic_annotations: Dict[int, Any], image_id: int, categories: Dict[int, str]) -> List[LabeledBox2D]: if image_id not in panoptic_annotations: return [] box2d: List[LabeledBox2D] = [] for annotation in panoptic_annotations[image_id]: for segment_info in annotation["segments_info"]: # category_id 1-91 are thing categories from the detection task # category_id 92-200 are stuff categories from the stuff task if segment_info["category_id"] > 91: category = categories[segment_info["category_id"]] box2d.append( LabeledBox2D.from_xywh(*segment_info["bbox"], category=category)) return box2d
def _get_data_part2(root_path: str, aniamls: Iterable[str]) -> Iterator[Data]: try: import xmltodict # pylint: disable=import-outside-toplevel except ModuleNotFoundError as error: raise ModuleImportError(module_name=error.name) from error for animal in aniamls: for image_path in glob( os.path.join(root_path, "animalpose_image_part2", animal, "*.jpeg")): data = Data( image_path, target_remote_path=f"{animal}/{os.path.basename(image_path)}") annotation_path = os.path.join( root_path, "animalpose_anno2", animal, f"{os.path.splitext(os.path.basename(image_path))[0]}.xml", ) with open(annotation_path, encoding="utf-8") as fp: labels: Any = xmltodict.parse(fp.read()) box2d = labels["annotation"]["visible_bounds"] data.label.box2d = [ LabeledBox2D.from_xywh( x=float(box2d["@xmin"]), y=float( box2d["@xmax"]), # xmax means ymin in the annotation width=float(box2d["@width"]), height=float(box2d["@height"]), category=animal, ) ] keypoints2d = LabeledKeypoints2D(category=animal) for keypoint in labels["annotation"]["keypoints"]["keypoint"]: keypoints2d.append( Keypoint2D(float(keypoint["@x"]), float(keypoint["@y"]), int(keypoint["@visible"]))) data.label.keypoints2d = [keypoints2d] yield data
def test_from_xywh(self): x, y, width, height = 1, 2, 3, 4 xmin, xmax, ymin, ymax = 1, 2, 4, 6 labeledbox2d = LabeledBox2D.from_xywh( x, y, width, height, category="cat", attributes={"gender": "male"}, instance="12345", ) assert labeledbox2d.category == "cat" assert labeledbox2d.attributes == {"gender": "male"} assert labeledbox2d.instance == "12345" assert labeledbox2d[0] == xmin assert labeledbox2d[1] == xmax assert labeledbox2d[2] == ymin assert labeledbox2d[3] == ymax
def _generate_data(image_path: str, labels: Dict[str, Any]) -> Data: data = Data(image_path) data.label.box2d = [] image_id = labels["image_name_id_map"][os.path.basename(image_path)] image_annotations_map = labels["image_annotations_map"] if image_id not in image_annotations_map: return data annotations = labels["annotations"] poses = labels["poses"] categories = labels["categories"] for annotation_id in image_annotations_map[image_id]: annotation = annotations[annotation_id] x_top, y_top, width, height = annotation["bbox"] attributes = { "occluded": annotation["occluded"], "difficult": annotation["difficult"], "pose": poses[annotation["pose_id"] - 1]["name"], "truncated": annotation["truncated"], } data.label.box2d.append( LabeledBox2D.from_xywh( x=x_top, y=y_top, width=width, height=height, category=categories[annotation["category_id"]]["name"], attributes=attributes, instance=str(annotation["tracking_id"]), )) return data
def _get_box2ds(label_path: str) -> Dict[str, LabeledBox2D]: all_box2d_attributes: DefaultDict[str, AttributeType] = defaultdict(dict) # The normal format of each line of the file is # n000002/0032_01.jpg 0 # n000002/0039_01.jpg 0 # n000002/0090_01.jpg 0 # ... for file_path in glob(os.path.join(label_path, "attributes", "*.txt")): attribute_name = os.path.basename(file_path).rstrip(".txt").split( "-", 1)[1] with open(file_path, encoding="utf-8") as fp: for line in fp: name, attribute_value = line.rstrip("\n").split("\t", 1) all_box2d_attributes[name.rstrip( ".jpg")][attribute_name] = bool(int(attribute_value)) all_boxes = {} for file_path in ( os.path.join(label_path, "loose_bb_test.csv"), os.path.join(label_path, "loose_bb_train.csv"), ): # The normal format of each line of the file is # NAME_ID,X,Y,W,H # "n000001/0001_01",60,60,79,109 # "n000001/0002_01",134,81,207,295 # "n000001/0003_01",58,32,75,103 # ... with open(file_path, encoding="utf-8") as fp: for row in islice(csv.reader(fp), 1, None): name_id = row.pop(0).strip('"') box = LabeledBox2D.from_xywh(*map(float, row)) box2d_attribute = all_box2d_attributes.get(name_id) if box2d_attribute: box.attributes = box2d_attribute all_boxes[name_id] = box return all_boxes
def _load_data(path: str, attribute_map: _ATTRIBUTE_MAP_TYPE, segment_name: str) -> Iterator[Data]: """Loads the box2d and classification label in to data. The train and val label file context should be like:: 0--Parade/0_Parade_marchingband_1_849.jpg 1 449 330 122 149 0 0 0 0 0 0 0--Parade/0_Parade_Parade_0_452.jpg 0 0 0 0 0 0 0 0 0 0 0 0--Parade/0_Parade_marchingband_1_799.jpg 21 78 221 7 8 2 0 0 0 0 0 78 238 14 17 2 0 0 0 0 0 113 212 11 15 2 0 0 0 0 0 134 260 15 15 2 0 0 0 0 0 Arguments: path: The path of label file. attribute_map: A attribute value enum table. segment_name: Name of the segment. Yields: Data with loaded lables. """ is_test = segment_name == "test" with open(path, encoding="utf-8") as fp: for image_path in fp: event, file_name = image_path.split("/") # translate directory name to category. like 0--Parade -> Parade category = "_".join(event.split("--")[1:]) root_path = path.rsplit(os.sep, 2)[0] data = Data( os.path.join(root_path, f"WIDER_{segment_name}", "images", event, file_name) ) data.label.classification = Classification(category) if not is_test: label_num = int(fp.readline()) # when the label num is 0, a line of "0 0 0 0 0 0 0 0 0 0" also given if label_num == 0: fp.readline() data.label.box2d = [] for line in islice(fp, label_num): labels = line.strip().split() attributes = { key: mapping[int(value)] for (key, mapping), value in zip(attribute_map.items(), labels[4:10]) } data.label.box2d.append( LabeledBox2D.from_xywh( x=int(labels[0]), y=int(labels[1]), width=int(labels[2]), height=int(labels[3]), attributes=attributes, ) ) yield data