Exemplo n.º 1
0
def save_image_file(image, img_type, dataset, path):
    """
    Brings the image in the right format to be saved. Therefore, it reverses all load transforms

    :param image: PIL image
    :param img_type: color, depth, segmentation
    :param dataset: e.g. 'cityscapes'
    :param path: path of the destination path
    """

    depth_transformer = mytransforms.LoadDepth()
    segmentation_transformer = mytransforms.LoadSegmentation()

    image = np.array(image)  # convert from PIL to openCV

    if 'color' in img_type:
        image = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)

    elif 'depth' in img_type:
        image = depth_transformer.inverse({img_type: image})[img_type]
        # image = image.astype(np.uint16)

    elif 'segmentation' in img_type:
        image = segmentation_transformer.inverse({img_type: image})[img_type]
        # image = np.array(image, dtype=np.uint8)

    cv2.imwrite(path, image)
Exemplo n.º 2
0
    def _load_sample(self, si):
        """
        Loads the specified sample.

        :param si: dict of the form {global_index: {"color": path, "depth": path, ...}}
        :return: - the global index of the sample in the dataset
                 - the sample in the standard dataloader format
                 - a path dictionary that is built similar to the sample dictionary and contains the image path instead of
                   an image object
        """
        set_idx, sample = si

        dataset = sample.pop('dataset')
        dataset_path = sample.pop('dataset_path')

        new_sample = dict()
        paths = dict()

        for key, content in sample.items():
            assert any(key.startswith(s) for s in SEGMENTATION_KEYS)
            filepath = os.path.join(dataset_path, content)
            filepath = filepath.replace('/', os.sep)
            filepath = filepath.replace('\\', os.sep)
            image = cv2.imread(filepath, -1)
            new_sample[key, 0, 0] = image
            paths[key, 0, 0] = content

        # By using the transform ConvertSegmentation, the segmentation images will be converted to the train_id format
        load_transforms = transforms.Compose([
            mytransforms.LoadSegmentation(),
            mytransforms.ConvertSegmentation(labels=self.labels, labels_mode=self.labels_mode)
        ])
        new_sample = load_transforms(new_sample)

        return set_idx, new_sample, paths
Exemplo n.º 3
0
def load_sample(si):
    """
    Loads the specified sample.

    :param si: dict of the form {global_index: {"color": path, "depth": path, ...}}
    :return: - the global index of the sample in the dataset
             - the sample in the standard dataloader format
             - a path dictionary that is built similar to the sample dictionary and contains the image path instead of
               an image object
    """
    set_idx, sample = si

    dataset = sample.pop('dataset')
    dataset_path = sample.pop('dataset_path')
    depth_mode = sample.pop('depth_mode')

    new_sample = dict()
    paths = dict()

    for key, content in sample.items():
        if any(key.startswith(s) for s in IMAGE_KEYS):
            filepath = os.path.join(dataset_path, content)
            filepath = filepath.replace('/', os.sep)
            filepath = filepath.replace('\\', os.sep)

            image = cv2.imread(filepath, -1)

            new_sample[key, 0, 0] = image
            paths[key, 0, 0] = content

        else:
            new_sample[key, 0, 0] = content

    load_transforms = transforms.Compose([
        mytransforms.LoadRGB(),
        mytransforms.LoadSegmentation(),
        mytransforms.LoadDepth(),
        mytransforms.LoadNumerics()
    ])

    new_sample = load_transforms(new_sample)

    return set_idx, new_sample, paths
Exemplo n.º 4
0
    def __init__(self,
                 dataset,
                 trainvaltest_split,
                 video_mode='mono',
                 stereo_mode='mono',
                 cluster_mode=None,
                 simple_mode=False,
                 labels=None,
                 labels_mode=None,
                 data_transforms=None,
                 scales=None,
                 keys_to_load=None,
                 keys_to_video=None,
                 keys_to_stereo=None,
                 split=None,
                 video_frames=None,
                 disable_const_items=True,
                 folders_to_load=None,
                 files_to_load=None,
                 n_files=None,
                 output_filenames=False,
                 flow_validation_mode=True):
        """Initialises the dataset by loading the desired data from the json file

        :param dataset: name of the dataset
        :param trainvaltest_split: can be train, validation or test
        :param video_mode: can be mono or video and defines if only the images or image sequences are to be loaded
        :param stereo_mode: can be mono or stereo and defines if the stereo images are to be loaded
        :param simple_mode: if True, the Data is read directly from a folder without using a .json file
        :param labels: gives the labels as defined in the named tuples style in Cityscapes. Get the labels from
            defintions folder
        :param labels_mode: can be fromid or fromrgb and defines if the segmentation masks are given as id or color
        :param data_transforms: takes the transforms.compose list
        :param scales: list of all scales at which the images should be loaded (list of exponents for powers of 2)
        :param keys_to_load: defines all keys which should be loaded
        :param keys_to_video: defines for which keys the sequences are to be loaded
        :param keys_to_stereo: defines for which keys the stereo images are supposed to be loaded
        :param split: dataset split that is supposed to be loaded. default is the complete dataset itself
        :param video_frames: all frames of the sequence that are supposed to be loaded (list of frame numbers relative
            to the main frame, e.g. [0, -2, -1, 1, 2])
        :param disable_const_items: removes the constant items like camera calibration from loading procedure
        :param folders_to_load: list of folders from which data should be loaded; folders not mentioned are skipped in
            the respective set. Only the last folder in a path is considered; filter is case insensitive.
            Default: None -> all folders are loaded from dataset
        :param files_to_load: list of files that should be loaded; files not mentioned are skipped in the respective
            set. File names need not be complete; filter is case insensitive.
            Default: None -> all files are loaded from dataset
        :param n_files: How many files shall be loaded. Files are selected randomly if there are more files than n_files
            Seeded by numpy.random.seed()
        """
        super(BaseDataset, self).__init__()
        assert isinstance(dataset, str)
        assert trainvaltest_split in (
            'train', 'validation',
            'test'), '''trainvaltest_split must be train,
        validation or test'''
        assert video_mode in ('mono',
                              'video'), 'video_mode must be mono or video'
        assert stereo_mode in ('mono',
                               'stereo'), 'stereo_mode must be mono or stereo'
        assert isinstance(simple_mode, bool)
        if data_transforms is None:
            data_transforms = [
                mytransforms.CreateScaledImage(),
                mytransforms.CreateColoraug(),
                mytransforms.ToTensor()
            ]
        if scales is None:
            scales = [0]
        if keys_to_load is None:
            keys_to_load = ['color']
        if keys_to_stereo is None and stereo_mode == 'stereo':
            keys_to_stereo = ['color']
        if keys_to_video is None and video_mode == 'video':
            keys_to_video = ['color']
        if video_frames is None:
            video_frames = [0, -1, 1]

        self.dataset = dataset
        self.video_mode = video_mode
        self.stereo_mode = stereo_mode
        self.scales = scales
        self.disable_const_items = disable_const_items
        self.output_filenames = output_filenames
        self.parameters = dps.DatasetParameterset(dataset)
        if labels is not None:
            self.parameters.labels = labels
        if labels_mode is not None:
            self.parameters.labels_mode = labels_mode
        path_getter = gp.GetPath()
        dataset_folder = path_getter.get_data_path()
        datasetpath = os.path.join(dataset_folder, self.dataset)
        self.datasetpath = datasetpath
        if split is None:
            splitpath = None
        else:
            splitpath = os.path.join(dataset_folder,
                                     self.dataset + '_' + split)

        if simple_mode is False:
            self.data = self.read_json_file(datasetpath, splitpath,
                                            trainvaltest_split, keys_to_load,
                                            keys_to_stereo, keys_to_video,
                                            video_frames, folders_to_load,
                                            files_to_load, n_files)
        else:
            self.data = self.read_from_folder(datasetpath, keys_to_load,
                                              video_mode, video_frames)

        self.load_transforms = transforms.Compose([
            mytransforms.LoadRGB(),
            mytransforms.LoadSegmentation(),
            mytransforms.LoadDepth(),
            mytransforms.LoadFlow(validation_mode=flow_validation_mode),
            mytransforms.LoadNumerics()
        ])

        # IMPORTANT to create a new list if the same list is passed to multiple datasets. Otherwise, due to the
        # mutability of lists, ConvertSegmentation will only be added once. Hence, the labels may be wrong for the 2nd,
        # 3rd, ... dataset!
        self.data_transforms = list(data_transforms)

        # Error if CreateColorAug and CreateScaledImage not in transforms.
        if mytransforms.CreateScaledImage not in data_transforms:
            raise Exception(
                'The transform CreateScaledImage() has to be part of the data_transforms list'
            )
        if mytransforms.CreateColoraug not in data_transforms:
            raise Exception(
                'The transform CreateColoraug() has to be part of the data_transforms list'
            )

        # Error if depth, segmentation or flow keys are given but not the corresponding Convert-Transform
        if any([key.startswith('segmentation') for key in keys_to_load]) and \
                mytransforms.ConvertSegmentation not in self.data_transforms:
            raise Exception(
                'When loading segmentation images, please add mytransforms.ConvertSegmentation() to '
                'the data_transforms')
        if any([key.startswith('depth') for key in keys_to_load]) and \
                mytransforms.ConvertDepth not in self.data_transforms:
            raise Exception(
                'When loading depth images, please add mytransforms.ConvertDepth() to the data_transforms'
            )
        if any([key.startswith('flow') for key in keys_to_load]) and \
                mytransforms.ConvertFlow not in self.data_transforms:
            raise Exception(
                'When loading flow images, please add mytransforms.ConvertFlow() to the data_transforms'
            )

        # In the flow validation mode, it is not allowed to use data-altering transforms
        if any([key.startswith('flow')
                for key in keys_to_load]) and flow_validation_mode:
            allowed_transforms = [
                mytransforms.CreateScaledImage, mytransforms.CreateColoraug,
                mytransforms.ConvertSegmentation, mytransforms.ConvertDepth,
                mytransforms.ConvertFlow, mytransforms.RemoveOriginals,
                mytransforms.ToTensor, mytransforms.Relabel,
                mytransforms.OneHotEncoding, mytransforms.NormalizeZeroMean,
                mytransforms.AdjustKeys, mytransforms.RemapKeys,
                mytransforms.AddKeyValue
            ]
            for transform in self.data_transforms:
                if transform not in allowed_transforms:
                    raise Exception(
                        'In flow validation mode, it is not allowed to use data-altering transforms'
                    )

        # Set the correct parameters to the ConvertDepth and ConvertSegmentation transforms
        for i, transform in zip(range(len(self.data_transforms)),
                                self.data_transforms):
            if isinstance(transform, mytransforms.ConvertDepth):
                transform.set_mode(self.parameters.depth_mode)
            elif isinstance(transform, mytransforms.ConvertSegmentation):
                transform.set_mode(self.parameters.labels,
                                   self.parameters.labels_mode)
            elif isinstance(transform, mytransforms.ConvertFlow):
                transform.set_mode(self.parameters.flow_mode,
                                   flow_validation_mode)

        self.data_transforms = transforms.Compose(self.data_transforms)