geoai-py 0.8.2__tar.gz → 0.8.3__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.
Files changed (128) hide show
  1. {geoai_py-0.8.2 → geoai_py-0.8.3}/PKG-INFO +1 -1
  2. geoai_py-0.8.3/docs/examples/instance_segmentation.ipynb +487 -0
  3. {geoai_py-0.8.2 → geoai_py-0.8.3}/geoai/__init__.py +1 -1
  4. {geoai_py-0.8.2 → geoai_py-0.8.3}/geoai/geoai.py +5 -0
  5. {geoai_py-0.8.2 → geoai_py-0.8.3}/geoai/train.py +466 -24
  6. {geoai_py-0.8.2 → geoai_py-0.8.3}/geoai/utils.py +313 -59
  7. {geoai_py-0.8.2 → geoai_py-0.8.3}/geoai_py.egg-info/PKG-INFO +1 -1
  8. {geoai_py-0.8.2 → geoai_py-0.8.3}/geoai_py.egg-info/SOURCES.txt +1 -0
  9. {geoai_py-0.8.2 → geoai_py-0.8.3}/mkdocs.yml +1 -0
  10. {geoai_py-0.8.2 → geoai_py-0.8.3}/pyproject.toml +2 -2
  11. {geoai_py-0.8.2 → geoai_py-0.8.3}/.editorconfig +0 -0
  12. {geoai_py-0.8.2 → geoai_py-0.8.3}/.github/FUNDING.yml +0 -0
  13. {geoai_py-0.8.2 → geoai_py-0.8.3}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  14. {geoai_py-0.8.2 → geoai_py-0.8.3}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  15. {geoai_py-0.8.2 → geoai_py-0.8.3}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  16. {geoai_py-0.8.2 → geoai_py-0.8.3}/.github/dependabot.yml +0 -0
  17. {geoai_py-0.8.2 → geoai_py-0.8.3}/.github/workflows/docker-image.yml +0 -0
  18. {geoai_py-0.8.2 → geoai_py-0.8.3}/.github/workflows/docker-publish.yml +0 -0
  19. {geoai_py-0.8.2 → geoai_py-0.8.3}/.github/workflows/docs-build.yml +0 -0
  20. {geoai_py-0.8.2 → geoai_py-0.8.3}/.github/workflows/docs.yml +0 -0
  21. {geoai_py-0.8.2 → geoai_py-0.8.3}/.github/workflows/macos.yml +0 -0
  22. {geoai_py-0.8.2 → geoai_py-0.8.3}/.github/workflows/pypi.yml +0 -0
  23. {geoai_py-0.8.2 → geoai_py-0.8.3}/.github/workflows/ubuntu.yml +0 -0
  24. {geoai_py-0.8.2 → geoai_py-0.8.3}/.github/workflows/windows.yml +0 -0
  25. {geoai_py-0.8.2 → geoai_py-0.8.3}/.gitignore +0 -0
  26. {geoai_py-0.8.2 → geoai_py-0.8.3}/.pre-commit-config.yaml +0 -0
  27. {geoai_py-0.8.2 → geoai_py-0.8.3}/Dockerfile +0 -0
  28. {geoai_py-0.8.2 → geoai_py-0.8.3}/LICENSE +0 -0
  29. {geoai_py-0.8.2 → geoai_py-0.8.3}/MANIFEST.in +0 -0
  30. {geoai_py-0.8.2 → geoai_py-0.8.3}/README.md +0 -0
  31. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/CNAME +0 -0
  32. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/assets/logo.ico +0 -0
  33. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/assets/logo.png +0 -0
  34. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/assets/logo_rect.png +0 -0
  35. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/changelog.md +0 -0
  36. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/classify.md +0 -0
  37. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/contributing.md +0 -0
  38. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/download.md +0 -0
  39. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/_template.ipynb +0 -0
  40. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/batch_segmentation.ipynb +0 -0
  41. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/building_detection_lidar.ipynb +0 -0
  42. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/building_footprints_africa.ipynb +0 -0
  43. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/building_footprints_china.ipynb +0 -0
  44. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/building_footprints_usa.ipynb +0 -0
  45. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/building_regularization.ipynb +0 -0
  46. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/car_detection.ipynb +0 -0
  47. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/create_vector.ipynb +0 -0
  48. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/data_visualization.ipynb +0 -0
  49. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/dataviz/lidar_viz.ipynb +0 -0
  50. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/dataviz/raster_viz.ipynb +0 -0
  51. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/dataviz/vector_viz.ipynb +0 -0
  52. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/download_data.ipynb +0 -0
  53. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/download_naip.ipynb +0 -0
  54. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/download_sentinel2.ipynb +0 -0
  55. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/edit_vector.ipynb +0 -0
  56. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/geometric_properties.ipynb +0 -0
  57. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/globe_projection.ipynb +0 -0
  58. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/grounded_sam.ipynb +0 -0
  59. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/image_chips.ipynb +0 -0
  60. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/image_tiling.ipynb +0 -0
  61. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/jupytext.toml +0 -0
  62. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/load_model_checkpoint.ipynb +0 -0
  63. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/parking_spot_detection.ipynb +0 -0
  64. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/planetary_computer.ipynb +0 -0
  65. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/rastervision/semantic_segmentation.ipynb +0 -0
  66. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/regularization.ipynb +0 -0
  67. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/samgeo/arcgis.ipynb +0 -0
  68. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/samgeo/automatic_mask_generator.ipynb +0 -0
  69. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/samgeo/automatic_mask_generator_hq.ipynb +0 -0
  70. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/samgeo/box_prompts.ipynb +0 -0
  71. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/samgeo/fast_sam.ipynb +0 -0
  72. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/samgeo/input_prompts.ipynb +0 -0
  73. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/samgeo/input_prompts_hq.ipynb +0 -0
  74. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/samgeo/maxar_open_data.ipynb +0 -0
  75. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/samgeo/satellite-predictor.ipynb +0 -0
  76. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/samgeo/satellite.ipynb +0 -0
  77. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/samgeo/swimming_pools.ipynb +0 -0
  78. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/samgeo/text_prompts.ipynb +0 -0
  79. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/samgeo/text_prompts_batch.ipynb +0 -0
  80. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/samgeo.ipynb +0 -0
  81. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/ship_detection.ipynb +0 -0
  82. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/solar_panel_detection.ipynb +0 -0
  83. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/text_prompt_segmentation.ipynb +0 -0
  84. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/train_building_footprints_usa.ipynb +0 -0
  85. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/train_car_detection.ipynb +0 -0
  86. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/train_landcover_classification.ipynb +0 -0
  87. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/train_object_detection_model.ipynb +0 -0
  88. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/train_segmentation_model.ipynb +0 -0
  89. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/train_ship_detection.ipynb +0 -0
  90. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/train_solar_panel_detection.ipynb +0 -0
  91. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/train_water_detection.ipynb +0 -0
  92. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/view_metadata.ipynb +0 -0
  93. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/water_detection.ipynb +0 -0
  94. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/water_detection_s2.ipynb +0 -0
  95. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/water_dynamics.ipynb +0 -0
  96. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/waterbody-dataset-sample/README.md +0 -0
  97. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/examples/wetland_mapping.ipynb +0 -0
  98. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/extract.md +0 -0
  99. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/faq.md +0 -0
  100. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/geoai.md +0 -0
  101. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/hf.md +0 -0
  102. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/index.md +0 -0
  103. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/installation.md +0 -0
  104. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/overrides/main.html +0 -0
  105. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/sam.md +0 -0
  106. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/segment.md +0 -0
  107. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/segmentation.md +0 -0
  108. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/train.md +0 -0
  109. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/usage.md +0 -0
  110. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/utils.md +0 -0
  111. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/workshops/GeoAI_Workshop_2025.ipynb +0 -0
  112. {geoai_py-0.8.2 → geoai_py-0.8.3}/docs/workshops/jupytext.toml +0 -0
  113. {geoai_py-0.8.2 → geoai_py-0.8.3}/geoai/classify.py +0 -0
  114. {geoai_py-0.8.2 → geoai_py-0.8.3}/geoai/download.py +0 -0
  115. {geoai_py-0.8.2 → geoai_py-0.8.3}/geoai/extract.py +0 -0
  116. {geoai_py-0.8.2 → geoai_py-0.8.3}/geoai/hf.py +0 -0
  117. {geoai_py-0.8.2 → geoai_py-0.8.3}/geoai/sam.py +0 -0
  118. {geoai_py-0.8.2 → geoai_py-0.8.3}/geoai/segment.py +0 -0
  119. {geoai_py-0.8.2 → geoai_py-0.8.3}/geoai/segmentation.py +0 -0
  120. {geoai_py-0.8.2 → geoai_py-0.8.3}/geoai_py.egg-info/dependency_links.txt +0 -0
  121. {geoai_py-0.8.2 → geoai_py-0.8.3}/geoai_py.egg-info/entry_points.txt +0 -0
  122. {geoai_py-0.8.2 → geoai_py-0.8.3}/geoai_py.egg-info/requires.txt +0 -0
  123. {geoai_py-0.8.2 → geoai_py-0.8.3}/geoai_py.egg-info/top_level.txt +0 -0
  124. {geoai_py-0.8.2 → geoai_py-0.8.3}/requirements.txt +0 -0
  125. {geoai_py-0.8.2 → geoai_py-0.8.3}/requirements_docs.txt +0 -0
  126. {geoai_py-0.8.2 → geoai_py-0.8.3}/setup.cfg +0 -0
  127. {geoai_py-0.8.2 → geoai_py-0.8.3}/tests/__init__.py +0 -0
  128. {geoai_py-0.8.2 → geoai_py-0.8.3}/tests/test_geoai.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: geoai-py
3
- Version: 0.8.2
3
+ Version: 0.8.3
4
4
  Summary: A Python package for using Artificial Intelligence (AI) with geospatial data
5
5
  Author-email: Qiusheng Wu <giswqs@gmail.com>
6
6
  License: MIT License
@@ -0,0 +1,487 @@
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "metadata": {},
6
+ "source": [
7
+ "# Instance Segmentation with GeoAI\n",
8
+ "\n",
9
+ "[![image](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/opengeos/geoai/blob/main/docs/examples/instance_segmentation.ipynb)\n",
10
+ "\n",
11
+ "This notebook demonstrates how to use the new instance segmentation functionality in GeoAI for training models and running inference on geospatial data.\n",
12
+ "\n",
13
+ "## Overview\n",
14
+ "\n",
15
+ "Instance segmentation combines object detection and semantic segmentation to identify and segment individual objects in images. This is particularly useful for:\n",
16
+ "\n",
17
+ "- Building detection and segmentation\n",
18
+ "- Vehicle counting and tracking\n",
19
+ "- Infrastructure mapping\n",
20
+ "- Object delineation in satellite imagery\n",
21
+ "\n",
22
+ "## New Functions\n",
23
+ "\n",
24
+ "GeoAI now provides clear wrapper functions for instance segmentation:\n",
25
+ "\n",
26
+ "### Training\n",
27
+ "- `train_instance_segmentation_model()` - Train a Mask R-CNN model\n",
28
+ "\n",
29
+ "### Inference\n",
30
+ "- `instance_segmentation()` - Run inference on a single GeoTIFF\n",
31
+ "- `instance_segmentation_batch()` - Run inference on multiple GeoTIFFs\n",
32
+ "\n",
33
+ "### Model Creation\n",
34
+ "- `get_instance_segmentation_model()` - Create a Mask R-CNN model with custom parameters"
35
+ ]
36
+ },
37
+ {
38
+ "cell_type": "markdown",
39
+ "metadata": {},
40
+ "source": [
41
+ "## Install packages\n",
42
+ "To use the new functionality, ensure the required packages are installed."
43
+ ]
44
+ },
45
+ {
46
+ "cell_type": "code",
47
+ "execution_count": null,
48
+ "metadata": {},
49
+ "outputs": [],
50
+ "source": [
51
+ "# %pip install geoai-py"
52
+ ]
53
+ },
54
+ {
55
+ "cell_type": "markdown",
56
+ "metadata": {},
57
+ "source": [
58
+ "## Import libraries"
59
+ ]
60
+ },
61
+ {
62
+ "cell_type": "code",
63
+ "execution_count": null,
64
+ "metadata": {},
65
+ "outputs": [],
66
+ "source": [
67
+ "import geoai\n",
68
+ "import os\n",
69
+ "from pathlib import Path"
70
+ ]
71
+ },
72
+ {
73
+ "cell_type": "markdown",
74
+ "metadata": {},
75
+ "source": [
76
+ "## Setup\n",
77
+ "\n",
78
+ "First, let's check our environment and set up paths."
79
+ ]
80
+ },
81
+ {
82
+ "cell_type": "code",
83
+ "execution_count": null,
84
+ "metadata": {},
85
+ "outputs": [],
86
+ "source": [
87
+ "# Check if CUDA is available\n",
88
+ "device = geoai.get_device()\n",
89
+ "print(f\"Using device: {device}\")\n",
90
+ "\n",
91
+ "# Set up paths\n",
92
+ "out_folder = \"instance_segmentation_buildings\"\n",
93
+ "models_dir = Path(out_folder) / \"models\"\n",
94
+ "output_dir = Path(out_folder) / \"output\"\n",
95
+ "\n",
96
+ "# Create directories if they don't exist\n",
97
+ "models_dir.mkdir(parents=True, exist_ok=True)\n",
98
+ "output_dir.mkdir(parents=True, exist_ok=True)\n",
99
+ "\n",
100
+ "print(f\"Working directory: {out_folder}\")\n",
101
+ "print(f\"Models will be saved to: {models_dir}\")\n",
102
+ "print(f\"Output will be saved to: {output_dir}\")"
103
+ ]
104
+ },
105
+ {
106
+ "cell_type": "markdown",
107
+ "metadata": {},
108
+ "source": [
109
+ "## Download sample data\n",
110
+ "\n",
111
+ "We'll use the same dataset as the semantic segmentation example for consistency."
112
+ ]
113
+ },
114
+ {
115
+ "cell_type": "code",
116
+ "execution_count": null,
117
+ "metadata": {},
118
+ "outputs": [],
119
+ "source": [
120
+ "train_raster_url = (\n",
121
+ " \"https://huggingface.co/datasets/giswqs/geospatial/resolve/main/naip_rgb_train.tif\"\n",
122
+ ")\n",
123
+ "train_vector_url = \"https://huggingface.co/datasets/giswqs/geospatial/resolve/main/naip_train_buildings.geojson\"\n",
124
+ "test_raster_url = (\n",
125
+ " \"https://huggingface.co/datasets/giswqs/geospatial/resolve/main/naip_test.tif\"\n",
126
+ ")"
127
+ ]
128
+ },
129
+ {
130
+ "cell_type": "code",
131
+ "execution_count": null,
132
+ "metadata": {},
133
+ "outputs": [],
134
+ "source": [
135
+ "train_raster_path = geoai.download_file(train_raster_url)\n",
136
+ "train_vector_path = geoai.download_file(train_vector_url)\n",
137
+ "test_raster_path = geoai.download_file(test_raster_url)\n",
138
+ "\n",
139
+ "print(f\"Downloaded training raster: {train_raster_path}\")\n",
140
+ "print(f\"Downloaded training vector: {train_vector_path}\")\n",
141
+ "print(f\"Downloaded test raster: {test_raster_path}\")"
142
+ ]
143
+ },
144
+ {
145
+ "cell_type": "markdown",
146
+ "metadata": {},
147
+ "source": [
148
+ "## Visualize sample data"
149
+ ]
150
+ },
151
+ {
152
+ "cell_type": "code",
153
+ "execution_count": null,
154
+ "metadata": {},
155
+ "outputs": [],
156
+ "source": [
157
+ "geoai.get_raster_info(train_raster_path)"
158
+ ]
159
+ },
160
+ {
161
+ "cell_type": "code",
162
+ "execution_count": null,
163
+ "metadata": {},
164
+ "outputs": [],
165
+ "source": [
166
+ "geoai.view_vector_interactive(train_vector_path, tiles=train_raster_url)"
167
+ ]
168
+ },
169
+ {
170
+ "cell_type": "code",
171
+ "execution_count": null,
172
+ "metadata": {},
173
+ "outputs": [],
174
+ "source": [
175
+ "geoai.view_raster(test_raster_url)"
176
+ ]
177
+ },
178
+ {
179
+ "cell_type": "markdown",
180
+ "metadata": {},
181
+ "source": [
182
+ "## Create training data\n",
183
+ "\n",
184
+ "We'll create training tiles for instance segmentation. Note that for instance segmentation, we need to ensure each building instance has a unique pixel value in the label."
185
+ ]
186
+ },
187
+ {
188
+ "cell_type": "code",
189
+ "execution_count": null,
190
+ "metadata": {},
191
+ "outputs": [],
192
+ "source": [
193
+ "# Create training tiles\n",
194
+ "tiles = geoai.export_geotiff_tiles(\n",
195
+ " in_raster=train_raster_path,\n",
196
+ " out_folder=out_folder,\n",
197
+ " in_class_data=train_vector_path,\n",
198
+ " tile_size=512,\n",
199
+ " stride=256,\n",
200
+ " buffer_radius=0,\n",
201
+ ")\n",
202
+ "\n",
203
+ "print(f\"Created {len(tiles)} training tiles\")\n",
204
+ "print(f\"Images saved to: {out_folder}/images\")\n",
205
+ "print(f\"Labels saved to: {out_folder}/labels\")"
206
+ ]
207
+ },
208
+ {
209
+ "cell_type": "markdown",
210
+ "metadata": {},
211
+ "source": [
212
+ "## 1. Model Creation\n",
213
+ "\n",
214
+ "Let's create an instance segmentation model with custom parameters."
215
+ ]
216
+ },
217
+ {
218
+ "cell_type": "code",
219
+ "execution_count": null,
220
+ "metadata": {},
221
+ "outputs": [],
222
+ "source": [
223
+ "# Create a model for binary segmentation (background + buildings)\n",
224
+ "model = geoai.get_instance_segmentation_model(\n",
225
+ " num_classes=2, # background + buildings\n",
226
+ " num_channels=3, # RGB channels\n",
227
+ " pretrained=True,\n",
228
+ ")\n",
229
+ "\n",
230
+ "print(f\"Model created with {sum(p.numel() for p in model.parameters())} parameters\")\n",
231
+ "print(f\"Model device: {next(model.parameters()).device}\")\n",
232
+ "print(f\"Model type: {type(model)}\")"
233
+ ]
234
+ },
235
+ {
236
+ "cell_type": "markdown",
237
+ "metadata": {},
238
+ "source": [
239
+ "## 2. Training Instance Segmentation Model\n",
240
+ "\n",
241
+ "Now let's train the instance segmentation model using our prepared data."
242
+ ]
243
+ },
244
+ {
245
+ "cell_type": "code",
246
+ "execution_count": null,
247
+ "metadata": {},
248
+ "outputs": [],
249
+ "source": [
250
+ "# Training configuration\n",
251
+ "training_config = {\n",
252
+ " \"images_dir\": f\"{out_folder}/images\",\n",
253
+ " \"labels_dir\": f\"{out_folder}/labels\",\n",
254
+ " \"output_dir\": str(models_dir),\n",
255
+ " \"num_classes\": 2, # background + buildings\n",
256
+ " \"num_channels\": 3, # RGB\n",
257
+ " \"batch_size\": 2, # Small batch size for demo\n",
258
+ " \"num_epochs\": 20, # Few epochs for demo\n",
259
+ " \"learning_rate\": 0.005,\n",
260
+ " \"val_split\": 0.2,\n",
261
+ " \"visualize\": True,\n",
262
+ " \"device\": device,\n",
263
+ " \"verbose\": True,\n",
264
+ "}\n",
265
+ "\n",
266
+ "print(\"Training configuration:\")\n",
267
+ "for key, value in training_config.items():\n",
268
+ " print(f\" {key}: {value}\")"
269
+ ]
270
+ },
271
+ {
272
+ "cell_type": "code",
273
+ "execution_count": null,
274
+ "metadata": {},
275
+ "outputs": [],
276
+ "source": [
277
+ "# Train the model\n",
278
+ "print(\"Starting training...\")\n",
279
+ "geoai.train_instance_segmentation_model(**training_config)\n",
280
+ "print(\"Training completed!\")"
281
+ ]
282
+ },
283
+ {
284
+ "cell_type": "code",
285
+ "execution_count": null,
286
+ "metadata": {},
287
+ "outputs": [],
288
+ "source": [
289
+ "geoai.plot_performance_metrics(\n",
290
+ " history_path=str(models_dir / \"training_history.pth\"),\n",
291
+ " figsize=(15, 5),\n",
292
+ " verbose=True,\n",
293
+ ")"
294
+ ]
295
+ },
296
+ {
297
+ "cell_type": "markdown",
298
+ "metadata": {},
299
+ "source": [
300
+ "## 3. Running Inference\n",
301
+ "\n",
302
+ "Once we have a trained model, we can run inference on new images."
303
+ ]
304
+ },
305
+ {
306
+ "cell_type": "code",
307
+ "execution_count": null,
308
+ "metadata": {},
309
+ "outputs": [],
310
+ "source": [
311
+ "# Define paths\n",
312
+ "model_path = str(models_dir / \"best_model.pth\")\n",
313
+ "output_path = str(output_dir / \"instance_segmentation_result.tif\")\n",
314
+ "\n",
315
+ "# Check if model exists\n",
316
+ "if os.path.exists(model_path):\n",
317
+ " print(f\"Model found at: {model_path}\")\n",
318
+ "else:\n",
319
+ " print(f\"Model not found at: {model_path}\")\n",
320
+ " print(\"Please ensure training completed successfully\")"
321
+ ]
322
+ },
323
+ {
324
+ "cell_type": "code",
325
+ "execution_count": null,
326
+ "metadata": {},
327
+ "outputs": [],
328
+ "source": [
329
+ "# Single image inference with improved parameters\n",
330
+ "inference_config = {\n",
331
+ " \"input_path\": test_raster_path,\n",
332
+ " \"output_path\": output_path,\n",
333
+ " \"model_path\": model_path,\n",
334
+ " \"window_size\": 512,\n",
335
+ " \"overlap\": 128, # Reduced overlap to minimize artifacts\n",
336
+ " \"confidence_threshold\": 0.5,\n",
337
+ " \"batch_size\": 2,\n",
338
+ " \"num_channels\": 3,\n",
339
+ " \"num_classes\": 2,\n",
340
+ " \"device\": device,\n",
341
+ "}\n",
342
+ "\n",
343
+ "print(\"Running inference with sliding window processing...\")\n",
344
+ "result_path, inference_time = geoai.instance_segmentation(**inference_config)\n",
345
+ "print(f\"Inference completed in {inference_time:.2f} seconds!\")"
346
+ ]
347
+ },
348
+ {
349
+ "cell_type": "code",
350
+ "execution_count": null,
351
+ "metadata": {},
352
+ "outputs": [],
353
+ "source": [
354
+ "geoai.view_raster(\n",
355
+ " output_path, nodata=0, colormap=\"tab20\", opacity=0.7, basemap=test_raster_url\n",
356
+ ")"
357
+ ]
358
+ },
359
+ {
360
+ "cell_type": "markdown",
361
+ "metadata": {},
362
+ "source": [
363
+ "![](https://github.com/user-attachments/assets/e2555842-3060-4f5a-8481-09e77f05761a)"
364
+ ]
365
+ },
366
+ {
367
+ "cell_type": "markdown",
368
+ "metadata": {},
369
+ "source": [
370
+ "## 4. Vectorize and Visualize Results\n",
371
+ "\n",
372
+ "Convert the predicted mask to vector format for better visualization and analysis."
373
+ ]
374
+ },
375
+ {
376
+ "cell_type": "code",
377
+ "execution_count": null,
378
+ "metadata": {},
379
+ "outputs": [],
380
+ "source": [
381
+ "output_vector_path = \"building_predictions.geojson\"\n",
382
+ "gdf = geoai.orthogonalize(output_path, output_vector_path, epsilon=2)"
383
+ ]
384
+ },
385
+ {
386
+ "cell_type": "code",
387
+ "execution_count": null,
388
+ "metadata": {},
389
+ "outputs": [],
390
+ "source": [
391
+ "# Add geometric properties\n",
392
+ "gdf_props = geoai.add_geometric_properties(gdf, area_unit=\"m2\", length_unit=\"m\")"
393
+ ]
394
+ },
395
+ {
396
+ "cell_type": "code",
397
+ "execution_count": null,
398
+ "metadata": {},
399
+ "outputs": [],
400
+ "source": [
401
+ "# Interactive visualization with area information\n",
402
+ "geoai.view_vector_interactive(gdf_props, column=\"area_m2\", tiles=test_raster_url)"
403
+ ]
404
+ },
405
+ {
406
+ "cell_type": "code",
407
+ "execution_count": null,
408
+ "metadata": {},
409
+ "outputs": [],
410
+ "source": [
411
+ "# Filter out small buildings and visualize\n",
412
+ "gdf_filtered = gdf_props[(gdf_props[\"area_m2\"] > 50)]\n",
413
+ "print(f\"Buildings after filtering (area > 50 m²): {len(gdf_filtered)}\")\n",
414
+ "\n",
415
+ "geoai.view_vector_interactive(gdf_filtered, column=\"area_m2\", tiles=test_raster_url)"
416
+ ]
417
+ },
418
+ {
419
+ "cell_type": "code",
420
+ "execution_count": null,
421
+ "metadata": {},
422
+ "outputs": [],
423
+ "source": [
424
+ "# Create a split map comparison\n",
425
+ "geoai.create_split_map(\n",
426
+ " left_layer=gdf_filtered,\n",
427
+ " right_layer=test_raster_url,\n",
428
+ " left_args={\"style\": {\"color\": \"red\", \"fillOpacity\": 0.3}},\n",
429
+ " basemap=test_raster_url,\n",
430
+ ")"
431
+ ]
432
+ },
433
+ {
434
+ "cell_type": "markdown",
435
+ "metadata": {},
436
+ "source": [
437
+ "## 8. Key Parameters Guide\n",
438
+ "\n",
439
+ "Here are the key parameters you can adjust:"
440
+ ]
441
+ },
442
+ {
443
+ "cell_type": "markdown",
444
+ "metadata": {},
445
+ "source": [
446
+ "## Summary\n",
447
+ "\n",
448
+ "This notebook demonstrated the new instance segmentation functionality in GeoAI:\n",
449
+ "\n",
450
+ "1. **Model Creation**: Created Mask R-CNN models with custom parameters\n",
451
+ "2. **Training**: Trained an instance segmentation model on building data\n",
452
+ "3. **Inference**: Ran inference on test images\n",
453
+ "4. **Visualization**: Converted results to vectors and visualized them\n",
454
+ "5. **Analysis**: Compared with semantic segmentation approaches\n",
455
+ "\n",
456
+ "The new functions provide a cleaner API while maintaining backward compatibility with existing code. They're built on top of the robust MaskRCNN implementation already present in GeoAI.\n",
457
+ "\n",
458
+ "### Available Functions:\n",
459
+ "- `geoai.train_instance_segmentation_model()` - Train Mask R-CNN models\n",
460
+ "- `geoai.instance_segmentation()` - Single image inference\n",
461
+ "- `geoai.instance_segmentation_batch()` - Batch processing\n",
462
+ "- `geoai.get_instance_segmentation_model()` - Create custom models"
463
+ ]
464
+ }
465
+ ],
466
+ "metadata": {
467
+ "kernelspec": {
468
+ "display_name": "geo",
469
+ "language": "python",
470
+ "name": "python3"
471
+ },
472
+ "language_info": {
473
+ "codemirror_mode": {
474
+ "name": "ipython",
475
+ "version": 3
476
+ },
477
+ "file_extension": ".py",
478
+ "mimetype": "text/x-python",
479
+ "name": "python",
480
+ "nbconvert_exporter": "python",
481
+ "pygments_lexer": "ipython3",
482
+ "version": "3.12.2"
483
+ }
484
+ },
485
+ "nbformat": 4,
486
+ "nbformat_minor": 4
487
+ }
@@ -2,7 +2,7 @@
2
2
 
3
3
  __author__ = """Qiusheng Wu"""
4
4
  __email__ = "giswqs@gmail.com"
5
- __version__ = "0.8.2"
5
+ __version__ = "0.8.3"
6
6
 
7
7
 
8
8
  import os
@@ -32,6 +32,11 @@ from .train import (
32
32
  train_segmentation_model,
33
33
  semantic_segmentation,
34
34
  semantic_segmentation_batch,
35
+ train_instance_segmentation_model,
36
+ instance_segmentation,
37
+ instance_segmentation_batch,
38
+ get_instance_segmentation_model,
39
+ instance_segmentation_inference_on_geotiff,
35
40
  )
36
41
  from .utils import *
37
42