This is a short demo that shows how to use BatchGenerator
to process a dataset offline, i.e. to perform some transformations on all images (and maybe ground truth images, too) of some dataset(s) and then save the results to some target directory. In doing so, the generator reproduces the same directory hierarchy of the source directory in the target directory.
If ground truth data is given, it is being processed consistently with the respective images, of course.
The example used here is the Cityscapes dataset: https://www.cityscapes-dataset.com/
In [1]:
from batch_generator import BatchGenerator
from cityscapesscripts.helpers.labels import IDS_TO_TRAINIDS_ARRAY
In [2]:
# The directories that contain the train, val, and test images
train_images = '../../datasets/Cityscapes/leftImg8bit/train/'
train_extra_images = '../../datasets/Cityscapes/leftImg8bit/train_extra/'
val_images = '../../datasets/Cityscapes/leftImg8bit/val/'
test_images = '../../datasets/Cityscapes/leftImg8bit/test/'
# The directories that contain the train and val ground truth images
train_gt = '../../datasets/Cityscapes/gtFine/train/'
train_extra_gt = '../../datasets/Cityscapes/gtCoarse/train_extra/'
val_gt = '../../datasets/Cityscapes/gtFine/val/'
# Define which of the above to pass to the `BatchGenerator` constructor.
image_dirs = [train_images, val_images]
ground_truth_dirs = [train_gt, val_gt]
export_dir = '../../datasets/Cityscapes_small/' # The directory into which you want to export the processed images
root_dir = '../../datasets/Cityscapes/' # The root directory of the dataset.
In [3]:
offline_processor = BatchGenerator(image_dirs=image_dirs,
image_file_extension='png',
ground_truth_dirs=ground_truth_dirs,
image_name_split_separator='leftImg8bit',
ground_truth_suffix='gtFine_labelIds',
check_existence=True,
root_dir=root_dir,
export_dir=export_dir)
num_files = offline_processor.get_num_files()
print("Total number of files in all datasets: ", num_files)
Simply call process_all()
on the BatchGenerator
instance with the desired parameters.
In this example I want to do two things with the data:
The segmentation class IDs in the Cityscapes ground truth images range from 0 to 33 and contain a whole bunch of irrelevant classes that are being ignored in the evaluation. I am only interested in learning the 19 classes that count for evaluation. I will therefore remap the IDs of the relevant classes to IDs 1 through 20 and I will map all irrelevant classes to one collective background class ID, namely 0. I simply pass the generator an integer array that represents the map. I could also pass a map in the form of a dictionary instead, but that would slow down the processing. Once I'm done training my model, I can revert this mapping back to the original class IDs the same way.
The images in the Cityscapes datasets have a size of (1024, 2048)
. I wish I could just train on these full-size images, but that's too large for my GPU. I will therefore downsize the images by a factor of 16 to (256, 512)
.
Take a look at the documentation for more details on the above transformations and to learn about the other transformations available in BatchGenerator
.
In [4]:
offline_processor.process_all(convert_colors_to_ids=False,
convert_ids_to_ids=IDS_TO_TRAINIDS_ARRAY, # <-- Convert the class IDs to different ones.
convert_to_one_hot=False,
void_class_id=None,
random_crop=False,
crop=False,
resize=(256, 512), # <-- Resize the images.
brightness=False,
flip=False,
translate=False,
scale=False,
gray=False,
to_disk=True) # <-- Save the processed images to disk.
In [ ]: