geoai-py 0.8.2__tar.gz → 0.9.0__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.8.2 → geoai_py-0.9.0}/.github/workflows/docs-build.yml +9 -6
- {geoai_py-0.8.2 → geoai_py-0.9.0}/.github/workflows/docs.yml +9 -6
- {geoai_py-0.8.2 → geoai_py-0.9.0}/.github/workflows/ubuntu.yml +9 -6
- {geoai_py-0.8.2 → geoai_py-0.9.0}/PKG-INFO +3 -1
- geoai_py-0.9.0/docs/change_detection.md +3 -0
- geoai_py-0.9.0/docs/examples/change_detection.ipynb +422 -0
- geoai_py-0.9.0/docs/examples/instance_segmentation.ipynb +487 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/geoai/__init__.py +1 -1
- geoai_py-0.9.0/geoai/change_detection.py +1561 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/geoai/geoai.py +6 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/geoai/train.py +539 -30
- {geoai_py-0.8.2 → geoai_py-0.9.0}/geoai/utils.py +313 -59
- {geoai_py-0.8.2 → geoai_py-0.9.0}/geoai_py.egg-info/PKG-INFO +3 -1
- {geoai_py-0.8.2 → geoai_py-0.9.0}/geoai_py.egg-info/SOURCES.txt +4 -1
- {geoai_py-0.8.2 → geoai_py-0.9.0}/geoai_py.egg-info/requires.txt +2 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/mkdocs.yml +3 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/pyproject.toml +2 -2
- {geoai_py-0.8.2 → geoai_py-0.9.0}/requirements.txt +2 -0
- geoai_py-0.8.2/docs/examples/waterbody-dataset-sample/README.md +0 -1
- {geoai_py-0.8.2 → geoai_py-0.9.0}/.editorconfig +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/.github/FUNDING.yml +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/.github/dependabot.yml +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/.github/workflows/docker-image.yml +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/.github/workflows/docker-publish.yml +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/.github/workflows/macos.yml +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/.github/workflows/pypi.yml +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/.github/workflows/windows.yml +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/.gitignore +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/.pre-commit-config.yaml +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/Dockerfile +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/LICENSE +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/MANIFEST.in +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/README.md +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/CNAME +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/assets/logo.ico +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/assets/logo.png +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/assets/logo_rect.png +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/changelog.md +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/classify.md +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/contributing.md +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/download.md +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/_template.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/batch_segmentation.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/building_detection_lidar.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/building_footprints_africa.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/building_footprints_china.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/building_footprints_usa.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/building_regularization.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/car_detection.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/create_vector.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/data_visualization.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/dataviz/lidar_viz.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/dataviz/raster_viz.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/dataviz/vector_viz.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/download_data.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/download_naip.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/download_sentinel2.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/edit_vector.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/geometric_properties.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/globe_projection.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/grounded_sam.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/image_chips.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/image_tiling.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/jupytext.toml +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/load_model_checkpoint.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/parking_spot_detection.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/planetary_computer.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/rastervision/semantic_segmentation.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/regularization.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/samgeo/arcgis.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/samgeo/automatic_mask_generator.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/samgeo/automatic_mask_generator_hq.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/samgeo/box_prompts.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/samgeo/fast_sam.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/samgeo/input_prompts.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/samgeo/input_prompts_hq.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/samgeo/maxar_open_data.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/samgeo/satellite-predictor.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/samgeo/satellite.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/samgeo/swimming_pools.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/samgeo/text_prompts.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/samgeo/text_prompts_batch.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/samgeo.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/ship_detection.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/solar_panel_detection.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/text_prompt_segmentation.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/train_building_footprints_usa.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/train_car_detection.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/train_landcover_classification.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/train_object_detection_model.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/train_segmentation_model.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/train_ship_detection.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/train_solar_panel_detection.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/train_water_detection.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/view_metadata.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/water_detection.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/water_detection_s2.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/water_dynamics.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/examples/wetland_mapping.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/extract.md +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/faq.md +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/geoai.md +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/hf.md +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/index.md +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/installation.md +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/overrides/main.html +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/sam.md +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/segment.md +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/segmentation.md +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/train.md +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/usage.md +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/utils.md +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/workshops/GeoAI_Workshop_2025.ipynb +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/docs/workshops/jupytext.toml +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/geoai/classify.py +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/geoai/download.py +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/geoai/extract.py +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/geoai/hf.py +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/geoai/sam.py +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/geoai/segment.py +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/geoai/segmentation.py +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/geoai_py.egg-info/dependency_links.txt +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/geoai_py.egg-info/entry_points.txt +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/geoai_py.egg-info/top_level.txt +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/requirements_docs.txt +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/setup.cfg +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/tests/__init__.py +0 -0
- {geoai_py-0.8.2 → geoai_py-0.9.0}/tests/test_geoai.py +0 -0
@@ -16,6 +16,9 @@ jobs:
|
|
16
16
|
with:
|
17
17
|
fetch-depth: 0
|
18
18
|
|
19
|
+
# - name: Install GDAL system dependencies
|
20
|
+
# run: sudo apt-get update && sudo apt-get install -y gdal-bin libgdal-dev
|
21
|
+
|
19
22
|
- name: Install uv
|
20
23
|
uses: astral-sh/setup-uv@v6
|
21
24
|
with:
|
@@ -33,15 +36,15 @@ jobs:
|
|
33
36
|
|
34
37
|
- name: Install optional dependencies
|
35
38
|
run: |
|
36
|
-
uv pip install --find-links https://girder.github.io/large_image_wheels GDAL pyproj
|
39
|
+
# uv pip install --find-links https://girder.github.io/large_image_wheels GDAL pyproj
|
37
40
|
uv pip install pytest
|
38
41
|
uv pip install "geoai-py[extra]"
|
39
42
|
|
40
|
-
- name: Test import
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
43
|
+
# - name: Test import
|
44
|
+
# run: |
|
45
|
+
# uv run python -c "import geoai; print('geoai import successful')"
|
46
|
+
# uv run python -c "from osgeo import gdal; print('gdal import successful')"
|
47
|
+
# uv run gdalinfo --version
|
45
48
|
|
46
49
|
- name: Running pytest
|
47
50
|
run: |
|
@@ -15,6 +15,9 @@ jobs:
|
|
15
15
|
with:
|
16
16
|
fetch-depth: 0
|
17
17
|
|
18
|
+
# - name: Install GDAL system dependencies
|
19
|
+
# run: sudo apt-get update && sudo apt-get install -y gdal-bin libgdal-dev
|
20
|
+
|
18
21
|
- name: Install uv
|
19
22
|
uses: astral-sh/setup-uv@v6
|
20
23
|
with:
|
@@ -32,15 +35,15 @@ jobs:
|
|
32
35
|
|
33
36
|
- name: Install optional dependencies
|
34
37
|
run: |
|
35
|
-
uv pip install --find-links https://girder.github.io/large_image_wheels GDAL pyproj
|
38
|
+
# uv pip install --find-links https://girder.github.io/large_image_wheels GDAL pyproj
|
36
39
|
uv pip install pytest
|
37
40
|
uv pip install "geoai-py[extra]"
|
38
41
|
|
39
|
-
- name: Test import
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
42
|
+
# - name: Test import
|
43
|
+
# run: |
|
44
|
+
# uv run python -c "import geoai; print('geoai import successful')"
|
45
|
+
# uv run python -c "from osgeo import gdal; print('gdal import successful')"
|
46
|
+
# uv run gdalinfo --version
|
44
47
|
|
45
48
|
- name: Running pytest
|
46
49
|
run: |
|
@@ -19,6 +19,9 @@ jobs:
|
|
19
19
|
steps:
|
20
20
|
- uses: actions/checkout@v4
|
21
21
|
|
22
|
+
# - name: Install GDAL system dependencies
|
23
|
+
# run: sudo apt-get update && sudo apt-get install -y gdal-bin libgdal-dev
|
24
|
+
|
22
25
|
- name: Install uv
|
23
26
|
uses: astral-sh/setup-uv@v6
|
24
27
|
with:
|
@@ -35,15 +38,15 @@ jobs:
|
|
35
38
|
|
36
39
|
- name: Install optional dependencies
|
37
40
|
run: |
|
38
|
-
|
41
|
+
# uv pip install --find-links https://girder.github.io/large_image_wheels gdal pyproj
|
39
42
|
uv pip install pytest
|
40
43
|
uv pip install "geoai-py[extra]"
|
41
44
|
|
42
|
-
- name: Test import
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
45
|
+
# - name: Test import
|
46
|
+
# run: |
|
47
|
+
# uv run python -c "import geoai; print('geoai import successful')"
|
48
|
+
# uv run python -c "from osgeo import gdal; print('gdal import successful')"
|
49
|
+
# uv run gdalinfo --version
|
47
50
|
|
48
51
|
- name: Running pytest
|
49
52
|
run: |
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: geoai-py
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.9.0
|
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
|
@@ -19,6 +19,7 @@ License-File: LICENSE
|
|
19
19
|
Requires-Dist: albumentations
|
20
20
|
Requires-Dist: buildingregulariser
|
21
21
|
Requires-Dist: contextily
|
22
|
+
Requires-Dist: ever-beta
|
22
23
|
Requires-Dist: geopandas
|
23
24
|
Requires-Dist: huggingface_hub
|
24
25
|
Requires-Dist: jupyter-server-proxy
|
@@ -35,6 +36,7 @@ Requires-Dist: rioxarray
|
|
35
36
|
Requires-Dist: scikit-image
|
36
37
|
Requires-Dist: scikit-learn
|
37
38
|
Requires-Dist: torch
|
39
|
+
Requires-Dist: torchange
|
38
40
|
Requires-Dist: torchgeo
|
39
41
|
Requires-Dist: torchinfo
|
40
42
|
Requires-Dist: tqdm
|
@@ -0,0 +1,422 @@
|
|
1
|
+
{
|
2
|
+
"cells": [
|
3
|
+
{
|
4
|
+
"cell_type": "markdown",
|
5
|
+
"metadata": {},
|
6
|
+
"source": [
|
7
|
+
"# Change Detection with Instance Segmentation\n",
|
8
|
+
"\n",
|
9
|
+
"[](https://colab.research.google.com/github/opengeos/geoai/blob/main/docs/examples/change_detection.ipynb)\n",
|
10
|
+
"\n",
|
11
|
+
"This notebook demonstrates the change detection functionality in GeoAI, which provides instance segmentation and confidence scoring for individual change objects. \n",
|
12
|
+
"\n",
|
13
|
+
"The change detection functionality builds upon the [torchange](https://github.com/Z-Zheng/pytorch-change-models) package developed by Dr. Zhuo Zheng. We have made it much easier to analyze remote sensing imagery and visualize the results.\n",
|
14
|
+
"\n",
|
15
|
+
"## Overview\n",
|
16
|
+
"\n",
|
17
|
+
"The change detection system provides:\n",
|
18
|
+
"\n",
|
19
|
+
"- **Instance Segmentation**: Each change object gets a unique ID\n",
|
20
|
+
"- **Confidence Scores**: Individual confidence values for each detected instance\n",
|
21
|
+
"- **Proper GeoTIFF Output**: Maintains spatial reference information\n",
|
22
|
+
"\n",
|
23
|
+
"## Key Features\n",
|
24
|
+
"\n",
|
25
|
+
"- Instance-level change detection with unique IDs\n",
|
26
|
+
"- Confidence scoring for quality assessment\n",
|
27
|
+
"- Support for large GeoTIFF files\n",
|
28
|
+
"- Comprehensive analysis capabilities"
|
29
|
+
]
|
30
|
+
},
|
31
|
+
{
|
32
|
+
"cell_type": "markdown",
|
33
|
+
"metadata": {},
|
34
|
+
"source": [
|
35
|
+
"## Install packages"
|
36
|
+
]
|
37
|
+
},
|
38
|
+
{
|
39
|
+
"cell_type": "code",
|
40
|
+
"execution_count": null,
|
41
|
+
"metadata": {},
|
42
|
+
"outputs": [],
|
43
|
+
"source": [
|
44
|
+
"# %pip install geoai-py"
|
45
|
+
]
|
46
|
+
},
|
47
|
+
{
|
48
|
+
"cell_type": "markdown",
|
49
|
+
"metadata": {},
|
50
|
+
"source": [
|
51
|
+
"## Import libraries"
|
52
|
+
]
|
53
|
+
},
|
54
|
+
{
|
55
|
+
"cell_type": "code",
|
56
|
+
"execution_count": null,
|
57
|
+
"metadata": {},
|
58
|
+
"outputs": [],
|
59
|
+
"source": [
|
60
|
+
"import geoai\n",
|
61
|
+
"import os\n",
|
62
|
+
"import numpy as np\n",
|
63
|
+
"import matplotlib.pyplot as plt\n",
|
64
|
+
"from pathlib import Path"
|
65
|
+
]
|
66
|
+
},
|
67
|
+
{
|
68
|
+
"cell_type": "markdown",
|
69
|
+
"metadata": {},
|
70
|
+
"source": [
|
71
|
+
"## Setup"
|
72
|
+
]
|
73
|
+
},
|
74
|
+
{
|
75
|
+
"cell_type": "code",
|
76
|
+
"execution_count": null,
|
77
|
+
"metadata": {},
|
78
|
+
"outputs": [],
|
79
|
+
"source": [
|
80
|
+
"# Check if CUDA is available\n",
|
81
|
+
"device = geoai.get_device()\n",
|
82
|
+
"print(f\"Using device: {device}\")\n",
|
83
|
+
"\n",
|
84
|
+
"# Set up paths\n",
|
85
|
+
"out_folder = \"change_detection_results\"\n",
|
86
|
+
"Path(out_folder).mkdir(exist_ok=True)\n",
|
87
|
+
"\n",
|
88
|
+
"print(f\"Working directory: {out_folder}\")"
|
89
|
+
]
|
90
|
+
},
|
91
|
+
{
|
92
|
+
"cell_type": "markdown",
|
93
|
+
"metadata": {},
|
94
|
+
"source": [
|
95
|
+
"## Download sample data\n",
|
96
|
+
"\n",
|
97
|
+
"We'll use NAIP imagery for Las Vegas to demonstrate change detection."
|
98
|
+
]
|
99
|
+
},
|
100
|
+
{
|
101
|
+
"cell_type": "code",
|
102
|
+
"execution_count": null,
|
103
|
+
"metadata": {},
|
104
|
+
"outputs": [],
|
105
|
+
"source": [
|
106
|
+
"# Download NAIP imagery\n",
|
107
|
+
"naip_2019_url = \"https://huggingface.co/datasets/giswqs/geospatial/resolve/main/las_vegas_naip_2019_a.tif\"\n",
|
108
|
+
"naip_2022_url = \"https://huggingface.co/datasets/giswqs/geospatial/resolve/main/las_vegas_naip_2022_a.tif\"\n",
|
109
|
+
"\n",
|
110
|
+
"naip_2019_path = geoai.download_file(naip_2019_url)\n",
|
111
|
+
"naip_2022_path = geoai.download_file(naip_2022_url)\n",
|
112
|
+
"\n",
|
113
|
+
"print(f\"Downloaded 2019 NAIP: {naip_2019_path}\")\n",
|
114
|
+
"print(f\"Downloaded 2022 NAIP: {naip_2022_path}\")"
|
115
|
+
]
|
116
|
+
},
|
117
|
+
{
|
118
|
+
"cell_type": "markdown",
|
119
|
+
"metadata": {},
|
120
|
+
"source": [
|
121
|
+
"## Visualize sample data"
|
122
|
+
]
|
123
|
+
},
|
124
|
+
{
|
125
|
+
"cell_type": "code",
|
126
|
+
"execution_count": null,
|
127
|
+
"metadata": {},
|
128
|
+
"outputs": [],
|
129
|
+
"source": [
|
130
|
+
"# Check raster information\n",
|
131
|
+
"geoai.get_raster_info(naip_2019_path)"
|
132
|
+
]
|
133
|
+
},
|
134
|
+
{
|
135
|
+
"cell_type": "code",
|
136
|
+
"execution_count": null,
|
137
|
+
"metadata": {},
|
138
|
+
"outputs": [],
|
139
|
+
"source": [
|
140
|
+
"# View the images\n",
|
141
|
+
"geoai.view_raster(naip_2019_path)"
|
142
|
+
]
|
143
|
+
},
|
144
|
+
{
|
145
|
+
"cell_type": "code",
|
146
|
+
"execution_count": null,
|
147
|
+
"metadata": {},
|
148
|
+
"outputs": [],
|
149
|
+
"source": [
|
150
|
+
"geoai.view_raster(naip_2022_path)"
|
151
|
+
]
|
152
|
+
},
|
153
|
+
{
|
154
|
+
"cell_type": "markdown",
|
155
|
+
"metadata": {},
|
156
|
+
"source": [
|
157
|
+
"## Initialize Change Detection\n",
|
158
|
+
"\n",
|
159
|
+
"Create the change detection system with optimal parameters."
|
160
|
+
]
|
161
|
+
},
|
162
|
+
{
|
163
|
+
"cell_type": "code",
|
164
|
+
"execution_count": null,
|
165
|
+
"metadata": {},
|
166
|
+
"outputs": [],
|
167
|
+
"source": [
|
168
|
+
"# Initialize change detection\n",
|
169
|
+
"detector = geoai.ChangeDetection(sam_model_type=\"vit_h\")\n",
|
170
|
+
"\n",
|
171
|
+
"# Configure parameters (following the torchange example)\n",
|
172
|
+
"detector.set_hyperparameters(\n",
|
173
|
+
" change_confidence_threshold=145,\n",
|
174
|
+
" use_normalized_feature=True,\n",
|
175
|
+
" bitemporal_match=True,\n",
|
176
|
+
")\n",
|
177
|
+
"\n",
|
178
|
+
"detector.set_mask_generator_params(\n",
|
179
|
+
" points_per_side=32,\n",
|
180
|
+
" stability_score_thresh=0.95,\n",
|
181
|
+
")\n",
|
182
|
+
"\n",
|
183
|
+
"print(\"Change detection system initialized!\")"
|
184
|
+
]
|
185
|
+
},
|
186
|
+
{
|
187
|
+
"cell_type": "markdown",
|
188
|
+
"metadata": {},
|
189
|
+
"source": [
|
190
|
+
"## Run Change Detection\n",
|
191
|
+
"\n",
|
192
|
+
"Execute change detection with instance segmentation and confidence scoring."
|
193
|
+
]
|
194
|
+
},
|
195
|
+
{
|
196
|
+
"cell_type": "code",
|
197
|
+
"execution_count": null,
|
198
|
+
"metadata": {},
|
199
|
+
"outputs": [],
|
200
|
+
"source": [
|
201
|
+
"# Run change detection\n",
|
202
|
+
"results = detector.detect_changes(\n",
|
203
|
+
" naip_2019_path,\n",
|
204
|
+
" naip_2022_path,\n",
|
205
|
+
" output_path=f\"{out_folder}/binary_mask.tif\",\n",
|
206
|
+
" export_probability=True,\n",
|
207
|
+
" probability_output_path=f\"{out_folder}/probability_mask.tif\",\n",
|
208
|
+
" export_instance_masks=True,\n",
|
209
|
+
" instance_masks_output_path=f\"{out_folder}/instance_masks.tif\",\n",
|
210
|
+
" return_detailed_results=True,\n",
|
211
|
+
" return_results=False,\n",
|
212
|
+
")\n",
|
213
|
+
"\n",
|
214
|
+
"print(f\"Change detection completed!\")\n",
|
215
|
+
"print(f\"Total instances detected: {results['summary']['total_masks']}\")\n",
|
216
|
+
"print(f\"Image size: {results['summary']['original_shape']}\")"
|
217
|
+
]
|
218
|
+
},
|
219
|
+
{
|
220
|
+
"cell_type": "markdown",
|
221
|
+
"metadata": {},
|
222
|
+
"source": [
|
223
|
+
"## Analyze Results\n",
|
224
|
+
"\n",
|
225
|
+
"Display key statistics and quality metrics."
|
226
|
+
]
|
227
|
+
},
|
228
|
+
{
|
229
|
+
"cell_type": "code",
|
230
|
+
"execution_count": null,
|
231
|
+
"metadata": {},
|
232
|
+
"outputs": [],
|
233
|
+
"source": [
|
234
|
+
"# Display statistics\n",
|
235
|
+
"if \"statistics\" in results and results[\"statistics\"]:\n",
|
236
|
+
" print(\"Quality Statistics:\")\n",
|
237
|
+
" for metric, stats in results[\"statistics\"].items():\n",
|
238
|
+
" print(f\" {metric}: mean={stats['mean']:.3f}, std={stats['std']:.3f}\")\n",
|
239
|
+
"\n",
|
240
|
+
"# Show top instances\n",
|
241
|
+
"if \"masks\" in results and len(results[\"masks\"]) > 0:\n",
|
242
|
+
" print(\"\\nTop 5 detected instances:\")\n",
|
243
|
+
" for i, mask in enumerate(results[\"masks\"][:5]):\n",
|
244
|
+
" print(\n",
|
245
|
+
" f\" {i+1}. Instance {mask['mask_id']}: \"\n",
|
246
|
+
" f\"IoU={mask['iou_pred']:.3f}, \"\n",
|
247
|
+
" f\"Stability={mask['stability_score']:.3f}, \"\n",
|
248
|
+
" f\"Area={mask['area']} pixels\"\n",
|
249
|
+
" )"
|
250
|
+
]
|
251
|
+
},
|
252
|
+
{
|
253
|
+
"cell_type": "markdown",
|
254
|
+
"metadata": {},
|
255
|
+
"source": [
|
256
|
+
"## Visualizations\n",
|
257
|
+
"\n",
|
258
|
+
"Use the integrated visualization methods for comprehensive analysis."
|
259
|
+
]
|
260
|
+
},
|
261
|
+
{
|
262
|
+
"cell_type": "code",
|
263
|
+
"execution_count": null,
|
264
|
+
"metadata": {},
|
265
|
+
"outputs": [],
|
266
|
+
"source": [
|
267
|
+
"# probability visualization\n",
|
268
|
+
"detector.visualize_results(\n",
|
269
|
+
" naip_2019_path,\n",
|
270
|
+
" naip_2022_path,\n",
|
271
|
+
" f\"{out_folder}/binary_mask.tif\",\n",
|
272
|
+
" f\"{out_folder}/probability_mask.tif\",\n",
|
273
|
+
")"
|
274
|
+
]
|
275
|
+
},
|
276
|
+
{
|
277
|
+
"cell_type": "markdown",
|
278
|
+
"metadata": {},
|
279
|
+
"source": [
|
280
|
+
""
|
281
|
+
]
|
282
|
+
},
|
283
|
+
{
|
284
|
+
"cell_type": "code",
|
285
|
+
"execution_count": null,
|
286
|
+
"metadata": {},
|
287
|
+
"outputs": [],
|
288
|
+
"source": [
|
289
|
+
"# Create split comparison visualization\n",
|
290
|
+
"detector.create_split_comparison(\n",
|
291
|
+
" naip_2019_path,\n",
|
292
|
+
" naip_2022_path,\n",
|
293
|
+
" f\"{out_folder}/binary_mask.tif\",\n",
|
294
|
+
" f\"{out_folder}/probability_mask.tif\",\n",
|
295
|
+
" f\"{out_folder}/split_comparison.png\",\n",
|
296
|
+
")"
|
297
|
+
]
|
298
|
+
},
|
299
|
+
{
|
300
|
+
"cell_type": "code",
|
301
|
+
"execution_count": null,
|
302
|
+
"metadata": {},
|
303
|
+
"outputs": [],
|
304
|
+
"source": [
|
305
|
+
"# Analyze individual instances\n",
|
306
|
+
"instance_stats = detector.analyze_instances(\n",
|
307
|
+
" f\"{out_folder}/instance_masks.tif\",\n",
|
308
|
+
" f\"{out_folder}/instance_masks_scores.tif\",\n",
|
309
|
+
" f\"{out_folder}/instance_analysis.png\",\n",
|
310
|
+
")"
|
311
|
+
]
|
312
|
+
},
|
313
|
+
{
|
314
|
+
"cell_type": "markdown",
|
315
|
+
"metadata": {},
|
316
|
+
"source": [
|
317
|
+
""
|
318
|
+
]
|
319
|
+
},
|
320
|
+
{
|
321
|
+
"cell_type": "markdown",
|
322
|
+
"metadata": {},
|
323
|
+
"source": [
|
324
|
+
"## Comprehensive Analysis Report\n",
|
325
|
+
"\n",
|
326
|
+
"Generate a detailed analysis report combining all metrics."
|
327
|
+
]
|
328
|
+
},
|
329
|
+
{
|
330
|
+
"cell_type": "code",
|
331
|
+
"execution_count": null,
|
332
|
+
"metadata": {},
|
333
|
+
"outputs": [],
|
334
|
+
"source": [
|
335
|
+
"# Create comprehensive analysis report\n",
|
336
|
+
"detector.create_comprehensive_report(results, f\"{out_folder}/comprehensive_report.png\")"
|
337
|
+
]
|
338
|
+
},
|
339
|
+
{
|
340
|
+
"cell_type": "markdown",
|
341
|
+
"metadata": {},
|
342
|
+
"source": [
|
343
|
+
""
|
344
|
+
]
|
345
|
+
},
|
346
|
+
{
|
347
|
+
"cell_type": "markdown",
|
348
|
+
"metadata": {},
|
349
|
+
"source": [
|
350
|
+
"## One-Click Complete Analysis\n",
|
351
|
+
"\n",
|
352
|
+
"For ultimate simplicity, use the complete analysis method."
|
353
|
+
]
|
354
|
+
},
|
355
|
+
{
|
356
|
+
"cell_type": "code",
|
357
|
+
"execution_count": null,
|
358
|
+
"metadata": {},
|
359
|
+
"outputs": [],
|
360
|
+
"source": [
|
361
|
+
"# Alternative: Run complete analysis in one step\n",
|
362
|
+
"# This method does everything - detection, file outputs, and all visualizations\n",
|
363
|
+
"complete_results = detector.run_complete_analysis(\n",
|
364
|
+
" naip_2019_path, naip_2022_path, \"complete_analysis_results\"\n",
|
365
|
+
")"
|
366
|
+
]
|
367
|
+
},
|
368
|
+
{
|
369
|
+
"cell_type": "markdown",
|
370
|
+
"metadata": {},
|
371
|
+
"source": [
|
372
|
+
"## Summary\n",
|
373
|
+
"\n",
|
374
|
+
"This notebook demonstrated the change detection functionality in GeoAI with integrated visualization methods:\n",
|
375
|
+
"\n",
|
376
|
+
"### Key Features Used:\n",
|
377
|
+
"1. **Change Detection**: Instance segmentation with confidence scoring\n",
|
378
|
+
"2. **Integrated Visualizations**: Built-in methods for comprehensive analysis\n",
|
379
|
+
"3. **Simplified API**: Clean, streamlined interface following geoai patterns\n",
|
380
|
+
"4. **Complete Analysis**: One-click method for full analysis workflow\n",
|
381
|
+
"\n",
|
382
|
+
"### Output Files Generated:\n",
|
383
|
+
"- `binary_mask.tif`: Traditional binary change detection\n",
|
384
|
+
"- `probability_mask.tif`: Probability-weighted change detection \n",
|
385
|
+
"- `instance_masks.tif`: Instance segmentation with unique IDs\n",
|
386
|
+
"- `instance_masks_scores.tif`: Confidence scores for each instance\n",
|
387
|
+
"- `enhanced_probability_results.png`: Comprehensive visualization\n",
|
388
|
+
"- `split_comparison.png`: Before/after split comparison\n",
|
389
|
+
"- `instance_analysis.png`: Individual instance analysis\n",
|
390
|
+
"- `comprehensive_report.png`: Complete analysis report\n",
|
391
|
+
"\n",
|
392
|
+
"### Advantages Over Traditional Methods:\n",
|
393
|
+
"1. **Instance-Level Analysis**: Each change object has unique ID and metrics\n",
|
394
|
+
"2. **Quality Assessment**: Confidence scores for filtering and ranking\n",
|
395
|
+
"3. **Rich Visualizations**: Multiple analysis perspectives in one package\n",
|
396
|
+
"4. **Simplified Workflow**: Integrated methods reduce code complexity\n",
|
397
|
+
"5. **Flexible Usage**: From simple detection to comprehensive analysis"
|
398
|
+
]
|
399
|
+
}
|
400
|
+
],
|
401
|
+
"metadata": {
|
402
|
+
"kernelspec": {
|
403
|
+
"display_name": "geo",
|
404
|
+
"language": "python",
|
405
|
+
"name": "python3"
|
406
|
+
},
|
407
|
+
"language_info": {
|
408
|
+
"codemirror_mode": {
|
409
|
+
"name": "ipython",
|
410
|
+
"version": 3
|
411
|
+
},
|
412
|
+
"file_extension": ".py",
|
413
|
+
"mimetype": "text/x-python",
|
414
|
+
"name": "python",
|
415
|
+
"nbconvert_exporter": "python",
|
416
|
+
"pygments_lexer": "ipython3",
|
417
|
+
"version": "3.12.2"
|
418
|
+
}
|
419
|
+
},
|
420
|
+
"nbformat": 4,
|
421
|
+
"nbformat_minor": 4
|
422
|
+
}
|