geowatch.cli.coco_align module

Given the raw data in kwcoco format, this script will extract orthorectified regions around areas of interest across time.

The align script works by making two geopandas data frames of geo-boundaries, one for regions and one for all images (as defined by their geotiff metadata). I then use the util_gis.geopandas_pairwise_overlaps to efficiently find which regions intersect which images. Images that intersect a region are grouped together (the same image might belong to multiple regions). Then within each region group, the script finds all images that have the same datetime metadata and groups those together. Finally, images with the “same-exact” bands are grouped together. For each band-group I use gdal-warp to crop to the region, which creates a set of temporary files, and then finally gdalmerge is used to combine those different crops into a single image.

The main corner case in the above process is when one image has r|g|b but another image has r|g|b|yellow, there is no logic to split those channels out at the moment.

The following is an end-to-end example works on public data

CommandLine

# Create a demo region file
xdoctest geowatch.demo.demo_region demo_khq_region_fpath

DATASET_SUFFIX=DemoKHQ-2022-06-10-V2
DEMO_DPATH=$HOME/.cache/geowatch/demo/datasets

REGION_FPATH="$HOME/.cache/geowatch/demo/annotations/KHQ_R001.geojson"
SITE_GLOBSTR="$HOME/.cache/geowatch/demo/annotations/KHQ_R001_sites/*.geojson"

START_DATE=$(jq -r '.features[] | select(.properties.type=="region") | .properties.start_date' "$REGION_FPATH")
END_DATE=$(jq -r '.features[] | select(.properties.type=="region") | .properties.end_date' "$REGION_FPATH")
# Shrink time window to test with less data
START_DATE=2016-12-02
END_DATE=2020-12-31
REGION_ID=$(jq -r '.features[] | select(.properties.type=="region") | .properties.region_id' "$REGION_FPATH")
SEARCH_FPATH=$DEMO_DPATH/stac_search.json
RESULT_FPATH=$DEMO_DPATH/all_sensors_kit/${REGION_ID}.input
CATALOG_FPATH=$DEMO_DPATH/all_sensors_kit/${REGION_ID}_catalog.json
KWCOCO_FPATH=$DEMO_DPATH/all_sensors_kit/${REGION_ID}.kwcoco.zip
KWCOCO_FIELDED_FPATH=$DEMO_DPATH/all_sensors_kit/${REGION_ID}-fielded.kwcoco.zip
KWCOCO_ALIGNED_DPATH=$DEMO_DPATH/all_sensors_kit/cropped/
KWCOCO_ALIGNED_FPATH=$DEMO_DPATH/all_sensors_kit/cropped/${REGION_ID}-fielded.kwcoco.zip

mkdir -p "$DEMO_DPATH"

# Create the search json wrt the sensors and processing level we want
python -m geowatch.stac.stac_search_builder \
    --start_date="$START_DATE" \
    --end_date="$END_DATE" \
    --cloud_cover=40 \
    --sensors=sentinel-2-l2a \
    --out_fpath "$SEARCH_FPATH"
cat "$SEARCH_FPATH"

# Delete this to prevent duplicates
rm -f "$RESULT_FPATH"

# Create the .input file
# use max_products_per_region to keep the result small
python -m geowatch.cli.stac_search \
    --region_file "$REGION_FPATH" \
    --search_json "$SEARCH_FPATH" \
    --mode area \
    --verbose 2 \
    --max_products_per_region 10 \
    --outfile "${RESULT_FPATH}"

cat "$RESULT_FPATH"

python -m geowatch.cli.baseline_framework_ingress \
    --input_path="$RESULT_FPATH" \
    --catalog_fpath="${CATALOG_FPATH}" \
    --virtual=True \
    --jobs=avail \
    --aws_profile=iarpa \
    --requester_pays=0

AWS_DEFAULT_PROFILE=iarpa python -m geowatch.cli.stac_to_kwcoco \
    --input_stac_catalog="${CATALOG_FPATH}" \
    --outpath="$KWCOCO_FPATH" \
    --jobs=8 \
    --from_collated=False \
    --ignore_duplicates=0

# Check that the resulting kwcoco has what you want in it
geowatch stats "$KWCOCO_FPATH"

# Use kwcoco info to dump a single image dictionary
kwcoco info "$KWCOCO_FPATH" -g 1 -i 0

# Prefetch header metadata from remote assets
AWS_DEFAULT_PROFILE=iarpa python -m geowatch.cli.coco_add_watch_fields \
    --src="$KWCOCO_FPATH" \
    --dst="$KWCOCO_FIELDED_FPATH" \
    --overwrite=warp \
    --workers=8 \
    --enable_video_stats=False \
    --target_gsd=10 \
    --remove_broken=True \
    --skip_populate_errors=False

# Use kwcoco info to see what info fielding added
kwcoco info "$KWCOCO_FPATH" -g 1 -i 0

# Perform the crop to create an aligned dataset with videos
AWS_DEFAULT_PROFILE=iarpa python -m geowatch.cli.coco_align \
    --regions "$REGION_FPATH" \
    --context_factor=1 \
    --geo_preprop=auto \
    --keep=img \
    --force_nodata=None \
    --include_channels="None" \
    --exclude_channels="None" \
    --debug_valid_regions=False \
    --rpc_align_method orthorectify \
    --sensor_to_time_window "None" \
    --verbose=0 \
    --aux_workers=0 \
    --target_gsd=10 \
    --force_min_gsd=None \
    --workers=26 \
    --tries=2 \
    --asset_timeout=1hours \
    --image_timeout=2hours \
    --hack_lazy=False \
    --src="$KWCOCO_FIELDED_FPATH" \
    --dst="$KWCOCO_FIELDED_FPATH" \
    --dst_bundle_dpath=$KWCOCO_ALIGNED_DPATH

Note

# Example invocation to create the full drop1 aligned dataset

DVC_DPATH=$HOME/data/dvc-repos/smart_watch_dvc INPUT_COCO_FPATH=$DVC_DPATH/drop1/data.kwcoco.json OUTPUT_COCO_FPATH=$DVC_DPATH/drop1-WV-only-aligned/data.kwcoco.json REGION_FPATH=$DVC_DPATH/drop1/all_regions.geojson VIZ_DPATH=$OUTPUT_COCO_FPATH/_viz_video

# Quick stats about input datasets python -m kwcoco stats $INPUT_COCO_FPATH python -m geowatch stats $INPUT_COCO_FPATH

# Combine the region models python -m geowatch.cli.merge_region_models

–src $DVC_DPATH/drop1/region_models/*.geojson –dst $REGION_FPATH

python -m geowatch.cli.coco_add_watch_fields

–src $INPUT_COCO_FPATH –dst $INPUT_COCO_FPATH.prepped –workers 16 –target_gsd=10

# Execute alignment / crop script python -m geowatch.cli.coco_align

–src $INPUT_COCO_FPATH.prepped –dst $OUTPUT_COCO_FPATH –regions $REGION_FPATH –rpc_align_method orthorectify –workers=10 –aux_workers=2 –context_factor=1 –geo_preprop=False –include_sensors=WV –keep img

Todo

  • [ ] Should this script have the option of calling “remove_bad_images” or

    “clean_geotiffs” to prevent generating bad images in the first place?

class geowatch.cli.coco_align.AssetExtractConfig(*args, **kwargs)[source]

Bases: DataConfig

Part of the extract config for asset jobs

Valid options: []

Parameters:
  • *args – positional arguments for this data config

  • **kwargs – keyword arguments for this data config

default = {'asset_timeout': <Value('4hours')>, 'backoff': <Value(3.0)>, 'cooldown': <Value(10)>, 'corruption_checks': <Value(False)>, 'exclude_channels': <Value(None)>, 'force_min_gsd': <Value(None)>, 'force_nodata': <Value(None)>, 'hack_lazy': <Value(False)>, 'include_channels': <Value(None)>, 'keep': <Value(None)>, 'qa_encoding': <Value(None)>, 'skip_previous_errors': <Value(False)>, 'tries': <Value(2)>, 'unsigned_nodata': <Value(256)>, 'verbose': <Value(0)>}
normalize()
class geowatch.cli.coco_align.ImageExtractConfig(*args, **kwargs)[source]

Bases: AssetExtractConfig

Part of the extract config for image jobs

Valid options: []

Parameters:
  • *args – positional arguments for this data config

  • **kwargs – keyword arguments for this data config

default = {'asset_timeout': <Value('4hours')>, 'aux_workers': <Value(0)>, 'backoff': <Value(3.0)>, 'cooldown': <Value(10)>, 'corruption_checks': <Value(False)>, 'exclude_channels': <Value(None)>, 'force_min_gsd': <Value(None)>, 'force_nodata': <Value(None)>, 'hack_lazy': <Value(False)>, 'image_error_policy': <Value('raise')>, 'image_timeout': <Value('8hours')>, 'include_channels': <Value(None)>, 'keep': <Value(None)>, 'num_end_frames': <Value(None)>, 'num_start_frames': <Value(None)>, 'qa_encoding': <Value(None)>, 'rpc_align_method': <Value('orthorectify')>, 'skip_previous_errors': <Value(False)>, 'tries': <Value(2)>, 'unsigned_nodata': <Value(256)>, 'verbose': <Value(0)>}
class geowatch.cli.coco_align.ExtractConfig(*args, **kwargs)[source]

Bases: ImageExtractConfig

This is a subset of the above config for arguments a passed to extract_overlaps. We may use this config as a base class to inherit from, but for now we duplicate param names.

Valid options: []

Parameters:
  • *args – positional arguments for this data config

  • **kwargs – keyword arguments for this data config

default = {'asset_timeout': <Value('4hours')>, 'aux_workers': <Value(0)>, 'backoff': <Value(3.0)>, 'cooldown': <Value(10)>, 'corruption_checks': <Value(False)>, 'debug_valid_regions': <Value(False)>, 'exclude_channels': <Value(None)>, 'force_min_gsd': <Value(None)>, 'force_nodata': <Value(None)>, 'hack_lazy': <Value(False)>, 'image_error_policy': <Value('raise')>, 'image_timeout': <Value('8hours')>, 'img_workers': <Value(0)>, 'include_channels': <Value(None)>, 'keep': <Value(None)>, 'max_frames': <Value(None)>, 'num_end_frames': <Value(None)>, 'num_start_frames': <Value(None)>, 'qa_encoding': <Value(None)>, 'rpc_align_method': <Value('orthorectify')>, 'sensor_to_time_window': <Value(None)>, 'skip_previous_errors': <Value(False)>, 'target_gsd': <Value(10)>, 'tries': <Value(2)>, 'unsigned_nodata': <Value(256)>, 'verbose': <Value(0)>, 'write_subsets': <Value(False)>}
normalize()
class geowatch.cli.coco_align.CocoAlignGeotiffConfig(*args, **kwargs)[source]

Bases: ExtractConfig

Create a dataset of aligned temporal sequences around objects of interest in an unstructured collection of annotated geotiffs.

High Level Steps:
  • Find a set of geospatial AOIs

  • For each AOI find all images that overlap

  • Orthorectify (or warp) the selected spatial region and its annotations to a cannonical space.

Valid options: []

Parameters:
  • *args – positional arguments for this data config

  • **kwargs – keyword arguments for this data config

default = {'asset_timeout': <Value('4hours')>, 'aux_workers': <Value(0)>, 'backoff': <Value(3.0)>, 'context_factor': <Value(1.0)>, 'convexify_regions': <Value(False)>, 'cooldown': <Value(10)>, 'corruption_checks': <Value(False)>, 'debug_valid_regions': <Value(False)>, 'dst': <Value(None)>, 'dst_bundle_dpath': <Value(None)>, 'edit_geotiff_metadata': <Value(False)>, 'empty_region_policy': <Value('ignore')>, 'exclude_channels': <Value(None)>, 'exclude_sensors': <Value(None)>, 'force_min_gsd': <Value(None)>, 'force_nodata': <Value(None)>, 'geo_preprop': <Value('auto')>, 'hack_lazy': <Value(False)>, 'image_error_policy': <Value('raise')>, 'image_timeout': <Value('8hours')>, 'img_workers': <Value(0)>, 'include_channels': <Value(None)>, 'include_sensors': <Value(None)>, 'keep': <Value(None)>, 'max_frames': <Value(None)>, 'minimum_size': <Value(None)>, 'num_end_frames': <Value(None)>, 'num_start_frames': <Value(None)>, 'qa_encoding': <Value(None)>, 'regions': <Value('annots')>, 'rpc_align_method': <Value('orthorectify')>, 'sensor_to_time_window': <Value(None)>, 'site_summary': <Value(False)>, 'skip_previous_errors': <Value(False)>, 'src': <Value('in.geojson.json')>, 'target_gsd': <Value(10)>, 'tries': <Value(2)>, 'unsigned_nodata': <Value(256)>, 'verbose': <Value(0)>, 'write_subsets': <Value(False)>}
geowatch.cli.coco_align.main(cmdline=True, **kw)[source]

Main function for coco_align. See :class:``CocoAlignGeotiffConfig` for details

CommandLine

xdoctest -m geowatch.cli.coco_align main:0

Example

>>> from geowatch.cli.coco_align import *  # NOQA
>>> from geowatch.demo.landsat_demodata import grab_landsat_product
>>> from kwgis.gis.geotiff import geotiff_metadata
>>> # Create a dead simple coco dataset with one image
>>> import dateutil.parser
>>> import kwcoco
>>> import kwimage
>>> coco_dset = kwcoco.CocoDataset()
>>> ls_prod = grab_landsat_product()
>>> fpath = ls_prod['bands'][0]
>>> meta = geotiff_metadata(fpath)
>>> # We need a date captured ATM in a specific format
>>> dt = dateutil.parser.parse(
>>>     meta['filename_meta']['acquisition_date'])
>>> date_captured = dt.strftime('%Y/%m/%d')
>>> gid = coco_dset.add_image(file_name=fpath, date_captured=date_captured)
>>> dummy_poly = kwimage.Polygon.from_geojson(meta['geos_corners'])
>>> dummy_poly = dummy_poly.scale(0.03, about='center')
>>> sseg_geos = dummy_poly.to_geojson()
>>> # NOTE: script is not always robust to missing annotation
>>> # information like segmentation and bad bbox, but for this
>>> # test config it is
>>> coco_dset.add_annotation(
>>>     image_id=gid, bbox=[0, 0, 0, 0], segmentation_geos=sseg_geos)
>>> #
>>> # Create arguments to the script
>>> dpath = ub.Path.appdir('geowatch/tests/coco_align').ensuredir()
>>> dst = (dpath / 'align_bundle1').ensuredir()
>>> dst.delete()
>>> dst.ensuredir()
>>> kw = {
>>>     'src': coco_dset,
>>>     'dst': dst,
>>>     'regions': 'annots',
>>>     'workers': 2,
>>>     'aux_workers': 2,
>>>     'convexify_regions': True,
>>>     'minimum_size': '8000x8000 @ 1GSD',
>>>     #'image_timeout': '1 microsecond',
>>>     #'asset_timeout': '1 microsecond',
>>>     'hack_lazy': 0,
>>> }
>>> cmdline = False
>>> new_dset = main(cmdline, **kw)

Example

>>> # Test timeout
>>> # xdoctest: +REQUIRES(env:SLOW_DOCTESTS)
>>> from geowatch.cli.coco_align import *  # NOQA
>>> from geowatch.demo.landsat_demodata import grab_landsat_product
>>> from kwgis.gis.geotiff import geotiff_metadata
>>> # Create a dead simple coco dataset with one image
>>> import dateutil.parser
>>> import kwcoco
>>> import kwimage
>>> coco_dset = kwcoco.CocoDataset()
>>> ls_prod = grab_landsat_product()
>>> fpath = ls_prod['bands'][0]
>>> meta = geotiff_metadata(fpath)
>>> # We need a date captured ATM in a specific format
>>> dt = dateutil.parser.parse(
>>>     meta['filename_meta']['acquisition_date'])
>>> date_captured = dt.strftime('%Y/%m/%d')
>>> gid = coco_dset.add_image(file_name=fpath, date_captured=date_captured)
>>> dummy_poly = kwimage.Polygon.from_geojson(meta['geos_corners'])
>>> dummy_poly = dummy_poly.scale(0.03, about='center')
>>> sseg_geos = dummy_poly.to_geojson()
>>> from geowatch.geoannots import geomodels
>>> region = geomodels.RegionModel.random(region_poly=dummy_poly, start_time=dt.isoformat())
>>> # Create arguments to the script
>>> dpath = ub.Path.appdir('geowatch/tests/coco_align').ensuredir()
>>> dst = (dpath / 'align_bundle_timeout').ensuredir()
>>> dst.delete()
>>> dst.ensuredir()
>>> region_fpath = dpath / 'region_model.geojson'
>>> region_fpath.write_text(region.dumps())
>>> kw = {
>>>     'src': coco_dset,
>>>     'dst': dst,
>>>     'regions': region_fpath,
>>>     'workers': 2,
>>>     'aux_workers': 2,
>>>     'convexify_regions': True,
>>>     'asset_timeout': '0.00001 seconds',
>>>     'hack_lazy': 0,
>>> }
>>> cmdline = False
>>> new_dset = main(cmdline, **kw)
>>> assert len(new_dset.images()) == 0

Example

>>> # xdoctest: +REQUIRES(env:SLOW_DOCTEST)
>>> # Confirm expected behavior of `force_min_gsd` keyword argument
>>> from geowatch.cli.coco_align import *  # NOQA
>>> from geowatch.demo.landsat_demodata import grab_landsat_product
>>> from kwgis.gis.geotiff import geotiff_metadata
>>> from kwgis.gis.geotiff import geotiff_crs_info
>>> # Create a dead simple coco dataset with one image
>>> import kwcoco
>>> import kwimage
>>> import dateutil.parser
>>> coco_dset = kwcoco.CocoDataset()
>>> ls_prod = grab_landsat_product()
>>> fpath = ls_prod['bands'][0]
>>> meta = geotiff_metadata(fpath)
>>> # We need a date captured ATM in a specific format
>>> dt = dateutil.parser.parse(
>>>     meta['filename_meta']['acquisition_date'])
>>> date_captured = dt.strftime('%Y/%m/%d')
>>> gid = coco_dset.add_image(file_name=fpath, date_captured=date_captured)
>>> dummy_poly = kwimage.Polygon.from_geojson(meta['geos_corners'])
>>> dummy_poly = dummy_poly.scale(0.3, about='center')
>>> sseg_geos = dummy_poly.to_geojson()
>>> # NOTE: script is not always robust to missing annotation
>>> # information like segmentation and bad bbox, but for this
>>> # test config it is
>>> coco_dset.add_annotation(
>>>     image_id=gid, bbox=[0, 0, 0, 0], segmentation_geos=sseg_geos)
>>> #
>>> # Create arguments to the script
>>> dpath = ub.Path.appdir('geowatch/tests/coco_align').ensuredir()
>>> dst = ub.ensuredir((dpath, 'align_bundle1_force_gsd'))
>>> ub.delete(dst)
>>> dst = ub.ensuredir(dst)
>>> kw = {
>>>     'src': coco_dset,
>>>     'dst': dst,
>>>     'regions': 'annots',
>>>     'workers': 2,
>>>     'aux_workers': 2,
>>>     'convexify_regions': True,
>>>     #'image_timeout': '1 microsecond',
>>>     #'asset_timeout': '1 microsecond',
>>>     'force_min_gsd': 60.0,
>>> }
>>> cmdline = False
>>> new_dset = main(cmdline, **kw)
>>> coco_img = new_dset.coco_image(2)
>>> # Check our output is in the CRS we think it is
>>> asset = coco_img.primary_asset()
>>> parent_fpath = asset['parent_file_names']
>>> crop_fpath = ub.Path(new_dset.bundle_dpath) / asset['file_name']
>>> info = geotiff_crs_info(crop_fpath)
>>> assert(all(info['meter_per_pxl'] == 60.0))

Example

>>> # xdoctest: +REQUIRES(env:SLOW_DOCTEST)
>>> from geowatch.cli.coco_align import *  # NOQA
>>> from geowatch.demo.smart_kwcoco_demodata import demo_kwcoco_with_heatmaps
>>> from kwgis.utils import util_gdal
>>> import kwimage
>>> import geojson
>>> import json
>>> coco_dset = demo_kwcoco_with_heatmaps(num_videos=2, num_frames=2)
>>> dpath = ub.Path.appdir('geowatch/tests/coco_align2').ensuredir()
>>> dst = (dpath / 'align_bundle2').delete().ensuredir()
>>> # Create a dummy region file to crop to.
>>> first_img = coco_dset.images().take([0]).coco_images[0]
>>> first_fpath = first_img.primary_image_filepath()
>>> ds = util_gdal.GdalDataset.open(first_fpath)
>>> geo_poly = kwimage.Polygon.coerce(ds.info()['wgs84Extent'])
>>> region_shape = kwimage.Polygon.random(n=8, convex=False, rng=3)
>>> geo_transform = kwimage.Affine.fit(region_shape.bounding_box().corners(), geo_poly.bounding_box().corners())
>>> region_poly = region_shape.warp(geo_transform)
>>> region_feature = geojson.Feature(
>>>     properties={
>>>         "type": "region",
>>>         "region_id": "DUMMY_R042",
>>>         "start_date": '1970-01-01',
>>>         "end_date":  '2970-01-01',
>>>     },
>>>     geometry=region_poly.to_geojson(),
>>> )
>>> region = geojson.FeatureCollection([region_feature])
>>> region_fpath = dst / 'dummy_region.geojson'
>>> region_fpath.write_text(json.dumps(region))
>>> # Create arguments to the script
>>> kw = {
>>>     'src': coco_dset,
>>>     'dst': dst,
>>>     'regions': region_fpath,
>>>     'workers': 0,
>>>     'aux_workers': 0,
>>>     'debug_valid_regions': True,
>>>     'target_gsd': 0.7,
>>> }
>>> cmdline = False
>>> new_dset = main(cmdline, **kw)
>>> coco_img = new_dset.coco_image(2)
>>> # Check our output is in the CRS we think it is
>>> asset = coco_img.primary_asset()
>>> parent_fpath = asset['parent_file_names']
>>> crop_fpath = str(ub.Path(new_dset.bundle_dpath) / asset['file_name'])
>>> print(ub.cmd(['gdalinfo', parent_fpath])['out'])
>>> print(ub.cmd(['gdalinfo', crop_fpath])['out'])
>>> # Test that the input dataset visualizes ok
>>> from geowatch.cli import coco_visualize_videos
>>> viz_dpath = (dpath / 'viz_input_align_bundle2').ensuredir()
>>> coco_visualize_videos.main(cmdline=False, **{
>>>     'src': new_dset,
>>>     'viz_dpath': viz_dpath,
>>> })
class geowatch.cli.coco_align.SimpleDataCube(coco_dset, gids=None)[source]

Bases: object

Given a CocoDataset containing geotiffs, provide a simple API to extract a region in some coordinate space.

Intended usage is to use query_image_overlaps() to find images that overlap an ROI, then then extract_overlaps() to warp spatial subsets of that data into an aligned temporal sequence.

classmethod demo(with_region=False, extra=0)[source]
query_image_overlaps(region_df)[source]

Find the images that overlap with a each space-time region

For each region, assigns all images that overlap the space-time bounds, and constructs arguments to extract_overlaps().

Parameters:

region_df (GeoDataFrame) – data frame containing all space-time region queries.

Returns:

Information about which images belong to this ROI and their temporal sequence. Also contains strings to be used for subdirectories in the extract step.

Return type:

dict

Example

>>> from geowatch.cli.coco_align import *  # NOQA
>>> cube, region_df = SimpleDataCube.demo(with_region=True)
>>> to_extract = cube.query_image_overlaps(region_df)
extract_overlaps(image_overlaps, extract_dpath, new_dset=None, extract_config=None)[source]

Given a region of interest, extract an aligned temporal sequence of data to a specified directory.

Parameters:
  • image_overlaps (dict) – Information about images in an ROI and their temporal order computed from :func:query_image_overlaps.

  • extract_dpath (str) – where to dump the data extracted from this ROI.

  • new_dset (kwcoco.CocoDataset | None) – if specified, add extracted images and annotations to this dataset, otherwise create a new dataset.

  • extract_config (ExtractConfig) – configuration for how to perform the extract task.

Returns:

the given or new dataset that was modified

Return type:

kwcoco.CocoDataset

Example

>>> # xdoctest: +REQUIRES(env:SLOW_DOCTEST)
>>> from geowatch.cli.coco_align import *  # NOQA
>>> import kwcoco
>>> cube, region_df = SimpleDataCube.demo(with_region=True)
>>> extract_dpath = ub.Path.appdir('geowatch/tests/coco_align/demo_extract_overlaps').ensuredir()
>>> rpc_align_method = 'orthorectify'
>>> new_dset = kwcoco.CocoDataset()
>>> to_extract = cube.query_image_overlaps(region_df)
>>> image_overlaps = to_extract[0]
>>> extract_config = ExtractConfig(img_workers=32)
>>> cube.extract_overlaps(image_overlaps, extract_dpath,
>>>                       new_dset=new_dset, extract_config=extract_config)

Example

>>> # xdoctest: +REQUIRES(env:SLOW_DOCTEST)
>>> from geowatch.cli.coco_align import *  # NOQA
>>> import kwcoco
>>> cube, region_df = SimpleDataCube.demo(with_region=True, extra=True)
>>> extract_dpath = ub.Path.appdir('geowatch/tests/coco_align/demo_extract_overlaps2').ensuredir()
>>> rpc_align_method = 'orthorectify'
>>> to_extract = cube.query_image_overlaps(region_df)
>>> new_dset = kwcoco.CocoDataset()
>>> image_overlaps = to_extract[1]
>>> extract_config = ExtractConfig(img_workers=0)
>>> cube.extract_overlaps(image_overlaps, extract_dpath,
>>>                       new_dset=new_dset,
>>>                       extract_config=extract_config)
geowatch.cli.coco_align.extract_image_job(img, other_imgs, bundle_dpath, new_bundle_dpath, name, datetime_, num, frame_index, new_vidid, new_vidname, sub_bundle_dpath, space_str, space_region, space_box, start_gid, local_epsg=None, img_config=None)[source]

Threaded worker function for SimpleDataCube.extract_overlaps().

Returns:

new_img

Return type:

Dict

geowatch.cli.coco_align.serialize_kwimage_boxes(boxes)[source]

TODO: port to kwimage.Boxes.__json__

exception geowatch.cli.coco_align.SkipImage[source]

Bases: Exception