geoai-py 0.18.1__tar.gz → 0.18.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {geoai_py-0.18.1 → geoai_py-0.18.2}/.gitignore +2 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/.pre-commit-config.yaml +1 -1
- {geoai_py-0.18.1 → geoai_py-0.18.2}/PKG-INFO +1 -1
- {geoai_py-0.18.1 → geoai_py-0.18.2}/geoai/__init__.py +1 -1
- {geoai_py-0.18.1 → geoai_py-0.18.2}/geoai/train.py +22 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/geoai/utils.py +243 -41
- {geoai_py-0.18.1 → geoai_py-0.18.2}/geoai_py.egg-info/PKG-INFO +1 -1
- {geoai_py-0.18.1 → geoai_py-0.18.2}/mkdocs.yml +2 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/pyproject.toml +2 -2
- {geoai_py-0.18.1 → geoai_py-0.18.2}/.dockerignore +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/.editorconfig +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/CITATION.cff +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/Dockerfile +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/LICENSE +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/MANIFEST.in +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/README.md +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/geoai/agents/__init__.py +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/geoai/agents/catalog_models.py +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/geoai/agents/catalog_tools.py +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/geoai/agents/geo_agents.py +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/geoai/agents/map_tools.py +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/geoai/agents/stac_models.py +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/geoai/agents/stac_tools.py +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/geoai/change_detection.py +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/geoai/classify.py +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/geoai/detectron2.py +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/geoai/dinov3.py +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/geoai/download.py +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/geoai/extract.py +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/geoai/geoai.py +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/geoai/hf.py +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/geoai/map_widgets.py +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/geoai/sam.py +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/geoai/segment.py +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/geoai/segmentation.py +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/geoai/timm_segment.py +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/geoai/timm_train.py +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/geoai/tools/__init__.py +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/geoai/tools/cloudmask.py +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/geoai/tools/multiclean.py +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/geoai_py.egg-info/SOURCES.txt +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/geoai_py.egg-info/dependency_links.txt +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/geoai_py.egg-info/entry_points.txt +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/geoai_py.egg-info/requires.txt +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/geoai_py.egg-info/top_level.txt +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/pytest.ini +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/requirements.txt +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/requirements_docs.txt +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/setup.cfg +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/tests/__init__.py +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/tests/create_test_data.py +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/tests/test_classify.py +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/tests/test_download.py +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/tests/test_extract.py +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/tests/test_fixtures.py +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/tests/test_geoai.py +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/tests/test_segment.py +0 -0
- {geoai_py-0.18.1 → geoai_py-0.18.2}/tests/test_utils.py +0 -0
|
@@ -2015,17 +2015,39 @@ def get_semantic_transform(train: bool) -> Any:
|
|
|
2015
2015
|
"""
|
|
2016
2016
|
Get transforms for semantic segmentation data augmentation.
|
|
2017
2017
|
|
|
2018
|
+
This function returns default data augmentation transforms for training
|
|
2019
|
+
semantic segmentation models. The transforms include geometric transformations
|
|
2020
|
+
(horizontal/vertical flips, rotations) and photometric adjustments (brightness,
|
|
2021
|
+
contrast) that are commonly used in remote sensing tasks.
|
|
2022
|
+
|
|
2018
2023
|
Args:
|
|
2019
2024
|
train (bool): Whether to include training-specific transforms.
|
|
2025
|
+
If True, applies augmentations (flips, rotations, brightness/contrast adjustments).
|
|
2026
|
+
If False, only converts to tensor (for validation).
|
|
2020
2027
|
|
|
2021
2028
|
Returns:
|
|
2022
2029
|
SemanticTransforms: Composed transforms.
|
|
2030
|
+
|
|
2031
|
+
Example:
|
|
2032
|
+
>>> train_transform = get_semantic_transform(train=True)
|
|
2033
|
+
>>> val_transform = get_semantic_transform(train=False)
|
|
2023
2034
|
"""
|
|
2024
2035
|
transforms = []
|
|
2025
2036
|
transforms.append(SemanticToTensor())
|
|
2026
2037
|
|
|
2027
2038
|
if train:
|
|
2039
|
+
# Geometric transforms - preserve spatial structure
|
|
2028
2040
|
transforms.append(SemanticRandomHorizontalFlip(0.5))
|
|
2041
|
+
transforms.append(SemanticRandomVerticalFlip(0.5))
|
|
2042
|
+
transforms.append(SemanticRandomRotation90(0.5))
|
|
2043
|
+
|
|
2044
|
+
# Photometric transforms - improve model robustness
|
|
2045
|
+
transforms.append(
|
|
2046
|
+
SemanticBrightnessAdjustment(brightness_range=(0.8, 1.2), prob=0.5)
|
|
2047
|
+
)
|
|
2048
|
+
transforms.append(
|
|
2049
|
+
SemanticContrastAdjustment(contrast_range=(0.8, 1.2), prob=0.5)
|
|
2050
|
+
)
|
|
2029
2051
|
|
|
2030
2052
|
return SemanticTransforms(transforms)
|
|
2031
2053
|
|
|
@@ -3004,6 +3004,82 @@ def batch_vector_to_raster(
|
|
|
3004
3004
|
return output_files
|
|
3005
3005
|
|
|
3006
3006
|
|
|
3007
|
+
def get_default_augmentation_transforms(
|
|
3008
|
+
tile_size: int = 256,
|
|
3009
|
+
include_normalize: bool = False,
|
|
3010
|
+
mean: Tuple[float, float, float] = (0.485, 0.456, 0.406),
|
|
3011
|
+
std: Tuple[float, float, float] = (0.229, 0.224, 0.225),
|
|
3012
|
+
) -> Any:
|
|
3013
|
+
"""
|
|
3014
|
+
Get default data augmentation transforms for geospatial imagery using albumentations.
|
|
3015
|
+
|
|
3016
|
+
This function returns a composition of augmentation transforms commonly used
|
|
3017
|
+
for remote sensing and geospatial data. The transforms include geometric
|
|
3018
|
+
transformations (flips, rotations) and photometric adjustments (brightness,
|
|
3019
|
+
contrast, saturation).
|
|
3020
|
+
|
|
3021
|
+
Args:
|
|
3022
|
+
tile_size (int): Target size for tiles. Defaults to 256.
|
|
3023
|
+
include_normalize (bool): Whether to include normalization transform.
|
|
3024
|
+
Defaults to False. Set to True if using for training with pretrained models.
|
|
3025
|
+
mean (tuple): Mean values for normalization (RGB). Defaults to ImageNet values.
|
|
3026
|
+
std (tuple): Standard deviation for normalization (RGB). Defaults to ImageNet values.
|
|
3027
|
+
|
|
3028
|
+
Returns:
|
|
3029
|
+
albumentations.Compose: A composition of augmentation transforms.
|
|
3030
|
+
|
|
3031
|
+
Example:
|
|
3032
|
+
>>> import albumentations as A
|
|
3033
|
+
>>> # Get default transforms
|
|
3034
|
+
>>> transform = get_default_augmentation_transforms()
|
|
3035
|
+
>>> # Apply to image and mask
|
|
3036
|
+
>>> augmented = transform(image=image, mask=mask)
|
|
3037
|
+
>>> aug_image = augmented['image']
|
|
3038
|
+
>>> aug_mask = augmented['mask']
|
|
3039
|
+
"""
|
|
3040
|
+
try:
|
|
3041
|
+
import albumentations as A
|
|
3042
|
+
except ImportError:
|
|
3043
|
+
raise ImportError(
|
|
3044
|
+
"albumentations is required for data augmentation. "
|
|
3045
|
+
"Install it with: pip install albumentations"
|
|
3046
|
+
)
|
|
3047
|
+
|
|
3048
|
+
transforms_list = [
|
|
3049
|
+
# Geometric transforms
|
|
3050
|
+
A.HorizontalFlip(p=0.5),
|
|
3051
|
+
A.VerticalFlip(p=0.5),
|
|
3052
|
+
A.RandomRotate90(p=0.5),
|
|
3053
|
+
A.ShiftScaleRotate(
|
|
3054
|
+
shift_limit=0.1,
|
|
3055
|
+
scale_limit=0.1,
|
|
3056
|
+
rotate_limit=45,
|
|
3057
|
+
border_mode=0,
|
|
3058
|
+
p=0.5,
|
|
3059
|
+
),
|
|
3060
|
+
# Photometric transforms
|
|
3061
|
+
A.RandomBrightnessContrast(
|
|
3062
|
+
brightness_limit=0.2,
|
|
3063
|
+
contrast_limit=0.2,
|
|
3064
|
+
p=0.5,
|
|
3065
|
+
),
|
|
3066
|
+
A.HueSaturationValue(
|
|
3067
|
+
hue_shift_limit=10,
|
|
3068
|
+
sat_shift_limit=20,
|
|
3069
|
+
val_shift_limit=10,
|
|
3070
|
+
p=0.3,
|
|
3071
|
+
),
|
|
3072
|
+
A.GaussNoise(var_limit=(10.0, 50.0), p=0.2),
|
|
3073
|
+
A.GaussianBlur(blur_limit=(3, 5), p=0.2),
|
|
3074
|
+
]
|
|
3075
|
+
|
|
3076
|
+
# Add normalization if requested
|
|
3077
|
+
if include_normalize:
|
|
3078
|
+
transforms_list.append(A.Normalize(mean=mean, std=std))
|
|
3079
|
+
|
|
3080
|
+
return A.Compose(transforms_list)
|
|
3081
|
+
|
|
3082
|
+
|
|
3007
3083
|
def export_geotiff_tiles(
|
|
3008
3084
|
in_raster,
|
|
3009
3085
|
out_folder,
|
|
@@ -3018,6 +3094,9 @@ def export_geotiff_tiles(
|
|
|
3018
3094
|
create_overview=False,
|
|
3019
3095
|
skip_empty_tiles=False,
|
|
3020
3096
|
metadata_format="PASCAL_VOC",
|
|
3097
|
+
apply_augmentation=False,
|
|
3098
|
+
augmentation_count=3,
|
|
3099
|
+
augmentation_transforms=None,
|
|
3021
3100
|
):
|
|
3022
3101
|
"""
|
|
3023
3102
|
Export georeferenced GeoTIFF tiles and labels from raster and classification data.
|
|
@@ -3037,12 +3116,54 @@ def export_geotiff_tiles(
|
|
|
3037
3116
|
create_overview (bool): Whether to create an overview image of all tiles
|
|
3038
3117
|
skip_empty_tiles (bool): If True, skip tiles with no features
|
|
3039
3118
|
metadata_format (str): Output metadata format (PASCAL_VOC, COCO, YOLO). Default: PASCAL_VOC
|
|
3119
|
+
apply_augmentation (bool): If True, generate augmented versions of each tile.
|
|
3120
|
+
This will create multiple variants of each tile using data augmentation techniques.
|
|
3121
|
+
Defaults to False.
|
|
3122
|
+
augmentation_count (int): Number of augmented versions to generate per tile
|
|
3123
|
+
(only used if apply_augmentation=True). Defaults to 3.
|
|
3124
|
+
augmentation_transforms (albumentations.Compose, optional): Custom augmentation transforms.
|
|
3125
|
+
If None and apply_augmentation=True, uses default transforms from
|
|
3126
|
+
get_default_augmentation_transforms(). Should be an albumentations.Compose object.
|
|
3127
|
+
Defaults to None.
|
|
3128
|
+
|
|
3129
|
+
Returns:
|
|
3130
|
+
None: Tiles and labels are saved to out_folder.
|
|
3131
|
+
|
|
3132
|
+
Example:
|
|
3133
|
+
>>> # Export tiles without augmentation
|
|
3134
|
+
>>> export_geotiff_tiles('image.tif', 'output/', 'labels.tif')
|
|
3135
|
+
>>>
|
|
3136
|
+
>>> # Export tiles with default augmentation (3 augmented versions per tile)
|
|
3137
|
+
>>> export_geotiff_tiles('image.tif', 'output/', 'labels.tif',
|
|
3138
|
+
... apply_augmentation=True)
|
|
3139
|
+
>>>
|
|
3140
|
+
>>> # Export with custom augmentation
|
|
3141
|
+
>>> import albumentations as A
|
|
3142
|
+
>>> custom_transform = A.Compose([
|
|
3143
|
+
... A.HorizontalFlip(p=0.5),
|
|
3144
|
+
... A.RandomBrightnessContrast(p=0.5),
|
|
3145
|
+
... ])
|
|
3146
|
+
>>> export_geotiff_tiles('image.tif', 'output/', 'labels.tif',
|
|
3147
|
+
... apply_augmentation=True,
|
|
3148
|
+
... augmentation_count=5,
|
|
3149
|
+
... augmentation_transforms=custom_transform)
|
|
3040
3150
|
"""
|
|
3041
3151
|
|
|
3042
3152
|
import logging
|
|
3043
3153
|
|
|
3044
3154
|
logging.getLogger("rasterio").setLevel(logging.ERROR)
|
|
3045
3155
|
|
|
3156
|
+
# Initialize augmentation transforms if needed
|
|
3157
|
+
if apply_augmentation:
|
|
3158
|
+
if augmentation_transforms is None:
|
|
3159
|
+
augmentation_transforms = get_default_augmentation_transforms(
|
|
3160
|
+
tile_size=tile_size
|
|
3161
|
+
)
|
|
3162
|
+
if not quiet:
|
|
3163
|
+
print(
|
|
3164
|
+
f"Data augmentation enabled: generating {augmentation_count} augmented versions per tile"
|
|
3165
|
+
)
|
|
3166
|
+
|
|
3046
3167
|
# Create output directories
|
|
3047
3168
|
os.makedirs(out_folder, exist_ok=True)
|
|
3048
3169
|
image_dir = os.path.join(out_folder, "images")
|
|
@@ -3374,53 +3495,134 @@ def export_geotiff_tiles(
|
|
|
3374
3495
|
# Read image data
|
|
3375
3496
|
image_data = src.read(window=window)
|
|
3376
3497
|
|
|
3377
|
-
#
|
|
3378
|
-
|
|
3498
|
+
# Helper function to save a single tile (original or augmented)
|
|
3499
|
+
def save_tile(
|
|
3500
|
+
img_data,
|
|
3501
|
+
lbl_mask,
|
|
3502
|
+
tile_id,
|
|
3503
|
+
img_profile,
|
|
3504
|
+
window_trans,
|
|
3505
|
+
is_augmented=False,
|
|
3506
|
+
):
|
|
3507
|
+
"""Save a single image and label tile."""
|
|
3508
|
+
# Export image as GeoTIFF
|
|
3509
|
+
image_path = os.path.join(image_dir, f"tile_{tile_id:06d}.tif")
|
|
3379
3510
|
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
3511
|
+
# Update profile
|
|
3512
|
+
img_profile_copy = img_profile.copy()
|
|
3513
|
+
img_profile_copy.update(
|
|
3514
|
+
{
|
|
3515
|
+
"height": tile_size,
|
|
3516
|
+
"width": tile_size,
|
|
3517
|
+
"count": img_data.shape[0],
|
|
3518
|
+
"transform": window_trans,
|
|
3519
|
+
}
|
|
3520
|
+
)
|
|
3521
|
+
|
|
3522
|
+
# Save image as GeoTIFF
|
|
3523
|
+
try:
|
|
3524
|
+
with rasterio.open(image_path, "w", **img_profile_copy) as dst:
|
|
3525
|
+
dst.write(img_data)
|
|
3526
|
+
stats["total_tiles"] += 1
|
|
3527
|
+
except Exception as e:
|
|
3528
|
+
pbar.write(f"ERROR saving image GeoTIFF: {e}")
|
|
3529
|
+
stats["errors"] += 1
|
|
3530
|
+
return
|
|
3531
|
+
|
|
3532
|
+
# Export label as GeoTIFF (only if class data provided)
|
|
3533
|
+
if in_class_data is not None:
|
|
3534
|
+
# Create profile for label GeoTIFF
|
|
3535
|
+
label_profile = {
|
|
3536
|
+
"driver": "GTiff",
|
|
3537
|
+
"height": tile_size,
|
|
3538
|
+
"width": tile_size,
|
|
3539
|
+
"count": 1,
|
|
3540
|
+
"dtype": "uint8",
|
|
3541
|
+
"crs": src.crs,
|
|
3542
|
+
"transform": window_trans,
|
|
3543
|
+
}
|
|
3544
|
+
|
|
3545
|
+
label_path = os.path.join(label_dir, f"tile_{tile_id:06d}.tif")
|
|
3546
|
+
try:
|
|
3547
|
+
with rasterio.open(label_path, "w", **label_profile) as dst:
|
|
3548
|
+
dst.write(lbl_mask.astype(np.uint8), 1)
|
|
3549
|
+
|
|
3550
|
+
if not is_augmented and np.any(lbl_mask > 0):
|
|
3551
|
+
stats["tiles_with_features"] += 1
|
|
3552
|
+
stats["feature_pixels"] += np.count_nonzero(lbl_mask)
|
|
3553
|
+
except Exception as e:
|
|
3554
|
+
pbar.write(f"ERROR saving label GeoTIFF: {e}")
|
|
3555
|
+
stats["errors"] += 1
|
|
3556
|
+
|
|
3557
|
+
# Save original tile
|
|
3558
|
+
save_tile(
|
|
3559
|
+
image_data,
|
|
3560
|
+
label_mask,
|
|
3561
|
+
tile_index,
|
|
3562
|
+
src.profile,
|
|
3563
|
+
window_transform,
|
|
3564
|
+
is_augmented=False,
|
|
3389
3565
|
)
|
|
3390
3566
|
|
|
3391
|
-
#
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3567
|
+
# Generate and save augmented tiles if enabled
|
|
3568
|
+
if apply_augmentation:
|
|
3569
|
+
for aug_idx in range(augmentation_count):
|
|
3570
|
+
# Prepare image for augmentation (convert from CHW to HWC)
|
|
3571
|
+
img_for_aug = np.transpose(image_data, (1, 2, 0))
|
|
3572
|
+
|
|
3573
|
+
# Ensure uint8 data type for albumentations
|
|
3574
|
+
# Albumentations expects uint8 for most transforms
|
|
3575
|
+
if not np.issubdtype(img_for_aug.dtype, np.uint8):
|
|
3576
|
+
# If image is float, scale to 0-255 and convert to uint8
|
|
3577
|
+
if np.issubdtype(img_for_aug.dtype, np.floating):
|
|
3578
|
+
img_for_aug = (
|
|
3579
|
+
(img_for_aug * 255).clip(0, 255).astype(np.uint8)
|
|
3580
|
+
)
|
|
3581
|
+
else:
|
|
3582
|
+
img_for_aug = img_for_aug.astype(np.uint8)
|
|
3399
3583
|
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
|
|
3584
|
+
# Apply augmentation
|
|
3585
|
+
try:
|
|
3586
|
+
if in_class_data is not None:
|
|
3587
|
+
# Augment both image and mask
|
|
3588
|
+
augmented = augmentation_transforms(
|
|
3589
|
+
image=img_for_aug, mask=label_mask
|
|
3590
|
+
)
|
|
3591
|
+
aug_image = augmented["image"]
|
|
3592
|
+
aug_mask = augmented["mask"]
|
|
3593
|
+
else:
|
|
3594
|
+
# Augment only image
|
|
3595
|
+
augmented = augmentation_transforms(image=img_for_aug)
|
|
3596
|
+
aug_image = augmented["image"]
|
|
3597
|
+
aug_mask = label_mask
|
|
3412
3598
|
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
with rasterio.open(label_path, "w", **label_profile) as dst:
|
|
3416
|
-
dst.write(label_mask.astype(np.uint8), 1)
|
|
3599
|
+
# Convert back from HWC to CHW
|
|
3600
|
+
aug_image = np.transpose(aug_image, (2, 0, 1))
|
|
3417
3601
|
|
|
3418
|
-
|
|
3419
|
-
|
|
3420
|
-
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
|
|
3602
|
+
# Ensure correct dtype for saving
|
|
3603
|
+
aug_image = aug_image.astype(image_data.dtype)
|
|
3604
|
+
|
|
3605
|
+
# Generate unique tile ID for augmented version
|
|
3606
|
+
# Use a collision-free numbering scheme: (tile_index * (augmentation_count + 1)) + aug_idx + 1
|
|
3607
|
+
aug_tile_id = (
|
|
3608
|
+
(tile_index * (augmentation_count + 1)) + aug_idx + 1
|
|
3609
|
+
)
|
|
3610
|
+
|
|
3611
|
+
# Save augmented tile
|
|
3612
|
+
save_tile(
|
|
3613
|
+
aug_image,
|
|
3614
|
+
aug_mask,
|
|
3615
|
+
aug_tile_id,
|
|
3616
|
+
src.profile,
|
|
3617
|
+
window_transform,
|
|
3618
|
+
is_augmented=True,
|
|
3619
|
+
)
|
|
3620
|
+
|
|
3621
|
+
except Exception as e:
|
|
3622
|
+
pbar.write(
|
|
3623
|
+
f"ERROR applying augmentation {aug_idx} to tile {tile_index}: {e}"
|
|
3624
|
+
)
|
|
3625
|
+
stats["errors"] += 1
|
|
3424
3626
|
|
|
3425
3627
|
# Create annotations for object detection if using vector class data
|
|
3426
3628
|
if (
|
|
@@ -60,6 +60,7 @@ plugins:
|
|
|
60
60
|
"examples/*_detection.ipynb",
|
|
61
61
|
"examples/building_footprints_*.ipynb",
|
|
62
62
|
"examples/data_visualization.ipynb",
|
|
63
|
+
"examples/data_augmentation.ipynb",
|
|
63
64
|
"examples/train_*.ipynb",
|
|
64
65
|
"examples/water_dynamics.ipynb",
|
|
65
66
|
"examples/wetland_mapping.ipynb",
|
|
@@ -110,6 +111,7 @@ nav:
|
|
|
110
111
|
- examples/image_tiling.ipynb
|
|
111
112
|
- examples/create_training_data.ipynb
|
|
112
113
|
- examples/export_training_data_formats.ipynb
|
|
114
|
+
- examples/data_augmentation.ipynb
|
|
113
115
|
- examples/building_footprints_usa.ipynb
|
|
114
116
|
- examples/building_footprints_africa.ipynb
|
|
115
117
|
- examples/building_footprints_china.ipynb
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "geoai-py"
|
|
3
|
-
version = "0.18.
|
|
3
|
+
version = "0.18.2"
|
|
4
4
|
dynamic = [
|
|
5
5
|
"dependencies",
|
|
6
6
|
]
|
|
@@ -44,7 +44,7 @@ universal = true
|
|
|
44
44
|
|
|
45
45
|
|
|
46
46
|
[tool.bumpversion]
|
|
47
|
-
current_version = "0.18.
|
|
47
|
+
current_version = "0.18.2"
|
|
48
48
|
commit = true
|
|
49
49
|
tag = true
|
|
50
50
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|