def __init__(self, data_root: PathLike) -> None: self.label_root = Path(data_root, 'Annotations', 'DET') self.frame_root = Path(data_root, 'Data', 'DET') self._pascal_translator = _PascalTranslator(data_root, 'VID') # mapping from class_name to list of label paths containing that # class. This will be useful for sampling later on. self.cls_label_paths = defaultdict(list) # populate cls_label_paths, ignoring classes that are not in VID allowed_class_ids = set(self._pascal_translator.id_to_int.keys()) for label_path in list(self.label_root.rglob('*.xml')): class_ids = { pascal_object.class_id for pascal_object in parse_pascal_xmlfile(label_path) } # if any object has a class_id is not a VID class_id, this # instance is skipped if class_ids.issubset(allowed_class_ids): class_names = { self._pascal_translator.id_to_name[class_id] for class_id in class_ids } for class_name in class_names: self.cls_label_paths[class_name].append(label_path)
def __init__(self, data_root: PathLike, sample_size: int) -> None: """initialize and populate index_mappings.""" label_root = Path(data_root, 'Annotations', 'VID', 'val') frame_root = Path(data_root, 'Data', 'VID', 'val') pascal_translator = _PascalTranslator(data_root, 'VID') snippet_dirs = [p for p in label_root.iterdir() if p.is_dir()] index_mappings = list() for _ in range(sample_size): snippet_dir = random.choice(snippet_dirs) label_paths = sorted(list(snippet_dir.glob('*.xml'))) ind_0 = random.randrange(len(label_paths) - 2) instance_pair = list() for label_ind in [ind_0, ind_0 + 1]: label_path = label_paths[label_ind] frame_path = Path( frame_root, label_path.relative_to(label_root).with_suffix('.JPEG')) instance = RawImageInstance( impath=frame_path, labels=[ pascal_translator(pascal_object) for pascal_object in parse_pascal_xmlfile(label_path) ]) instance_pair.append(instance) index_mappings.append(tuple(instance_pair)) self._index_mappings = tuple(index_mappings)
def __init__(self, data_root: Path, allowed_class_ids: Set[str], allowed_class_ints: Set[int]) -> None: label_root = Path(data_root, "Annotations", "DET") frame_root = Path(data_root, "Data", "DET") # mapping from class_name to list of label paths containing that # class. This will be useful for sampling later on. self._rawinstances_by_cls = defaultdict(list) trn_files = [f"train_{cls_id}" for cls_id in allowed_class_ints] val_files = ["val"] for mode, files in zip(["train", "val"], [trn_files, val_files]): for f in files: instance_list_path = Path(data_root, "ImageSets", "DET", f"{f}.txt") with open(instance_list_path) as instance_list: for line in instance_list: instance_id, _ = line.split() if "extra" in instance_id: continue framepath = Path(frame_root, mode, f"{instance_id}.JPEG") labelpath = Path(label_root, mode, f"{instance_id}.xml") class_ids = { pascal_object.class_id for pascal_object in parse_pascal_xmlfile( labelpath) } if class_ids.issubset(allowed_class_ids): ri = RawImageInstance(impath=framepath, labelpath=labelpath) for class_id in class_ids: self._rawinstances_by_cls[class_id].append(ri)
def __getitem__(self, i: int) -> Tuple[ImageInstance, ImageInstance]: return tuple( ImageInstance( im=Image.open(ri.impath), labels=tuple( self._pascal_translator(pascal_object) for pascal_object in parse_pascal_xmlfile(ri.labelpath)), ) for ri in self._raw_samples[i])
def sample(self) -> ImageInstance: raw_instance = self._raw_sampler.sample() instance = ImageInstance( im=Image.open(raw_instance.impath), labels=tuple( self._pascal_translator(pascal_object) for pascal_object in parse_pascal_xmlfile(raw_instance.labelpath)), ) return instance
def sample(self) -> Tuple[ImageInstance, ImageInstance]: """non-deterministically query `raw_sampler` for image and label paths, then load images and labels.""" return tuple( ImageInstance( im=Image.open(ri.impath), labels=tuple( self._pascal_translator(pascal_object) for pascal_object in parse_pascal_xmlfile(ri.labelpath)), ) for ri in self._raw_sampler.sample())
def sample(self) -> Tuple[ImageInstance, ImageInstance]: """sample frames from times t and t+tau. time step tau is sampled from a discrete laplacian distribution to create a bias towards small displacements. original paper only takes 10 frames from each snippet because of large differences in snippet lengths limiting sample diversity. uniformly sampling a snippet before sampling frames from that snippet solves the same problem, while also maximizing sample diversity within snippets. """ # randomly sample a snippet dir and get associated sorted label paths snippet_dir = random.choice(self.snippet_dirs) label_paths = Path(self.label_root, snippet_dir).glob('*.xml') label_paths = sorted(list(label_paths)) # randomly sample tau from discrete laplacian distribution tau = abs(dlaplace.rvs(self.a)) # randomly sample first frame ind_0 = random.randrange(len(label_paths) - tau) ind_1 = ind_0 + tau instances = list() for label_ind in [ind_0, ind_1]: label_path = label_paths[label_ind] frame_path = Path( self.frame_root, label_path.relative_to(self.label_root).with_suffix('.JPEG')) instance = ImageInstance( im=Image.open(frame_path), labels=[ self._pascal_translator(pascal_object) for pascal_object in parse_pascal_xmlfile(label_path) ]) instances.append(instance) instances = tuple(instances) return instances
def sample(self) -> ImageInstance: """randomly sample instance from full DET dataset. original paper samples a fixed number of instances from each class because of class imbalance. This implementation uniformly samples from available classes first, then samples instances that contain that class. This solves the same problem without throwing data away. """ class_name = random.choice(self.cls_label_paths.keys()) label_path = random.choice(self.cls_label_paths[class_name]) frame_path = Path( self.frame_root, label_path.relative_to(self.label_root).with_suffix('.JPEG')) instance = ImageInstance( im=Image.open(frame_path), object_labels=[ self._pascal_translator(pascal_object) for pascal_object in parse_pascal_xmlfile(label_path) ]) return instance