<filename>front_end/bg_mapper.py

from PIL import Image
import copy
import numpy as np
import torch
from kkimgaug.lib.aug_det2 import Mapper
import detectron2.data.detection_utils as utils
import detectron2.data.transforms as T

# https://en.wikipedia.org/wiki/YUV#SDTV_with_BT.601
_M_RGB2YUV = [[0.299, 0.587, 0.114], [-0.14713, -0.28886, 0.436], [0.615, -0.51499, -0.10001]]
_M_YUV2RGB = [[1.0, 0.0, 1.13983], [1.0, -0.39465, -0.58060], [1.0, 2.03211, 0.0]]


def has_transparency(img):
    if img.mode == "P":
        transparent = img.info.get("transparency", -1)
        for _, index in img.getcolors():
            if index == transparent:
                return True
    elif img.mode == "RGBA":
        extrema = img.getextrema()
        if extrema[3][0] < 255:
            return True

    return False

def convert_PIL_to_numpy(image, format="BGR"):
    import numpy as np
    """
    Convert PIL image to numpy array of target format.
    Args:
        image (PIL.Image): a PIL image
        format (str): the format of output image
    Returns:
        (np.ndarray): also see `read_image`
    """
    if format is not None:
        # PIL only supports RGB, so convert to RGB and flip channels over below
        conversion_format = format
        if format in ["BGR", "YUV-BT.601"]:
            conversion_format = "RGB"
        image = image.convert(conversion_format)
    image = np.asarray(image)
    # PIL squeezes out the channel dimension for "L", so make it HWC
    if format == "L":
        image = np.expand_dims(image, -1)

    # handle formats not supported by PIL
    elif format == "BGR":
        # flip channels if needed
        image = image[:, :, ::-1]
    elif format == "YUV-BT.601":
        image = image / 255.0
        image = np.dot(image, np.array(_M_RGB2YUV).T)

    return image

def get_random_bg_image(folder):
    import os
    import random

    choose_random = random.choice(os.listdir(folder))

    return Image.open(os.path.join(folder, choose_random))

def add_bg_image(background_dir, image):

    if background_dir is not None:
        background = get_random_bg_image(folder = background_dir)
    
        # resize the image
        size = image.size[:2]
        background = background.resize(size,Image.ANTIALIAS)
        background.paste(image, (0, 0), image)
        return background
    else:
        return image

def new_call(self, dataset_dict):
    """
    copy "__call__" function of detectron2.data.dataset_mapper.DatasetMapper 
    """
    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)

    ### BG add if RGBA?##
    image = Image.open(dataset_dict["file_name"])
    print("new_call")
    if has_transparency(image):
        print("has transparency")
        image = convert_PIL_to_numpy( add_bg_image(self.background_dir, image), format=self.image_format)
    else:
        print("no transparency??")
        image = utils.read_image(dataset_dict["file_name"], format=self.image_format)
    ### my code ##        

    ##### My Code #####
    transformed = self.composer(
        image=image,
        bboxes=[x["bbox"] if x.get("bbox") else [] for x in dataset_dict["annotations"]],
        mask=[x["segmentation"] if x.get("segmentation") else [] for x in dataset_dict["annotations"]],
        keypoints=[x["keypoints"] if x.get("keypoints") else [] for x in dataset_dict["annotations"]],
    )
    image = transformed["image"]
    if "annotations" in dataset_dict:
        if transformed.get("label_bbox") is not None and len(transformed["label_bbox"]) > 0:
            dataset_dict["annotations"] = np.array(dataset_dict["annotations"])[transformed["label_bbox"]].tolist()
        else:
            dataset_dict["annotations"] = []
        for i, dictwk in enumerate(dataset_dict["annotations"]):
            if "bbox" in dictwk:
                dictwk["bbox"] = transformed["bboxes"][i]
            if "keypoints" in dictwk and len(dictwk["keypoints"]) > 0:
                dictwk["keypoints"] = transformed["keypoints"][i]
            if "segmentation" in dictwk and len(dictwk["segmentation"]) > 0:
                dictwk["segmentation"] = transformed["mask"][i]
    ##### My Code #####

    # USER: Remove if you don't do semantic/panoptic segmentation.
    if "sem_seg_file_name" in dataset_dict:
        sem_seg_gt = utils.read_image(dataset_dict.pop("sem_seg_file_name"), "L").squeeze(2)
    else:
        sem_seg_gt = None

    aug_input = T.AugInput(image, sem_seg=sem_seg_gt)
    transforms = self.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"))

    # USER: Remove if you don't use pre-computed proposals.
    # Most users would not need this feature.
    if self.proposal_topk is not None:
        utils.transform_proposals(
            dataset_dict, image_shape, transforms, proposal_topk=self.proposal_topk
        )

    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

    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.use_instance_mask:
                anno.pop("segmentation", None)
            if not self.use_keypoint:
                anno.pop("keypoints", None)

        # 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.
        if self.recompute_boxes:
            instances.gt_boxes = instances.gt_masks.get_bounding_boxes()
        dataset_dict["instances"] = utils.filter_empty_instances(instances)
    return dataset_dict

# local files
from kkimgaug.lib import BaseCompose
from kkimgaug.util.procs import bgr2rgb, rgb2bgr, mask_from_polygon_to_bool, mask_from_bool_to_polygon, \
    kpt_from_coco_to_xy, to_uint8, restore_kpt_coco_format, get_applied_augmentations, bbox_label_auto, \
    check_coco_annotations, mask_inside_bbox, bbox_compute_from_mask

class BGMapper(Mapper):

    def __init__(self, *args, background_dir=None, **kwargs):
        super().__init__(*args, **kwargs)
        self.background_dir = background_dir

    def __call__(self, dataset_dict):
        """
        copy "__call__" function of detectron2.data.dataset_mapper.DatasetMapper 
        """
        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)

        ### BG add if RGBA?##
        image = Image.open(dataset_dict["file_name"])
        if has_transparency(image):
            print("has transparency")
            image = convert_PIL_to_numpy( add_bg_image(self.background_dir, image), format=self.image_format)
        else:
            image = utils.read_image(dataset_dict["file_name"], format=self.image_format)
        ### my code ##        

        ##### My Code #####
        transformed = self.composer(
            image=image,
            bboxes=[x["bbox"] if x.get("bbox") else [] for x in dataset_dict["annotations"]],
            mask=[x["segmentation"] if x.get("segmentation") else [] for x in dataset_dict["annotations"]],
            keypoints=[x["keypoints"] if x.get("keypoints") else [] for x in dataset_dict["annotations"]],
        )
        image = transformed["image"]
        if "annotations" in dataset_dict:
            if transformed.get("label_bbox") is not None and len(transformed["label_bbox"]) > 0:
                dataset_dict["annotations"] = np.array(dataset_dict["annotations"])[transformed["label_bbox"]].tolist()
            else:
                dataset_dict["annotations"] = []
            for i, dictwk in enumerate(dataset_dict["annotations"]):
                if "bbox" in dictwk:
                    dictwk["bbox"] = transformed["bboxes"][i]
                if "keypoints" in dictwk and len(dictwk["keypoints"]) > 0:
                    dictwk["keypoints"] = transformed["keypoints"][i]
                if "segmentation" in dictwk and len(dictwk["segmentation"]) > 0:
                    dictwk["segmentation"] = transformed["mask"][i]
        ##### My Code #####

        # USER: Remove if you don't do semantic/panoptic segmentation.
        if "sem_seg_file_name" in dataset_dict:
            sem_seg_gt = utils.read_image(dataset_dict.pop("sem_seg_file_name"), "L").squeeze(2)
        else:
            sem_seg_gt = None

        aug_input = T.AugInput(image, sem_seg=sem_seg_gt)
        transforms = self.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"))

        # USER: Remove if you don't use pre-computed proposals.
        # Most users would not need this feature.
        if self.proposal_topk is not None:
            utils.transform_proposals(
                dataset_dict, image_shape, transforms, proposal_topk=self.proposal_topk
            )

        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

        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.use_instance_mask:
                    anno.pop("segmentation", None)
                if not self.use_keypoint:
                    anno.pop("keypoints", None)

            # 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.
            if self.recompute_boxes:
                instances.gt_boxes = instances.gt_masks.get_bounding_boxes()
            dataset_dict["instances"] = utils.filter_empty_instances(instances)
        return dataset_dict
<filename>front_end/bg_mapper.py

from PIL import Image
import copy
import numpy as np
import torch
from kkimgaug.lib.aug_det2 import Mapper
import detectron2.data.detection_utils as utils
import detectron2.data.transforms as T

# https://en.wikipedia.org/wiki/YUV#SDTV_with_BT.601
_M_RGB2YUV = [[0.299, 0.587, 0.114], [-0.14713, -0.28886, 0.436], [0.615, -0.51499, -0.10001]]
_M_YUV2RGB = [[1.0, 0.0, 1.13983], [1.0, -0.39465, -0.58060], [1.0, 2.03211, 0.0]]


def has_transparency(img):
    if img.mode == "P":
        transparent = img.info.get("transparency", -1)
        for _, index in img.getcolors():
            if index == transparent:
                return True
    elif img.mode == "RGBA":
        extrema = img.getextrema()
        if extrema[3][0] < 255:
            return True

    return False

def convert_PIL_to_numpy(image, format="BGR"):
    import numpy as np
    """
    Convert PIL image to numpy array of target format.
    Args:
        image (PIL.Image): a PIL image
        format (str): the format of output image
    Returns:
        (np.ndarray): also see `read_image`
    """
    if format is not None:
        # PIL only supports RGB, so convert to RGB and flip channels over below
        conversion_format = format
        if format in ["BGR", "YUV-BT.601"]:
            conversion_format = "RGB"
        image = image.convert(conversion_format)
    image = np.asarray(image)
    # PIL squeezes out the channel dimension for "L", so make it HWC
    if format == "L":
        image = np.expand_dims(image, -1)

    # handle formats not supported by PIL
    elif format == "BGR":
        # flip channels if needed
        image = image[:, :, ::-1]
    elif format == "YUV-BT.601":
        image = image / 255.0
        image = np.dot(image, np.array(_M_RGB2YUV).T)

    return image

def get_random_bg_image(folder):
    import os
    import random

    choose_random = random.choice(os.listdir(folder))

    return Image.open(os.path.join(folder, choose_random))

def add_bg_image(background_dir, image):

    if background_dir is not None:
        background = get_random_bg_image(folder = background_dir)
    
        # resize the image
        size = image.size[:2]
        background = background.resize(size,Image.ANTIALIAS)
        background.paste(image, (0, 0), image)
        return background
    else:
        return image

def new_call(self, dataset_dict):
    """
    copy "__call__" function of detectron2.data.dataset_mapper.DatasetMapper 
    """
    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)

    ### BG add if RGBA?##
    image = Image.open(dataset_dict["file_name"])
    print("new_call")
    if has_transparency(image):
        print("has transparency")
        image = convert_PIL_to_numpy( add_bg_image(self.background_dir, image), format=self.image_format)
    else:
        print("no transparency??")
        image = utils.read_image(dataset_dict["file_name"], format=self.image_format)
    ### my code ##        

    ##### My Code #####
    transformed = self.composer(
        image=image,
        bboxes=[x["bbox"] if x.get("bbox") else [] for x in dataset_dict["annotations"]],
        mask=[x["segmentation"] if x.get("segmentation") else [] for x in dataset_dict["annotations"]],
        keypoints=[x["keypoints"] if x.get("keypoints") else [] for x in dataset_dict["annotations"]],
    )
    image = transformed["image"]
    if "annotations" in dataset_dict:
        if transformed.get("label_bbox") is not None and len(transformed["label_bbox"]) > 0:
            dataset_dict["annotations"] = np.array(dataset_dict["annotations"])[transformed["label_bbox"]].tolist()
        else:
            dataset_dict["annotations"] = []
        for i, dictwk in enumerate(dataset_dict["annotations"]):
            if "bbox" in dictwk:
                dictwk["bbox"] = transformed["bboxes"][i]
            if "keypoints" in dictwk and len(dictwk["keypoints"]) > 0:
                dictwk["keypoints"] = transformed["keypoints"][i]
            if "segmentation" in dictwk and len(dictwk["segmentation"]) > 0:
                dictwk["segmentation"] = transformed["mask"][i]
    ##### My Code #####

    # USER: Remove if you don't do semantic/panoptic segmentation.
    if "sem_seg_file_name" in dataset_dict:
        sem_seg_gt = utils.read_image(dataset_dict.pop("sem_seg_file_name"), "L").squeeze(2)
    else:
        sem_seg_gt = None

    aug_input = T.AugInput(image, sem_seg=sem_seg_gt)
    transforms = self.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"))

    # USER: Remove if you don't use pre-computed proposals.
    # Most users would not need this feature.
    if self.proposal_topk is not None:
        utils.transform_proposals(
            dataset_dict, image_shape, transforms, proposal_topk=self.proposal_topk
        )

    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

    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.use_instance_mask:
                anno.pop("segmentation", None)
            if not self.use_keypoint:
                anno.pop("keypoints", None)

        # 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.
        if self.recompute_boxes:
            instances.gt_boxes = instances.gt_masks.get_bounding_boxes()
        dataset_dict["instances"] = utils.filter_empty_instances(instances)
    return dataset_dict

# local files
from kkimgaug.lib import BaseCompose
from kkimgaug.util.procs import bgr2rgb, rgb2bgr, mask_from_polygon_to_bool, mask_from_bool_to_polygon, \
    kpt_from_coco_to_xy, to_uint8, restore_kpt_coco_format, get_applied_augmentations, bbox_label_auto, \
    check_coco_annotations, mask_inside_bbox, bbox_compute_from_mask

class BGMapper(Mapper):

    def __init__(self, *args, background_dir=None, **kwargs):
        super().__init__(*args, **kwargs)
        self.background_dir = background_dir

    def __call__(self, dataset_dict):
        """
        copy "__call__" function of detectron2.data.dataset_mapper.DatasetMapper 
        """
        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)

        ### BG add if RGBA?##
        image = Image.open(dataset_dict["file_name"])
        if has_transparency(image):
            print("has transparency")
            image = convert_PIL_to_numpy( add_bg_image(self.background_dir, image), format=self.image_format)
        else:
            image = utils.read_image(dataset_dict["file_name"], format=self.image_format)
        ### my code ##        

        ##### My Code #####
        transformed = self.composer(
            image=image,
            bboxes=[x["bbox"] if x.get("bbox") else [] for x in dataset_dict["annotations"]],
            mask=[x["segmentation"] if x.get("segmentation") else [] for x in dataset_dict["annotations"]],
            keypoints=[x["keypoints"] if x.get("keypoints") else [] for x in dataset_dict["annotations"]],
        )
        image = transformed["image"]
        if "annotations" in dataset_dict:
            if transformed.get("label_bbox") is not None and len(transformed["label_bbox"]) > 0:
                dataset_dict["annotations"] = np.array(dataset_dict["annotations"])[transformed["label_bbox"]].tolist()
            else:
                dataset_dict["annotations"] = []
            for i, dictwk in enumerate(dataset_dict["annotations"]):
                if "bbox" in dictwk:
                    dictwk["bbox"] = transformed["bboxes"][i]
                if "keypoints" in dictwk and len(dictwk["keypoints"]) > 0:
                    dictwk["keypoints"] = transformed["keypoints"][i]
                if "segmentation" in dictwk and len(dictwk["segmentation"]) > 0:
                    dictwk["segmentation"] = transformed["mask"][i]
        ##### My Code #####

        # USER: Remove if you don't do semantic/panoptic segmentation.
        if "sem_seg_file_name" in dataset_dict:
            sem_seg_gt = utils.read_image(dataset_dict.pop("sem_seg_file_name"), "L").squeeze(2)
        else:
            sem_seg_gt = None

        aug_input = T.AugInput(image, sem_seg=sem_seg_gt)
        transforms = self.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"))

        # USER: Remove if you don't use pre-computed proposals.
        # Most users would not need this feature.
        if self.proposal_topk is not None:
            utils.transform_proposals(
                dataset_dict, image_shape, transforms, proposal_topk=self.proposal_topk
            )

        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

        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.use_instance_mask:
                    anno.pop("segmentation", None)
                if not self.use_keypoint:
                    anno.pop("keypoints", None)

            # 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.
            if self.recompute_boxes:
                instances.gt_boxes = instances.gt_masks.get_bounding_boxes()
            dataset_dict["instances"] = utils.filter_empty_instances(instances)
        return dataset_dict
# https://en.wikipedia.org/wiki/YUV#SDTV_with_BT.601 Convert PIL image to numpy array of target format.     Args:         image (PIL.Image): a PIL image         format (str): the format of output image     Returns:         (np.ndarray): also see `read_image` # PIL only supports RGB, so convert to RGB and flip channels over below # PIL squeezes out the channel dimension for "L", so make it HWC # handle formats not supported by PIL # flip channels if needed # resize the image copy "__call__" function of detectron2.data.dataset_mapper.DatasetMapper # it will be modified by code below # USER: Write your own image loading if it's not from a file ### BG add if RGBA?## ### my code ## ##### My Code ##### ##### My Code ##### # USER: Remove if you don't do semantic/panoptic segmentation. # 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. # USER: Remove if you don't use pre-computed proposals. # Most users would not need this feature. # USER: Modify this if you want to keep them for some reason. # USER: Modify this if you want to keep them for some reason. # USER: Implement additional transformations if you have other types of data # 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. # local files copy "__call__" function of detectron2.data.dataset_mapper.DatasetMapper # it will be modified by code below # USER: Write your own image loading if it's not from a file ### BG add if RGBA?## ### my code ## ##### My Code ##### ##### My Code ##### # USER: Remove if you don't do semantic/panoptic segmentation. # 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. # USER: Remove if you don't use pre-computed proposals. # Most users would not need this feature. # USER: Modify this if you want to keep them for some reason. # USER: Modify this if you want to keep them for some reason. # USER: Implement additional transformations if you have other types of data # 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.