geoai-py 0.8.3__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.
Files changed (131) hide show
  1. {geoai_py-0.8.3 → geoai_py-0.9.0}/.github/workflows/docs-build.yml +9 -6
  2. {geoai_py-0.8.3 → geoai_py-0.9.0}/.github/workflows/docs.yml +9 -6
  3. {geoai_py-0.8.3 → geoai_py-0.9.0}/.github/workflows/ubuntu.yml +9 -6
  4. {geoai_py-0.8.3 → geoai_py-0.9.0}/PKG-INFO +3 -1
  5. geoai_py-0.9.0/docs/change_detection.md +3 -0
  6. geoai_py-0.9.0/docs/examples/change_detection.ipynb +422 -0
  7. {geoai_py-0.8.3 → geoai_py-0.9.0}/geoai/__init__.py +1 -1
  8. geoai_py-0.9.0/geoai/change_detection.py +1561 -0
  9. {geoai_py-0.8.3 → geoai_py-0.9.0}/geoai/geoai.py +1 -0
  10. {geoai_py-0.8.3 → geoai_py-0.9.0}/geoai/train.py +75 -8
  11. {geoai_py-0.8.3 → geoai_py-0.9.0}/geoai_py.egg-info/PKG-INFO +3 -1
  12. {geoai_py-0.8.3 → geoai_py-0.9.0}/geoai_py.egg-info/SOURCES.txt +3 -1
  13. {geoai_py-0.8.3 → geoai_py-0.9.0}/geoai_py.egg-info/requires.txt +2 -0
  14. {geoai_py-0.8.3 → geoai_py-0.9.0}/mkdocs.yml +2 -0
  15. {geoai_py-0.8.3 → geoai_py-0.9.0}/pyproject.toml +2 -2
  16. {geoai_py-0.8.3 → geoai_py-0.9.0}/requirements.txt +2 -0
  17. geoai_py-0.8.3/docs/examples/waterbody-dataset-sample/README.md +0 -1
  18. {geoai_py-0.8.3 → geoai_py-0.9.0}/.editorconfig +0 -0
  19. {geoai_py-0.8.3 → geoai_py-0.9.0}/.github/FUNDING.yml +0 -0
  20. {geoai_py-0.8.3 → geoai_py-0.9.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  21. {geoai_py-0.8.3 → geoai_py-0.9.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  22. {geoai_py-0.8.3 → geoai_py-0.9.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  23. {geoai_py-0.8.3 → geoai_py-0.9.0}/.github/dependabot.yml +0 -0
  24. {geoai_py-0.8.3 → geoai_py-0.9.0}/.github/workflows/docker-image.yml +0 -0
  25. {geoai_py-0.8.3 → geoai_py-0.9.0}/.github/workflows/docker-publish.yml +0 -0
  26. {geoai_py-0.8.3 → geoai_py-0.9.0}/.github/workflows/macos.yml +0 -0
  27. {geoai_py-0.8.3 → geoai_py-0.9.0}/.github/workflows/pypi.yml +0 -0
  28. {geoai_py-0.8.3 → geoai_py-0.9.0}/.github/workflows/windows.yml +0 -0
  29. {geoai_py-0.8.3 → geoai_py-0.9.0}/.gitignore +0 -0
  30. {geoai_py-0.8.3 → geoai_py-0.9.0}/.pre-commit-config.yaml +0 -0
  31. {geoai_py-0.8.3 → geoai_py-0.9.0}/Dockerfile +0 -0
  32. {geoai_py-0.8.3 → geoai_py-0.9.0}/LICENSE +0 -0
  33. {geoai_py-0.8.3 → geoai_py-0.9.0}/MANIFEST.in +0 -0
  34. {geoai_py-0.8.3 → geoai_py-0.9.0}/README.md +0 -0
  35. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/CNAME +0 -0
  36. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/assets/logo.ico +0 -0
  37. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/assets/logo.png +0 -0
  38. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/assets/logo_rect.png +0 -0
  39. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/changelog.md +0 -0
  40. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/classify.md +0 -0
  41. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/contributing.md +0 -0
  42. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/download.md +0 -0
  43. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/_template.ipynb +0 -0
  44. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/batch_segmentation.ipynb +0 -0
  45. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/building_detection_lidar.ipynb +0 -0
  46. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/building_footprints_africa.ipynb +0 -0
  47. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/building_footprints_china.ipynb +0 -0
  48. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/building_footprints_usa.ipynb +0 -0
  49. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/building_regularization.ipynb +0 -0
  50. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/car_detection.ipynb +0 -0
  51. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/create_vector.ipynb +0 -0
  52. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/data_visualization.ipynb +0 -0
  53. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/dataviz/lidar_viz.ipynb +0 -0
  54. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/dataviz/raster_viz.ipynb +0 -0
  55. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/dataviz/vector_viz.ipynb +0 -0
  56. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/download_data.ipynb +0 -0
  57. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/download_naip.ipynb +0 -0
  58. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/download_sentinel2.ipynb +0 -0
  59. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/edit_vector.ipynb +0 -0
  60. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/geometric_properties.ipynb +0 -0
  61. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/globe_projection.ipynb +0 -0
  62. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/grounded_sam.ipynb +0 -0
  63. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/image_chips.ipynb +0 -0
  64. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/image_tiling.ipynb +0 -0
  65. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/instance_segmentation.ipynb +0 -0
  66. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/jupytext.toml +0 -0
  67. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/load_model_checkpoint.ipynb +0 -0
  68. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/parking_spot_detection.ipynb +0 -0
  69. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/planetary_computer.ipynb +0 -0
  70. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/rastervision/semantic_segmentation.ipynb +0 -0
  71. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/regularization.ipynb +0 -0
  72. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/samgeo/arcgis.ipynb +0 -0
  73. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/samgeo/automatic_mask_generator.ipynb +0 -0
  74. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/samgeo/automatic_mask_generator_hq.ipynb +0 -0
  75. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/samgeo/box_prompts.ipynb +0 -0
  76. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/samgeo/fast_sam.ipynb +0 -0
  77. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/samgeo/input_prompts.ipynb +0 -0
  78. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/samgeo/input_prompts_hq.ipynb +0 -0
  79. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/samgeo/maxar_open_data.ipynb +0 -0
  80. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/samgeo/satellite-predictor.ipynb +0 -0
  81. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/samgeo/satellite.ipynb +0 -0
  82. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/samgeo/swimming_pools.ipynb +0 -0
  83. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/samgeo/text_prompts.ipynb +0 -0
  84. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/samgeo/text_prompts_batch.ipynb +0 -0
  85. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/samgeo.ipynb +0 -0
  86. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/ship_detection.ipynb +0 -0
  87. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/solar_panel_detection.ipynb +0 -0
  88. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/text_prompt_segmentation.ipynb +0 -0
  89. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/train_building_footprints_usa.ipynb +0 -0
  90. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/train_car_detection.ipynb +0 -0
  91. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/train_landcover_classification.ipynb +0 -0
  92. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/train_object_detection_model.ipynb +0 -0
  93. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/train_segmentation_model.ipynb +0 -0
  94. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/train_ship_detection.ipynb +0 -0
  95. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/train_solar_panel_detection.ipynb +0 -0
  96. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/train_water_detection.ipynb +0 -0
  97. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/view_metadata.ipynb +0 -0
  98. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/water_detection.ipynb +0 -0
  99. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/water_detection_s2.ipynb +0 -0
  100. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/water_dynamics.ipynb +0 -0
  101. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/examples/wetland_mapping.ipynb +0 -0
  102. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/extract.md +0 -0
  103. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/faq.md +0 -0
  104. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/geoai.md +0 -0
  105. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/hf.md +0 -0
  106. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/index.md +0 -0
  107. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/installation.md +0 -0
  108. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/overrides/main.html +0 -0
  109. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/sam.md +0 -0
  110. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/segment.md +0 -0
  111. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/segmentation.md +0 -0
  112. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/train.md +0 -0
  113. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/usage.md +0 -0
  114. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/utils.md +0 -0
  115. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/workshops/GeoAI_Workshop_2025.ipynb +0 -0
  116. {geoai_py-0.8.3 → geoai_py-0.9.0}/docs/workshops/jupytext.toml +0 -0
  117. {geoai_py-0.8.3 → geoai_py-0.9.0}/geoai/classify.py +0 -0
  118. {geoai_py-0.8.3 → geoai_py-0.9.0}/geoai/download.py +0 -0
  119. {geoai_py-0.8.3 → geoai_py-0.9.0}/geoai/extract.py +0 -0
  120. {geoai_py-0.8.3 → geoai_py-0.9.0}/geoai/hf.py +0 -0
  121. {geoai_py-0.8.3 → geoai_py-0.9.0}/geoai/sam.py +0 -0
  122. {geoai_py-0.8.3 → geoai_py-0.9.0}/geoai/segment.py +0 -0
  123. {geoai_py-0.8.3 → geoai_py-0.9.0}/geoai/segmentation.py +0 -0
  124. {geoai_py-0.8.3 → geoai_py-0.9.0}/geoai/utils.py +0 -0
  125. {geoai_py-0.8.3 → geoai_py-0.9.0}/geoai_py.egg-info/dependency_links.txt +0 -0
  126. {geoai_py-0.8.3 → geoai_py-0.9.0}/geoai_py.egg-info/entry_points.txt +0 -0
  127. {geoai_py-0.8.3 → geoai_py-0.9.0}/geoai_py.egg-info/top_level.txt +0 -0
  128. {geoai_py-0.8.3 → geoai_py-0.9.0}/requirements_docs.txt +0 -0
  129. {geoai_py-0.8.3 → geoai_py-0.9.0}/setup.cfg +0 -0
  130. {geoai_py-0.8.3 → geoai_py-0.9.0}/tests/__init__.py +0 -0
  131. {geoai_py-0.8.3 → 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
- run: |
42
- uv run python -c "import geoai; print('geoai import successful')"
43
- uv run python -c "from osgeo import gdal; print('gdal import successful')"
44
- uv run gdalinfo --version
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
- run: |
41
- uv run python -c "import geoai; print('geoai import successful')"
42
- uv run python -c "from osgeo import gdal; print('gdal import successful')"
43
- uv run gdalinfo --version
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
- uv pip install --find-links https://girder.github.io/large_image_wheels gdal pyproj
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
- 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
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.8.3
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,3 @@
1
+ # change_detection module
2
+
3
+ ::: geoai.change_detection
@@ -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
+ "[![image](https://colab.research.google.com/assets/colab-badge.svg)](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
+ "![](https://github.com/user-attachments/assets/e7c00b50-c456-4653-b8ce-0c9ec8f05b7f)"
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
+ "![](https://github.com/user-attachments/assets/ea1f8a51-ea14-415a-9733-78b243061dd3)"
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
+ "![](https://github.com/user-attachments/assets/629caf85-0713-4e04-8023-f4273edbbb4c)"
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
+ }
@@ -2,7 +2,7 @@
2
2
 
3
3
  __author__ = """Qiusheng Wu"""
4
4
  __email__ = "giswqs@gmail.com"
5
- __version__ = "0.8.3"
5
+ __version__ = "0.9.0"
6
6
 
7
7
 
8
8
  import os