Module delta.imagery.imagery_config
Configuration options specific to imagery.
Functions
def load_images_labels(images_comp, labels_comp, classes_comp)-
Takes two configuration subsections and returns (image set, label set). Also takes classes configuration to apply preprocessing function to labels.
def register()-
Registers imagery config options with the global config manager.
cmd_args enables command line options if set to true.
Classes
class CacheConfig-
Configuration for cache.
Parameters
section_header:Optional[str]- The title of the section for command line arguments in the help.
Expand source code
class CacheConfig(DeltaConfigComponent): """ Configuration for cache. """ def __init__(self): super().__init__() self.register_field('dir', str, None, validate_path, 'Cache directory.') self.register_field('limit', int, None, validate_positive, 'Number of items to cache.') self._cache_manager = None def reset(self): super().reset() self._cache_manager = None def manager(self) -> disk_folder_cache.DiskCache: """ Returns ------- `disk_folder_cache.DiskCache`: the object to manage the cache """ if self._cache_manager is None: # Auto-populating defaults here is a workaround so small tools can skip the full # command line config setup. Could be improved! if 'dir' not in self._config_dict: self._config_dict['dir'] = 'default' if 'limit' not in self._config_dict: self._config_dict['limit'] = 8 cdir = self._config_dict['dir'] if cdir == 'default': cdir = appdirs.AppDirs('delta', 'nasa').user_cache_dir self._cache_manager = disk_folder_cache.DiskCache(cdir, self._config_dict['limit']) return self._cache_managerAncestors
Methods
def manager(self) ‑> DiskCache-
Returns
disk_folder_cache.DiskCache: the object to manage the cache
Inherited members
class ClassesConfig-
Configuration for classes.
Specify either a number of classes or list of classes with details.
Parameters
section_header:Optional[str]- The title of the section for command line arguments in the help.
Expand source code
class ClassesConfig(DeltaConfigComponent): """ Configuration for classes. Specify either a number of classes or list of classes with details. """ def __init__(self): super().__init__() self._classes = [] self._conversions = [] def __iter__(self): return self._classes.__iter__() def __getitem__(self, key): return self._classes[key] def __len__(self): return len(self._classes) # overwrite model entirely if updated (don't want combined layers from multiple files) def _load_dict(self, d : dict, base_dir): if not d: return self._config_dict = d self._classes = [] if isinstance(d, int): for i in range(d): self._classes.append(LabelClass(i)) elif isinstance(d, list): for (i, c) in enumerate(d): if isinstance(c, int): # just pixel value self._classes.append(LabelClass(i)) else: keys = c.keys() assert len(keys) == 1, 'Dict should have name of pixel value.' k = next(iter(keys)) assert isinstance(k, int), 'Class label value must be int.' inner_dict = c[k] self._classes.append(LabelClass(k, str(inner_dict.get('name')), inner_dict.get('color'), inner_dict.get('weight'))) elif isinstance(d, dict): for k in d: assert isinstance(k, int), 'Class label value must be int.' self._classes.append(LabelClass(k, str(d[k].get('name')), d[k].get('color'), d[k].get('weight'))) else: raise ValueError('Expected classes to be an int or list in config, was ' + str(d)) # make sure the order is consistent for same values, and create preprocessing function self._conversions = [] self._classes = sorted(self._classes, key=lambda x: x.value) for (i, v) in enumerate(self._classes): if v.value != i: self._conversions.append(v.value) v.end_value = i def class_id(self, class_name): """ Parameters ---------- class_name: int or str Either the original pixel value in images (int) or the name (str) of a class. The special value 'nodata' will give the nodata class, if any. Returns ------- int: the ID of the class in the labels after default image preprocessing (labels are arranged to a canonical order, with nodata always coming after them.) """ if class_name == len(self._classes) or class_name == 'nodata': return len(self._classes) for (i, c) in enumerate(self._classes): if class_name in (c.value, c.name): return i raise ValueError('Class ' + str(class_name) + ' not found.') def weights(self): """ Returns ------- List[float] List of class weights for use in training, if specified. """ weights = [] for c in self._classes: if c.weight is not None: weights.append(c.weight) if not weights: return None assert len(weights) == len(self._classes), 'For class weights, either all or none must be specified.' return weights def classes_to_indices_func(self): """ Returns ------- Callable[[numpy.ndarray], numpy.ndarray]: Function to convert label image to canonical form """ if not self._conversions: return None def convert(data): assert isinstance(data, np.ndarray) for (i, c) in enumerate(self._conversions): data[data == c] = i return data return convert def indices_to_classes_func(self): """ Returns ------- Callable[[numpy.ndarray], numpy.ndarray]: Reverse of `classes_to_indices_func`. """ if not self._conversions: return None def convert(data): assert isinstance(data, np.ndarray) for (i, c) in reversed(list(enumerate(self._conversions))): data[data == i] = c return data return convertAncestors
Methods
def class_id(self, class_name)-
Parameters
class_name:intorstr- Either the original pixel value in images (int) or the name (str) of a class. The special value 'nodata' will give the nodata class, if any.
Returns
int:- the ID of the class in the labels after default image preprocessing (labels are arranged to a canonical order, with nodata always coming after them.)
def classes_to_indices_func(self)-
Returns
Callable[[numpy.ndarray], numpy.ndarray]:- Function to convert label image to canonical form
def indices_to_classes_func(self)-
Returns
Callable[[numpy.ndarray], numpy.ndarray]:- Reverse of
classes_to_indices_func.
def weights(self)-
Returns
List[float]- List of class weights for use in training, if specified.
Inherited members
class DatasetConfig-
Configuration for a dataset.
Parameters
section_header:Optional[str]- The title of the section for command line arguments in the help.
Expand source code
class DatasetConfig(DeltaConfigComponent): """ Configuration for a dataset. """ def __init__(self): super().__init__('Dataset') self.register_component(ImageSetConfig('image'), 'images', '__image_comp') self.register_component(ImageSetConfig('label'), 'labels', '__label_comp') self.__images = None self.__labels = None self.register_component(ClassesConfig(), 'classes') def reset(self): super().reset() self.__images = None self.__labels = None def images(self) -> ImageSet: """ Returns ------- ImageSet: the training images """ if self.__images is None: (self.__images, self.__labels) = load_images_labels(self._components['images'], self._components['labels'], self._components['classes']) return self.__images def labels(self) -> ImageSet: """ Returns ------- ImageSet: the label images """ if self.__labels is None: (self.__images, self.__labels) = load_images_labels(self._components['images'], self._components['labels'], self._components['classes']) return self.__labelsAncestors
Methods
def images(self) ‑> ImageSet-
Returns
Imageset
the training images
def labels(self) ‑> ImageSet-
Returns
Imageset
the label images
Inherited members
class IOConfig-
Configuration for I/O.
Parameters
section_header:Optional[str]- The title of the section for command line arguments in the help.
Expand source code
class IOConfig(DeltaConfigComponent): """ Configuration for I/O. """ def __init__(self): super().__init__('IO') self.register_field('threads', int, None, None, 'Number of threads to use.') self.register_field('tile_size', list, 'tile_size', _validate_tile_size, 'Size of an image tile to load in memory at once.') self.register_field('interleave_blocks', int, 'interleave_blocks', None, 'Number of blocks to interleave at a time.') self.register_arg('threads', '--threads') self.register_component(CacheConfig(), 'cache') def threads(self): """ Returns ------- int: number of threads to use for I/O """ if 'threads' in self._config_dict and self._config_dict['threads']: return self._config_dict['threads'] return min(1, os.cpu_count() // 2)Ancestors
Methods
def threads(self)-
Returns
int:- number of threads to use for I/O
Inherited members
class ImagePreprocessConfig-
Configuration for image preprocessing.
Expects a list of preprocessing functions registered with
register_preprocess().Parameters
section_header:Optional[str]- The title of the section for command line arguments in the help.
Expand source code
class ImagePreprocessConfig(DeltaConfigComponent): """ Configuration for image preprocessing. Expects a list of preprocessing functions registered with `delta.config.extensions.register_preprocess`. """ def __init__(self): super().__init__() self._functions = [] def _load_dict(self, d, base_dir): if d is None: self._functions = [] return if not d: return self._functions = [] assert isinstance(d, list), 'preprocess should be list of commands' for func in d: if isinstance(func, str): self._functions.append((func, {})) else: assert isinstance(func, dict), 'preprocess items must be strings or dicts' assert len(func) == 1, 'One preprocess item per list entry.' name = list(func.keys())[0] self._functions.append((name, func[name])) def function(self, image_type): """ Parameters ---------- image_type: str Type of the image Returns ------- Callable: The specified preprocessing function to apply to the image. """ prep = lambda data, _, dummy: data for (name, args) in self._functions: t = preprocess_function(name) assert t is not None, 'Preprocess function %s not found.' % (name) p = t(image_type=image_type, **args) def helper(cur, prev): return lambda data, roi, bands: cur(prev(data, roi, bands), roi, bands) prep = helper(p, prep) return prepAncestors
Methods
def function(self, image_type)-
Parameters
image_type:str- Type of the image
Returns
Callable
The specified preprocessing function to apply to the image.
Inherited members
class ImageSet (images, image_type, preprocess=None, nodata_value=None)-
Specifies a set of image files.
The images can be accessed by using the
ImageSetas an iterable.Parameters
images:Iterator[str]- Image filenames
image_type:str- The image type as a string (i.e., tiff, worldview, landsat). Must have
been previously registered with
register_image_reader(). preprocess:Callable- Optional preprocessing function to apply to the image
following the signature in
DeltaImage.set_preprocess(). nodata_value:image dtype- A no data value for pixels to disregard
Expand source code
class ImageSet: """ Specifies a set of image files. The images can be accessed by using the `ImageSet` as an iterable. """ def __init__(self, images, image_type, preprocess=None, nodata_value=None): """ Parameters ---------- images: Iterator[str] Image filenames image_type: str The image type as a string (i.e., tiff, worldview, landsat). Must have been previously registered with `delta.config.extensions.register_image_reader`. preprocess: Callable Optional preprocessing function to apply to the image following the signature in `delta.imagery.delta_image.DeltaImage.set_preprocess`. nodata_value: image dtype A no data value for pixels to disregard """ self._images = images self._image_type = image_type self._preprocess = preprocess self._nodata_value = nodata_value def type(self): """ Returns ------- str: The type of the image """ return self._image_type def preprocess(self): """ Returns ------- Callable: The preprocessing function """ return self._preprocess def nodata_value(self): """ Returns ------- image dtype: Value of pixels to disregard. """ return self._nodata_value def set_nodata_value(self, nodata): """ Set the pixel value to disregard. Parameters ---------- nodata: image dtype The pixel value to set as nodata """ self._nodata_value = nodata def load(self, index): """ Loads the image of the given index. Parameters ---------- index: int Index of the image to load. Returns ------- `delta.imagery.delta_image.DeltaImage`: The image """ img = image_reader(self.type())(self[index], self.nodata_value()) if self._preprocess: img.set_preprocess(self._preprocess) return img def __len__(self): return len(self._images) def __getitem__(self, index): if index < 0 or index >= len(self): raise IndexError('Index %s out of range.' % (index)) return self._images[index] def __iter__(self): return self._images.__iter__()Methods
def load(self, index)-
Loads the image of the given index.
Parameters
index:int- Index of the image to load.
Returns
DeltaImage: The image def nodata_value(self)-
Returns
image dtype:- Value of pixels to disregard.
def preprocess(self)-
Returns
Callable
The preprocessing function
def set_nodata_value(self, nodata)-
Set the pixel value to disregard.
Parameters
nodata:image dtype- The pixel value to set as nodata
def type(self)-
Returns
str:- The type of the image
class ImageSetConfig (name=None)-
Configuration for a set of images.
Used for images, labels, and validation images and labels.
Parameters
section_header:Optional[str]- The title of the section for command line arguments in the help.
Expand source code
class ImageSetConfig(DeltaConfigComponent): """ Configuration for a set of images. Used for images, labels, and validation images and labels. """ def __init__(self, name=None): super().__init__() self.register_field('type', str, 'type', None, 'Image type.') self.register_field('files', list, None, _validate_paths, 'List of image files.') self.register_field('file_list', str, None, validate_path, 'File listing image files.') self.register_field('directory', str, None, validate_path, 'Directory of image files.') self.register_field('extension', str, None, None, 'Image file extension.') self.register_field('nodata_value', (float, int), None, None, 'Value of pixels to ignore.') if name: self.register_arg('type', '--' + name + '-type', name + '_type') self.register_arg('file_list', '--' + name + '-file-list', name + '_file_list') self.register_arg('directory', '--' + name + '-dir', name + '_directory') self.register_arg('extension', '--' + name + '-extension', name + '_extension') self.register_component(ImagePreprocessConfig(), 'preprocess') self._name = name def preprocess_function(self): """ Returns ------- Callable: Preprocessing function for the set of images. """ return self._components['preprocess'].function(self._config_dict['type']) def setup_arg_parser(self, parser, components = None) -> None: if self._name is None: return super().setup_arg_parser(parser, components) parser.add_argument("--" + self._name, dest=self._name, required=False, help="Specify a single image file.") def parse_args(self, options): if self._name is None: return super().parse_args(options) if hasattr(options, self._name) and getattr(options, self._name) is not None: self._config_dict['files'] = [getattr(options, self._name)] self._config_dict['directory'] = None self._config_dict['file_list'] = NoneAncestors
Methods
def preprocess_function(self)-
Returns
Callable
Preprocessing function for the set of images.
Inherited members
class LabelClass (value, name=None, color=None, weight=None)-
Label configuration.
Parameters
value:int- Pixel of the label
name:str- Name of the class to display
color:int- In visualizations, set the class to this RGB color.
weight:float- During training weight this class by this amount.
Expand source code
class LabelClass: """ Label configuration. """ def __init__(self, value, name=None, color=None, weight=None): """ Parameters ---------- value: int Pixel of the label name: str Name of the class to display color: int In visualizations, set the class to this RGB color. weight: float During training weight this class by this amount. """ color_order = [0x1f77b4, 0xff7f0e, 0x2ca02c, 0xd62728, 0x9467bd, 0x8c564b, \ 0xe377c2, 0x7f7f7f, 0xbcbd22, 0x17becf] if name is None: name = 'Class ' + str(value) if color is None: color = color_order[value] if value < len(color_order) else 0 self.value = value self.name = name self.color = color self.weight = weight self.end_value = None def __repr__(self): return 'Color: ' + self.name