def __call__(self, dataset_dict): """ Args: dataset_dict (dict): Metadata of one image, in Detectron2 Dataset format. Returns: dict: a format that builtin models in detectron2 accept """ dataset_dict = copy.deepcopy( dataset_dict) # it will be modified by code below # USER: Write your own image loading if it's not from a file image = utils.read_image(dataset_dict["file_name"], format=self.img_format) utils.check_image_size(dataset_dict, image) if "annotations" not in dataset_dict: image, transforms = T.apply_transform_gens( ([self.crop_gen] if self.crop_gen else []) + self.tfm_gens, image) else: # Crop around an instance if there are instances in the image. # USER: Remove if you don't use cropping if self.crop_gen: crop_tfm = utils.gen_crop_transform_with_instance( self.crop_gen.get_crop_size(image.shape[:2]), image.shape[:2], np.random.choice(dataset_dict["annotations"]), ) image = crop_tfm.apply_image(image) image, transforms = T.apply_transform_gens(self.tfm_gens, image) if self.crop_gen: transforms = crop_tfm + transforms image_shape = image.shape[:2] # h, w # Pytorch's dataloader is efficient on torch.Tensor due to shared-memory, # but not efficient on large generic data structures due to the use of pickle & mp.Queue. # Therefore it's important to use torch.Tensor. dataset_dict["image"] = torch.as_tensor( np.ascontiguousarray(image.transpose(2, 0, 1))) if not self.is_train: # USER: Modify this if you want to keep them for some reason. dataset_dict.pop("annotations", None) return dataset_dict if "annotations" in dataset_dict: # USER: Implement additional transformations if you have other types of data annos = [ utils.transform_instance_annotations( obj, transforms, image_shape, ) for obj in dataset_dict.pop("annotations") if obj.get("iscrowd", 0) == 0 ] instances = annotations_to_instances(annos, image_shape) dataset_dict["instances"] = utils.filter_empty_instances(instances) return dataset_dict
def __call__(self, dataset_dict): dataset_dict = copy.deepcopy( dataset_dict) # it will be modified by code below image = utils.read_image(dataset_dict["file_name"], format="BGR") aug_input = T.AugInput(image) transforms = self.augmentations(aug_input) image = aug_input.image # if not self.is_train: # # USER: Modify this if you want to keep them for some reason. # dataset_dict.pop("annotations", None) # dataset_dict.pop("sem_seg_file_name", None) # return dataset_dict image_shape = image.shape[:2] # h, w dataset_dict["image"] = torch.as_tensor( image.transpose(2, 0, 1).astype("float32")) annos = [ utils.transform_instance_annotations(obj, transforms, image_shape) for obj in dataset_dict.pop("annotations") if obj.get("iscrowd", 0) == 0 ] instances = utils.annotations_to_instances(annos, image_shape) dataset_dict["instances"] = utils.filter_empty_instances(instances) return dataset_dict
def mapper(dataset_dict): # 自定义mapper dataset_dict = copy.deepcopy(dataset_dict) # 后面要改变这个dict,所以先复制 image = utils.read_image(dataset_dict["file_name"], format="BGR") # 读取图片,numpy array # image, transforms = T.apply_transform_gens( # [T.Resize((800, 800)), T.RandomContrast(0.1, 3), T.RandomSaturation(0.1, 2), T.RandomRotation(angle=[0, 180]), # T.RandomFlip(prob=0.4, horizontal=False, vertical=True), T.RandomCrop('relative_range', (0.4, 0.6))], image) # 数组增强 # image, transforms = T.apply_transform_gens( # [T.Resize((800, 800)), T.RandomContrast(0.1, 3), T.RandomSaturation(0.1, 2), # T.RandomFlip(prob=0.4, horizontal=True, vertical=False), T.RandomCrop('relative_range', (0.4, 0.6))], image) image, transforms = T.apply_transform_gens( [T.Resize((800, 800)), T.RandomContrast(0.1, 3), T.RandomSaturation(0.1, 2), T.RandomFlip(prob=0.4, horizontal=True, vertical=False)], image) # 数组增强 dataset_dict["image"] = torch.as_tensor(image.transpose(2, 0, 1).astype("float32")) # 转成Tensor annos = [ utils.transform_instance_annotations(obj, transforms, image.shape[:2]) for obj in dataset_dict.pop("annotations") if obj.get("iscrowd", 0) == 0 ] # 数据增强要同步标注 instances = utils.annotations_to_instances(annos, image.shape[:2]) # 将标注转成Instance(Tensor) dataset_dict["instances"] = utils.filter_empty_instances(instances) # 去除空的 return dataset_dict
def mapper(dataset_dict): # Implement a mapper, similar to the default DatasetMapper, but with your own customizations dataset_dict = copy.deepcopy( dataset_dict) # it will be modified by code below image = utils.read_image(dataset_dict["file_name"], format="BGR") image, transforms = T.apply_transform_gens([ T.RandomFlip(prob=0.50, horizontal=True, vertical=False), T.RandomApply(tfm_or_aug=T.RandomBrightness(intensity_min=0.7, intensity_max=1.1), prob=0.40), T.RandomApply(tfm_or_aug=T.RandomSaturation(intensity_min=0.7, intensity_max=1.1), prob=0.40) ], image) dataset_dict["image"] = torch.as_tensor( image.transpose(2, 0, 1).astype("float32")) annos = [ utils.transform_instance_annotations(obj, transforms, image.shape[:2]) for obj in dataset_dict.pop("annotations") if obj.get("iscrowd", 0) == 0 ] instances = utils.annotations_to_instances(annos, image.shape[:2]) dataset_dict["instances"] = utils.filter_empty_instances(instances) return dataset_dict
def augment(record): record = deepcopy(record) image = plt.imread(record["filepath"]) annotations = record["annotations"] boxes = [annotation["bbox"] for annotation in annotations] classes = [annotation["category_id"] for annotation in annotations] boxes = BoundingBoxesOnImage( [ BoundingBox(*box, label=class_) for box, class_ in zip(boxes, classes) ], shape=image.shape, ) image, boxes = AUGMENTER(image=image, bounding_boxes=boxes) classes = [bbox.label for bbox in boxes.bounding_boxes] boxes = np.array([[box.x1, box.y1, box.x2, box.y2] for box in boxes.items]) image = image[..., [2, 1]] image = image.transpose(2, 0, 1).astype(np.float32) annotations = [{ "bbox": box, "bbox_mode": BoxMode.XYXY_ABS, "category_id": class_ } for box, class_ in zip(boxes, classes)] record["image"] = torch.as_tensor(image) instances = utils.annotations_to_instances(annotations, image.shape[1:]) record["instances"] = utils.filter_empty_instances(instances) return record
def custom_mapper(dataset_dict): # it will be modified by code below dataset_dict = copy.deepcopy(dataset_dict) image = utils.read_image(dataset_dict["file_name"], format="BGR") transform_list = [ T.Resize((512, 512)), T.RandomBrightness(0.8, 1.8), T.RandomContrast(0.6, 1.3), T.RandomSaturation(0.8, 1.4), T.RandomRotation(angle=[30, 30]), T.RandomLighting(0.7), T.RandomFlip(prob=0.4, horizontal=False, vertical=True), ] image, transforms = T.apply_transform_gens(transform_list, image) dataset_dict["image"] = torch.as_tensor( image.transpose(2, 0, 1).astype("float32")) annos = [ utils.transform_instance_annotations(obj, transforms, image.shape[:2]) for obj in dataset_dict.pop("annotations") if obj.get("iscrowd", 0) == 0 ] instances = utils.annotations_to_instances(annos, image.shape[:2]) dataset_dict["instances"] = utils.filter_empty_instances(instances) return dataset_dict
def custom_mapper(dataset_dict): # Implement a mapper, similar to the default DatasetMapper, but with your own customizations dataset_dict = copy.deepcopy( dataset_dict) # it will be modified by code below image = utils.read_image(dataset_dict["file_name"], format="BGR") # transform_list = [T.Resize(800,600), # T.RandomFlip(prob=0.5, horizontal=True, vertical=True), # T.RandomContrast(0.8, 3), # T.RandomBrightness(0.8, 1.6), # ] transform_list = [ #T.Resize((800, 800)), T.RandomContrast(0.8, 3), T.RandomBrightness(0.8, 1.6), T.RandomFlip(prob=0.5, horizontal=False, vertical=True), T.RandomFlip(prob=0.5, horizontal=True, vertical=False) ] ### 数据增强方式 image, transforms = T.apply_transform_gens(transform_list, image) ## # 数组增强 dataset_dict["image"] = torch.as_tensor( image.transpose(2, 0, 1).astype("float32")) ##转成Tensor annos = [ utils.transform_instance_annotations(obj, transforms, image.shape[:2]) for obj in dataset_dict.pop("annotations") if obj.get("iscrowd", 0) == 0 ] instances = utils.annotations_to_instances( annos, image.shape[:2]) # 将标注转成Instance(Tensor) dataset_dict["instances"] = utils.filter_empty_instances( instances) ## 去除空的 return dataset_dict
def custom_mapper(dataset_dict, size, flip_prob, min_brightness, max_brightness, \ min_contrast, max_contrast, min_saturation, max_saturation): # Implement a mapper, similar to the default DatasetMapper, but with your own customizations dataset_dict = copy.deepcopy(dataset_dict) # it will be modified by code below image = detection_utils.read_image(dataset_dict["file_name"], format="BGR") transform_list = [ T.Resize(size), T.RandomBrightness(min_brightness, max_brightness), T.RandomContrast(min_contrast, max_contrast), T.RandomSaturation(min_saturation, max_saturation), T.RandomFlip(prob=flip_prob, horizontal=False, vertical=True), T.RandomFlip(prob=flip_prob, horizontal=True, vertical=False), ] image, transforms = T.apply_transform_gens(transform_list, image) dataset_dict["image"] = torch.as_tensor(image.transpose(2, 0, 1).astype("float32")) annos = [ detection_utils.transform_instance_annotations(obj, transforms, image.shape[:2]) for obj in dataset_dict.pop("annotations") if obj.get("iscrowd", 0) == 0 ] instances = detection_utils.annotations_to_instances(annos, image.shape[:2]) dataset_dict["instances"] = detection_utils.filter_empty_instances(instances) return dataset_dict
def __call__(self, dataset_dict): dataset_dict = copy.deepcopy(dataset_dict) # it will be modified by code below image = utils.read_image(dataset_dict["file_name"], format="BGR") # aug_input = T.AugInput(image) # transforms = self.augmentations(aug_input) # image = aug_input.image prev_anno = dataset_dict["annotations"] bboxes = np.array([obj["bbox"] for obj in prev_anno], dtype=np.float32) # category_id = np.array([obj["category_id"] for obj in dataset_dict["annotations"]], dtype=np.int64) category_id = np.arange(len(dataset_dict["annotations"])) transformed = self.transform(image=image, bboxes=bboxes, category_ids=category_id) image = transformed["image"] annos = [] for i, j in enumerate(transformed["category_ids"]): d = prev_anno[j] d["bbox"] = transformed["bboxes"][i] annos.append(d) dataset_dict.pop("annotations", None) # Remove unnecessary field. # if not self.is_train: # # USER: Modify this if you want to keep them for some reason. # dataset_dict.pop("annotations", None) # dataset_dict.pop("sem_seg_file_name", None) # return dataset_dict image_shape = image.shape[:2] # h, w dataset_dict["image"] = torch.as_tensor(image.transpose(2, 0, 1).astype("float32")) instances = utils.annotations_to_instances(annos, image_shape) dataset_dict["instances"] = utils.filter_empty_instances(instances) return dataset_dict
def __call__(self, dataset_dict): self.tfm_gens = [] dataset_dict = deepcopy(dataset_dict) image = utils.read_image(dataset_dict["file_name"], format=self.img_format) utils.check_image_size(dataset_dict, image) if self.is_train: # Crop if 'crop' in self.da.keys(): crop_gen = T.RandomCrop(self.da['crop']['type'], self.da['crop']['size']) self.tfm_gens.append(crop_gen) # Horizontal flip if 'flip' in self.da.keys(): flip_gen = T.RandomFlip( prob=self.da['flip']['prob'], horizontal=self.da['flip']['horizontal'], vertical=self.da['flip']['vertical']) self.tfm_gens.append(flip_gen) image, transforms = T.apply_transform_gens(self.tfm_gens, image) image_shape = image.shape[:2] # h, w dataset_dict["image"] = torch.as_tensor( np.ascontiguousarray(image.transpose(2, 0, 1))) if not self.is_train: dataset_dict.pop("annotations", None) dataset_dict.pop("sem_seg_file_name", None) return dataset_dict if "annotations" in dataset_dict: for anno in dataset_dict["annotations"]: if not self.mask_on: anno.pop("segmentation", None) if not self.keypoint_on: anno.pop("keypoints", None) annos = [ utils.transform_instance_annotations( obj, transforms, image_shape, keypoint_hflip_indices=self.keypoint_hflip_indices) for obj in dataset_dict.pop("annotations") if obj.get("iscrowd", 0) == 0 ] instances = utils.annotations_to_instances( annos, image_shape, mask_format=self.mask_format) if self.crop_gen and instances.has("gt_masks"): instances.gt_boxes = instances.gt_masks.get_bounding_boxes() dataset_dict["instances"] = utils.filter_empty_instances(instances) return dataset_dict
def apply_image_augmentations(image, dataset_dict, sem_seg_gt, augmentations): """Applies given augmentation to the given image and its attributes (segm, instances, etc). Almost no changes from D2's original code (apart from erasing non-relevant portions, e.g. for keypoints), just wrapped it in a function to avoid duplicate code.""" aug_input = T.AugInput(image, sem_seg=sem_seg_gt) transforms = augmentations(aug_input) image, sem_seg_gt = aug_input.image, aug_input.sem_seg image_shape = image.shape[:2] # h, w # Pytorch's dataloader is efficient on torch.Tensor due to shared-memory, # but not efficient on large generic data structures due to the use of pickle & mp.Queue. # Therefore it's important to use torch.Tensor. dataset_dict["image"] = torch.as_tensor( np.ascontiguousarray(image.transpose(2, 0, 1))) if sem_seg_gt is not None: dataset_dict["sem_seg"] = torch.as_tensor( sem_seg_gt.astype("long")) if not self.is_train: dataset_dict.pop("annotations", None) dataset_dict.pop("sem_seg_file_name", None) return dataset_dict if "annotations" in dataset_dict: for anno in dataset_dict["annotations"]: if not self.use_instance_mask: anno.pop("segmentation", None) if not self.use_keypoint: anno.pop("keypoints", None) annos = [ utils.transform_instance_annotations( obj, transforms, image_shape, keypoint_hflip_indices=self.keypoint_hflip_indices, ) for obj in dataset_dict.pop("annotations") if obj.get("iscrowd", 0) == 0 ] instances = utils.annotations_to_instances( annos, image_shape, mask_format=self.instance_mask_format) # After transforms such as cropping are applied, the bounding box may no longer # tightly bound the object. As an example, imagine a triangle object # [(0,0), (2,0), (0,2)] cropped by a box [(1,0),(2,2)] (XYXY format). The tight # bounding box of the cropped triangle should be [(1,0),(2,1)], which is not equal to # the intersection of original bounding box and the cropping box. if self.recompute_boxes: instances.gt_boxes = instances.gt_masks.get_bounding_boxes( ) dataset_dict["instances"] = utils.filter_empty_instances( instances) return dataset_dict, transforms
def test_random_instance_crop(self): from detectron2.data import detection_utils as du from detectron2.data.transforms.augmentation import ( AugInput, AugmentationList, ) from detectron2.structures import BoxMode aug = tf_crop.RandomInstanceCrop([1.0, 1.0]) img_w, img_h = 10, 7 annotations = [ { "category_id": 0, "bbox": [1, 1, 4, 3], "bbox_mode": BoxMode.XYWH_ABS, }, { "category_id": 0, "bbox": [2, 2, 4, 3], "bbox_mode": BoxMode.XYWH_ABS, }, { "category_id": 0, "bbox": [6, 5, 3, 2], "bbox_mode": BoxMode.XYWH_ABS, }, ] img = np.ones([img_h, img_w, 3]) * 3 inputs = AugInput(image=img) # pass additional arguments inputs.annotations = annotations transforms = AugmentationList([aug])(inputs) self.assertIn(inputs.image.shape, [torch.Size([3, 4, 3]), torch.Size([2, 3, 3])]) # from dataset mapper unused annotations will be filtered out due to the # iscrowd flag image_shape = inputs.image.shape[:2] annos = [ du.transform_instance_annotations( obj, transforms, image_shape, ) for obj in annotations if obj.get("iscrowd", 0) == 0 ] instances = du.annotations_to_instances(annos, image_shape) filtered_instances = du.filter_empty_instances(instances) self.assertEqual(len(filtered_instances), 1) self.assertArrayEqual( filtered_instances.gt_boxes.tensor.tolist(), [[0, 0, image_shape[1], image_shape[0]]], )
def __call__(self, dataset_dict): """ Args: dataset_dict (dict): Metadata of one image, in Detectron2 Dataset format. Returns: dict: a format that builtin models in detectron2 accept """ dataset_dict = copy.deepcopy( dataset_dict) # it will be modified by code below image = utils.read_image(dataset_dict["file_name"], format=self.img_format) utils.check_image_size(dataset_dict, image) if self.crop_gen is None: image, transforms = T.apply_transform_gens(self.tfm_gens, image) else: if np.random.rand() > 0.5: image, transforms = T.apply_transform_gens( self.tfm_gens, image) else: image, transforms = T.apply_transform_gens( self.tfm_gens[:-1] + self.crop_gen + self.tfm_gens[-1:], image) image_shape = image.shape[:2] # h, w # Pytorch's dataloader is efficient on torch.Tensor due to shared-memory, # but not efficient on large generic data structures due to the use of pickle & mp.Queue. # Therefore it's important to use torch.Tensor. dataset_dict["image"] = torch.as_tensor( np.ascontiguousarray(image.transpose(2, 0, 1))) if not self.is_train: # USER: Modify this if you want to keep them for some reason. dataset_dict.pop("annotations", None) return dataset_dict if "annotations" in dataset_dict: # USER: Modify this if you want to keep them for some reason. for anno in dataset_dict["annotations"]: if not self.mask_on: anno.pop("segmentation", None) anno.pop("keypoints", None) # USER: Implement additional transformations if you have other types of data annos = [ utils.transform_instance_annotations(obj, transforms, image_shape) for obj in dataset_dict.pop("annotations") if obj.get("iscrowd", 0) == 0 ] instances = utils.annotations_to_instances(annos, image_shape) dataset_dict["instances"] = utils.filter_empty_instances(instances) return dataset_dict
def __call__(self, dataset_dict): """ :dataset_dict: this contains a single record(as per dataset) which the dataloader requested :return: Apply augmentation and convert record(as per dataset) into format required by model (https://detectron2.readthedocs.io/en/v0.2.1/tutorials/models.html#model-input-format) """ dataset_dict = copy.deepcopy(dataset_dict) # detectron utils reads images in batch, thus shape of image = (Height x Width x Channel) image = utils.read_image(dataset_dict["file_name"], format="BGR") # convert record into model input format prev_anno = dataset_dict["annotations"] bboxes = np.array([obj["bbox"] for obj in prev_anno], dtype=np.float32) # make dummy category ids for indexing purposes category_id = np.arange(len(dataset_dict["annotations"])) # transform the input image print(dataset_dict["file_name"]) transformed = self.transform(image=image, bboxes=bboxes, category_ids=category_id) # extract transformed image image = transformed["image"] # prep annotations for model input annos = [] for i, j in enumerate(transformed["category_ids"]): # fetch old annotation using dummy category_id temp = prev_anno[j] # updating the bboxes of old annotation temp["bbox"] = transformed["bboxes"][i] annos.append(temp) # delete annotations as model will use "instances" instead of annotations dataset_dict.pop("annotations", None) # image.shape returns H x W x C # image.shape[:2] returns H x W image_shape = image.shape[:2] # transpose operation converts H x W x C --> C x H x W dataset_dict["image"] = torch.as_tensor(image.transpose(2, 0, 1).astype("float32")) # convert annotations to instances format instances = utils.annotations_to_instances(annos, image_shape) # delete any images which do not contain annotations dataset_dict["instances"] = utils.filter_empty_instances(instances) return dataset_dict
def __call__(self, dataset_dict): """ Args: dataset_dict (dict): Metadata of one image, in Detectron2 Dataset format. Returns: dict: a format that builtin models in detectron2 accept """ dataset_dict = copy.deepcopy(dataset_dict) # it will be modified by code below image = utils.read_image(dataset_dict["file_name"], format=self.image_format) utils.check_image_size(dataset_dict, image) aug_input = T.AugInput(image) transforms = self.augmentations(aug_input) image = aug_input.image image_shape = image.shape[:2] # h, w # Pytorch's dataloader is efficient on torch.Tensor due to shared-memory, # but not efficient on large generic data structures due to the use of pickle & mp.Queue. # Therefore it's important to use torch.Tensor. dataset_dict["image"] = torch.as_tensor(np.ascontiguousarray(image.transpose(2, 0, 1))) if not self.is_train: dataset_dict.pop("annotations", None) return dataset_dict if "annotations" in dataset_dict: # Maps points from the closed interval [0, image_size - 1] on discrete # image coordinates to the half-open interval [x1, x2) on continuous image # coordinates. We use the continuous-discrete conversion from Heckbert # 1990 ("What is the coordinate of a pixel?"): d = floor(c) and c = d + 0.5, # where d is a discrete coordinate and c is a continuous coordinate. for ann in dataset_dict["annotations"]: point_coords_wrt_image = np.array(ann["point_coords"]).astype(np.float) point_coords_wrt_image = point_coords_wrt_image + 0.5 ann["point_coords"] = point_coords_wrt_image annos = [ # also need to transform point coordinates transform_instance_annotations( obj, transforms, image_shape, ) for obj in dataset_dict.pop("annotations") if obj.get("iscrowd", 0) == 0 ] instances = annotations_to_instances( annos, image_shape, sample_points=self.sample_points, ) dataset_dict["instances"] = utils.filter_empty_instances(instances) return dataset_dict
def __call__(self, dataset_dict): self.tfm_gens = [] dataset_dict = deepcopy(dataset_dict) image = utils.read_image(dataset_dict["file_name"], format=self.img_format) utils.check_image_size(dataset_dict, image) if self.is_train: # Crop '''print("Augmentation: ", "T.RandomCrop('relative', [0.8, 0.4])") crop_gen = T.RandomCrop('relative', [0.8, 0.4]) self.tfm_gens.append(crop_gen)''' # Horizontal flip print("Augmentation: ", "T.RandomFlip(prob=0.5, horizontal=True, vertical=False)") flip_gen = T.RandomFlip(prob=0.5, horizontal=True, vertical=False) self.tfm_gens.append(flip_gen) image, transforms = T.apply_transform_gens(self.tfm_gens, image) image_shape = image.shape[:2] # h, w dataset_dict["image"] = torch.as_tensor( np.ascontiguousarray(image.transpose(2, 0, 1))) if not self.is_train: dataset_dict.pop("annotations", None) return dataset_dict if "annotations" in dataset_dict: for anno in dataset_dict["annotations"]: if not self.mask_on: anno.pop("segmentation", None) annos = [ utils.transform_instance_annotations( obj, transforms, image_shape, keypoint_hflip_indices=self.keypoint_hflip_indices) for obj in dataset_dict.pop("annotations") if obj.get("iscrowd", 0) == 0 ] instances = utils.annotations_to_instances( annos, image_shape, mask_format=self.mask_format) if self.crop_gen and instances.has("gt_masks"): instances.gt_boxes = instances.gt_masks.get_bounding_boxes() dataset_dict["instances"] = utils.filter_empty_instances(instances) return dataset_dict
def mapper(dataset_dict): # Implement a mapper, similar to the default DatasetMapper, but with your own customizations dataset_dict = copy.deepcopy(dataset_dict) # it will be modified by code below image = utils.read_image(dataset_dict["file_name"], format="BGR") image, transforms = T.apply_transform_gens([T.Resize((800, 800))], image) dataset_dict["image"] = torch.as_tensor(image.transpose(2, 0, 1).astype("float32")) annos = [ utils.transform_instance_annotations(obj, transforms, image.shape[:2]) for obj in dataset_dict.pop("annotations") if obj.get("iscrowd", 0) == 0 ] instances = utils.annotations_to_instances(annos, image.shape[:2]) dataset_dict["instances"] = utils.filter_empty_instances(instances) return dataset_dict
def mapper(dataset_dict): dataset_dict = copy.deepcopy(dataset_dict) image = utils.read_image(dataset_dict["file_name"], format="BGR") image, transforms = T.apply_transform_gens([T.Resize((1152, 1152))], image) dataset_dict["image"] = torch.as_tensor( image.transpose(2, 0, 1).astype("float32")) annos = [ transform_instance_annotations(obj, transforms, image.shape[:2]) for obj in dataset_dict.pop("annotations") if obj.get("iscrowd", 0) == 0 ] instances = utils.annotations_to_instances_rotated(annos, image.shape[:2]) dataset_dict["instances"] = utils.filter_empty_instances(instances) return dataset_dict
def custom_mapper(dataset_dict, transform_list): dataset_dict = copy.deepcopy( dataset_dict) # it will be modified by code below image = utils.read_image(dataset_dict["file_name"], format="BGR") image, transforms = T.apply_transform_gens(transform_list, image) dataset_dict["image"] = torch.as_tensor( image.transpose(2, 0, 1).astype("float32")) annos = [ utils.transform_instance_annotations(obj, transforms, image.shape[:2]) for obj in dataset_dict.pop("annotations") ] instances = utils.annotations_to_instances(annos, image.shape[:2]) dataset_dict["instances"] = utils.filter_empty_instances(instances) return dataset_dict
def __call__(self, dataset_dict): """ Args: dataset_dict (dict): Metadata of one image, in Detectron2 Dataset format. Returns: dict: a format that builtin models in detectron2 accept """ dataset_dict = copy.deepcopy( dataset_dict) # it will be modified by code below # USER: Write your own image loading if it's not from a file image = utils.read_image(dataset_dict["file_name"], format=self.image_format) utils.check_image_size(dataset_dict, image) aug_input = T.AugInput(image) transforms = self.augmentations(aug_input) image = aug_input.image image_shape = image.shape[:2] # h, w # Pytorch's dataloader is efficient on torch.Tensor due to shared-memory, # but not efficient on large generic data structures due to the use of pickle & mp.Queue. # Therefore it's important to use torch.Tensor. dataset_dict["image"] = torch.as_tensor( np.ascontiguousarray(image.transpose(2, 0, 1))) if "annotations" in dataset_dict: # USER: Implement additional transformations if you have other types of data annos = [ utils.transform_instance_annotations( obj, transforms, image_shape, keypoint_hflip_indices=self.keypoint_hflip_indices) for obj in dataset_dict.pop("annotations") if obj.get("iscrowd", 0) == 0 ] instances = utils.annotations_to_instances( annos, image_shape, mask_format=self.instance_mask_format) # After transforms such as cropping are applied, the bounding box may no longer # tightly bound the object. As an example, imagine a triangle object # [(0,0), (2,0), (0,2)] cropped by a box [(1,0),(2,2)] (XYXY format). The tight # bounding box of the cropped triangle should be [(1,0),(2,1)], which is not equal to # the intersection of original bounding box and the cropping box. dataset_dict["instances"] = utils.filter_empty_instances(instances) return dataset_dict
def __call__(self, data_dict): data_dict = copy.deepcopy(data_dict) image = cv2.imread(data_dict["file_name"], cv2.IMREAD_UNCHANGED) image = image[:, :, :self.nb_channels] # if image.shape[2] == 4: # conversion = cv2.COLOR_BGRA2RGBA # else: # conversion = cv2.COLOR_BGR2RGB # image = cv2.cvtColor(image, conversion) # data_dict["image"] = torch.as_tensor(image.transpose(2, 0, 1) # .astype("float32")) if self.augmenter: rgb_image = image[:, :, :3] ndvi_image = None if image.shape[2] == 4: ndvi_image = image[:, :, 3] data_dict["original_annotations"] = data_dict["annotations"] data_dict["original_image"] = image augmented = self.augmenter(rgb_image, data_dict["annotations"], ndvi_image) data_dict["annotations"] = augmented["annotations"] if augmented['ndvi'] is not None: image = np.dstack([augmented["rgb_image"], augmented["ndvi"]]) else: image = augmented["rgb_image"] if self.cfg.INPUT.FORMAT == "BGR": image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) elif self.cfg.INPUT.FORMAT == "BGRN": image = cv2.cvtColor(image, cv2.COLOR_RGBA2BGRA) data_dict["image"] = torch.as_tensor( image.transpose(2, 0, 1).astype("float32")) instances = det_utils.annotations_to_instances( data_dict["annotations"], image.shape[:2]) data_dict["instances"] = det_utils.filter_empty_instances(instances) return data_dict
def __call__(self, dataset_dict): dataset_dict = copy.deepcopy(dataset_dict) image = utils.read_image(dataset_dict["file_name"], format="BGR") aug_input = T.AugInput(image) transforms = self.augmentations(aug_input) image = aug_input.image image_shape = image.shape[:2] #h, w dataset_dict["image"] = torch.as_tensor( image.transpose(2, 0, 1).astype("float32")) annos = [ utils.transform_instance_annotations(obj, transforms, image_shape) for obj in dataset_dict.pop("annotations") if obj.get("iscrowd", 0) == 0 ] instances = utils.annotations_to_instances(annos, image_shape) dataset_dict["instances"] = utils.filter_empty_instances(instances) return dataset_dict
def __call__(self, dataset_dict): """ Args: dataset_dict (dict): Metadata of one image, in Detectron2 Dataset format. Returns: dict: a format that builtin models in detectron2 accept """ image_shape = dataset_dict['height'], dataset_dict['width'] annos = dataset_dict["annotations"] mislabeled = [obj["mislabeled"] for obj in annos] instances = utils.annotations_to_instances( annos, image_shape, mask_format=self.instance_mask_format) instances.gt_mislabeled = torch.tensor(mislabeled, dtype=torch.bool) dataset_dict = super(CustomDatasetMapper, self).__call__(dataset_dict) dataset_dict["instances"] = utils.filter_empty_instances(instances) return dataset_dict
def customMapper(dataset_dict): dataset_dict = copy.deepcopy(dataset_dict) image = utils.read_image(dataset_dict["file_name"], format="BGR") transform_list = [ T.Resize((600, 800)), T.RandomFlip(prob=0.6, horizontal=True, vertical=False), T.RandomFlip(prob=0.6, horizontal=False, vertical=True), ] image, transforms = T.apply_transform_gens(transform_list, image) dataset_dict["image"] = torch.as_tensor(image.transpose(2, 0, 1).astype("float32")) annos = [ utils.transform_instance_annotations(obj, transforms, image.shape[:2]) for obj in dataset_dict.pop("annotations") if obj.get("iscrowd", 0) == 0 ] instances = utils.annotations_to_instances(annos, image.shape[:2]) dataset_dict["instances"] = utils.filter_empty_instances(instances) return dataset_dict
def __call__(self, dataset_dict): """ Args: dataset_dict (dict): Metadata of one image, in Detectron2 Dataset format. Returns: dict: a format that builtin models in detectron2 accept """ # Implement a mapper, similar to the default DatasetMapper, but with own customizations dataset_dict = copy.deepcopy( dataset_dict) # it will be modified by code below image = utils.read_image(dataset_dict["file_name"], format="BGR") # Custom augs to be used while training # Only HFlip and Resize are supported for rotated_boxes augs = [T.RandomFlip(0.4, horizontal=True, vertical=False)] #[T.RandomRotation([0,90])] if self.is_train: tfm_gens = self.tfm_gens + augs else: tfm_gens = self.tfm_gens logging.getLogger(__name__).info("Original Augmentation: " + str(self.tfm_gens)) logging.getLogger(__name__).info("Updated Augmentation List: " + str(tfm_gens)) image, transforms = T.apply_transform_gens(tfm_gens, image) dataset_dict["image"] = torch.as_tensor( image.transpose(2, 0, 1).astype("float32")) for a in dataset_dict['annotations']: a['bbox'] = transforms.apply_rotated_box(np.asarray( [a['bbox']]))[0].tolist() annos = dataset_dict['annotations'] instances = utils.annotations_to_instances_rotated( annos, image.shape[:2]) dataset_dict["instances"] = utils.filter_empty_instances(instances) return dataset_dict
def custom_mapper(input_dict): dataset_dict = copy.deepcopy( input_dict) # it will be modified by code below image = utils.read_image(dataset_dict["file_name"], format="BGR") transform_list = [ T.Resize((1200, 1200)), T.RandomFlip(prob=0.6, horizontal=True, vertical=False), T.RandomFlip(prob=0.6, horizontal=False, vertical=True), T.RandomContrast(0.7, 3.2), T.RandomBrightness(0.6, 1.8), ] image, transforms = T.apply_transform_gens(transform_list, image) dataset_dict["image"] = torch.as_tensor( image.transpose(2, 0, 1).astype("float32")) annos = [ utils.transform_instance_annotations(obj, transforms, image.shape[:2]) for obj in dataset_dict.pop("annotations") ] instances = utils.annotations_to_instances(annos, image.shape[:2]) dataset_dict["instances"] = utils.filter_empty_instances(instances) return dataset_dict
def custom_mapper(dataset_dict): dataset_dict = copy.deepcopy( dataset_dict) # it will be modified by code below image = utils.read_image(dataset_dict["file_name"], format="BGR") transform_list = [ InvertColors(), T.RandomBrightness(0.8, 1.8), T.RandomContrast(0.6, 1.3), T.RandomSaturation(0.8, 1.4), T.RandomLighting(0.7), ] image, transforms = T.apply_transform_gens(transform_list, image) dataset_dict["image"] = torch.as_tensor( image.transpose(2, 0, 1).astype("float32")) annos = [ utils.transform_instance_annotations(obj, transforms, image.shape[:2]) for obj in dataset_dict.pop("annotations") ] instances = utils.annotations_to_instances(annos, image.shape[:2]) dataset_dict["instances"] = utils.filter_empty_instances(instances) return dataset_dict
def mapper(dataset_dict): # Implement a mapper, similar to the default DatasetMapper, but with your own customizations dataset_dict = copy.deepcopy( dataset_dict) # it will be modified by code below image = utils.read_image(dataset_dict["file_name"], format="BGR") handler = load_augmentation_settings( handler_save_path='augmentation_settings.json') image, dataset_dict = handler(image=image, dataset_dict_detectron=dataset_dict) annots = [ obj for obj in dataset_dict.pop("annotations") if obj.get("iscrowd", 0) == 0 ] dataset_dict["image"] = torch.as_tensor( image.transpose(2, 0, 1).astype("float32")) instances = utils.annotations_to_instances(annots, image.shape[:2]) dataset_dict["instances"] = utils.filter_empty_instances(instances) return dataset_dict
def mapper(dataset_dict): # Implement a mapper, similar to the default DatasetMapper, but with your own customizations dataset_dict = copy.deepcopy(dataset_dict) # it will be modified by code below image = utils.read_image(dataset_dict["file_name"], format="BGR") #print(dataset_dict["file_name"]) #cv2.imwrite(os.path.join(aug_save_path, f'{str(count.count)}_asd.jpg'),image) handler = load_augmentation_settings(handler_save_path = 'test_handler.json') for i in range(len(dataset_dict["annotations"])): dataset_dict["annotations"][i]["segmentation"] = [] image, dataset_dict = handler(image=image, dataset_dict_detectron=dataset_dict) annots = [] for item in dataset_dict["annotations"]: annots.append(item) dataset_dict["image"] = torch.as_tensor(image.transpose(2, 0, 1).astype("float32")) instances = utils.annotations_to_instances(annots, image.shape[:2]) dataset_dict["instances"] = utils.filter_empty_instances(instances) if True: vis_img = image.copy() bbox_list = [BBox.from_list(vals) for vals in dataset_dict["instances"].gt_boxes.tensor.numpy().tolist()] # seg_list = [Segmentation([Polygon.from_list(poly.tolist(), demarcation=False) for poly in seg_polys]) for seg_polys in dataset_dict["instances"].gt_masks.polygons] for bbox in (bbox_list): # if len(seg) > 0 and False: # vis_img = draw_segmentation(img=vis_img, segmentation=seg, transparent=True) vis_img = draw_bbox(img=vis_img, bbox=bbox) height,width,channels = vis_img.shape print(height,width) if count.count<100: cv2.imwrite(os.path.join(aug_save_path, f'{str(count.count)}.jpg'),vis_img) count.count_add() aug_vis.step(vis_img) return dataset_dict
def mapper(dataset_dict): # Implement a mapper, similar to the default DatasetMapper, but with your own customizations dataset_dict = copy.deepcopy( dataset_dict) # it will be modified by code below image = utils.read_image(dataset_dict["file_name"], format="BGR") masks = anno_to_mask(image, dataset_dict['annotations']) #plt.figure(1);plt.subplot(211);plt.imshow(image);plt.subplot(212);plt.imshow(masks.sum(axis=2)) # Crop and augmentation image, masks = random_crop(image, masks) masks = masks[:, :, np.where(masks.sum(axis=(0, 1)) > 50)[0]] augmentation = create_augmentation() image, masks = imgaug_augmentation(image, masks, augmentation) masks = masks[:, :, np.where(masks.sum(axis=(0, 1)) > 50)[0]] masks = masks.transpose([2, 0, 1]) annotations = masks_to_anno(masks) #plt.figure(2);plt.subplot(211);plt.imshow(image);plt.subplot(212);plt.imshow(masks.sum(axis=0)) # Save into dataset_dict dataset_dict["image"] = torch.as_tensor( image.transpose(2, 0, 1).astype("float32")) instances = utils.annotations_to_instances(annotations, image.shape[:2]) dataset_dict["instances"] = utils.filter_empty_instances(instances) return dataset_dict