delayed_image.delayed_leafs module¶
Terminal nodes
- class delayed_image.delayed_leafs.DelayedImageLeaf(subdata=None, dsize=None, channels=None)[source]¶
Bases:
DelayedImage- Parameters:
subdata (DelayedArray)
dsize (None | Tuple[int | None, int | None]) – overrides subdata dsize
channels (None | int | FusedChannelSpec) – overrides subdata channels
- class delayed_image.delayed_leafs.DelayedLoad(fpath, channels=None, dsize=None, nodata_method=None)[source]¶
Bases:
DelayedImageLeafPoints to an image on disk to be loaded.
This is the starting point for most delayed operations. Disk IO is avoided until the
finalizeoperation is called. Callingpreparecan read image headers if metadata like the image width, height, and number of channels is not provided, but most operations can be performed while these are still unknown.If a gdal backend is available, and the underlying image is in the appropriate formate (e.g. COG), finalize will return a lazy reference that enables fast overviews and crops. For image formats that do not allow for tiling / overviews, then there is no way to avoid reading entire image as an ndarray.
Example
>>> from delayed_image import * # NOQA >>> self = DelayedLoad.demo(dsize=(16, 16)).prepare() >>> data1 = self.finalize()
Example
>>> # xdoctest: +REQUIRES(module:osgeo) >>> # Demo code to develop support for overviews >>> from delayed_image import * # NOQA >>> import kwimage >>> import ubelt as ub >>> fpath = kwimage.grab_test_image_fpath(overviews=3) >>> self = DelayedLoad(fpath, channels='r|g|b').prepare() >>> print(f'self={self}') >>> print('self.meta = {}'.format(ub.repr2(self.meta, nl=1))) >>> quantization = { >>> 'quant_max': 255, >>> 'nodata': 0, >>> } >>> node0 = self >>> node1 = node0.get_overview(2) >>> node2 = node1[13:900, 11:700] >>> node3 = node2.dequantize(quantization) >>> node4 = node3.warp({'scale': 0.05}) >>> # >>> data0 = node0._validate().finalize() >>> data1 = node1._validate().finalize() >>> data2 = node2._validate().finalize() >>> data3 = node3._validate().finalize() >>> data4 = node4._validate().finalize() >>> node4.write_network_text()
Example
>>> # xdoctest: +REQUIRES(module:osgeo) >>> # Test delayed ops with int16 and nodata values >>> from delayed_image import * # NOQA >>> import kwimage >>> from delayed_image.helpers import quantize_float01 >>> import ubelt as ub >>> dpath = ub.Path.appdir('delayed_image/tests/test_delay_nodata').ensuredir() >>> fpath = dpath / 'data.tif' >>> data = kwimage.ensure_float01(kwimage.grab_test_image()) >>> poly = kwimage.Polygon.random(rng=321032).scale(data.shape[0]) >>> poly.fill(data, np.nan) >>> data_uint16, quantization = quantize_float01(data) >>> nodata = quantization['nodata'] >>> kwimage.imwrite(fpath, data_uint16, nodata=nodata, backend='gdal', overviews=3) >>> # Test loading the data >>> self = DelayedLoad(fpath, channels='r|g|b', nodata_method='float').prepare() >>> node0 = self >>> node1 = node0.dequantize(quantization) >>> node2 = node1.warp({'scale': 0.51}, interpolation='lanczos') >>> node3 = node2[13:900, 11:700] >>> node4 = node3.warp({'scale': 0.9}, interpolation='lanczos') >>> node4.write_network_text() >>> node5 = node4.optimize() >>> node5.write_network_text() >>> node6 = node5.warp({'scale': 8}, interpolation='lanczos').optimize() >>> node6.write_network_text() >>> # >>> data0 = node0._validate().finalize() >>> data1 = node1._validate().finalize() >>> data2 = node2._validate().finalize() >>> data3 = node3._validate().finalize() >>> data4 = node4._validate().finalize() >>> data5 = node5._validate().finalize() >>> data6 = node6._validate().finalize() >>> # xdoctest: +REQUIRES(--show) >>> import kwplot >>> kwplot.autompl() >>> stack1 = kwimage.stack_images([data1, data2, data3, data4, data5]) >>> stack2 = kwimage.stack_images([stack1, data6], axis=1) >>> kwplot.imshow(stack2)
- Parameters:
fpath (str | PathLike) – URI pointing at the image data to load
channels (int | str | FusedChannelSpec | None) – the underlying channels of the image if known a-priori
dsize (Tuple[int, int]) – The width / height of the image if known a-priori
nodata_method (str | None) – How to handle nodata values in the file itself. Can be “auto”, “float”, or “ma”.
- property fpath¶
- classmethod demo(key='astro', channels=None, dsize=None, nodata_method=None, overviews=None)[source]¶
Creates a demo DelayedLoad node that points to a file generated by
kwimage.grab_test_image_fpath().If metadata like dsize and channels are not provided, then the
prepare()can be used to auto-populate them at the cost of the disk IO to read image headers.- Parameters:
key (str) – which test image to grab. Valid choices are: astro - an astronaught carl - Carl Sagan paraview - ParaView logo stars - picture of stars in the sky
channels (str) – if specified, these channels will be stored in the delayed load metadata. Note: these are not auto-populated. Usually the key corresponds to 3-channel data,
dsize (None | Tuple[int, int]) – if specified, we will return a variant of the data with the specific dsize
nodata_method (str | None) – How to handle nodata values in the file itself. Can be “auto”, “float”, or “ma”.
overviews (None | int) – if specified, will return a variant of the data with overviews
- Returns:
DelayedLoad
Example
>>> from delayed_image.delayed_leafs import * # NOQA >>> import delayed_image >>> delayed = delayed_image.DelayedLoad.demo() >>> print(f'delayed={delayed}') >>> delayed.prepare() >>> print(f'delayed={delayed}') >>> delayed = DelayedLoad.demo(channels='r|g|b', nodata_method='float') >>> print(f'delayed={delayed}') >>> delayed.prepare() >>> print(f'delayed={delayed}') >>> delayed.finalize()
- class delayed_image.delayed_leafs.DelayedNans(dsize=None, channels=None)[source]¶
Bases:
DelayedImageLeafConstructs nan channels as needed
Example
self = DelayedNans((10, 10), channel_spec.FusedChannelSpec.coerce(‘rgb’)) region_slices = (slice(5, 10), slice(1, 12)) delayed = self.crop(region_slices)
Example
>>> from delayed_image.delayed_leafs import * # NOQA >>> from delayed_image import DelayedChannelConcat >>> dsize = (307, 311) >>> c1 = DelayedNans(dsize=dsize, channels='foo') >>> c2 = DelayedLoad.demo('astro', dsize=dsize, channels='R|G|B').prepare() >>> cat = DelayedChannelConcat([c1, c2]) >>> warped_cat = cat.warp({'scale': 1.07}, dsize=(328, 332))._validate() >>> warped_cat._validate().optimize().finalize()
- class delayed_image.delayed_leafs.DelayedNodata(dsize=None, channels=None, nodata_method='float')[source]¶
Bases:
DelayedNansConstructs nan or masked array depending on what is needed
Example
>>> from delayed_image.delayed_leafs import * # NOQA >>> dsize = (307, 311) >>> self1 = DelayedNodata(dsize=dsize, channels='foo', nodata_method='float') >>> self2 = DelayedNodata(dsize=dsize, channels='foo', nodata_method='ma') >>> im1 = self1.finalize() >>> im2 = self2.finalize() >>> assert im1.dtype.kind == 'f' >>> assert not hasattr(im1, 'mask') >>> assert hasattr(im2, 'mask')
- class delayed_image.delayed_leafs.DelayedIdentity(data, channels=None, dsize=None)[source]¶
Bases:
DelayedImageLeafReturns an ndarray as-is
Example
self = DelayedNans((10, 10), channel_spec.FusedChannelSpec.coerce(‘rgb’)) region_slices = (slice(5, 10), slice(1, 12)) delayed = self.crop(region_slices)
Example
>>> from delayed_image import * # NOQA >>> arr = kwimage.checkerboard() >>> self = DelayedIdentity(arr, channels='gray') >>> warp = self.warp({'scale': 1.07}) >>> warp.optimize().finalize()