geoai-py 0.26.0__tar.gz → 0.28.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 (90) hide show
  1. {geoai_py-0.26.0 → geoai_py-0.28.0}/.gitignore +4 -0
  2. {geoai_py-0.26.0 → geoai_py-0.28.0}/PKG-INFO +9 -7
  3. {geoai_py-0.26.0 → geoai_py-0.28.0}/README.md +3 -3
  4. {geoai_py-0.26.0 → geoai_py-0.28.0}/geoai/__init__.py +41 -1
  5. {geoai_py-0.26.0 → geoai_py-0.28.0}/geoai/auto.py +4 -1
  6. {geoai_py-0.26.0 → geoai_py-0.28.0}/geoai/change_detection.py +1 -1
  7. {geoai_py-0.26.0 → geoai_py-0.28.0}/geoai/detectron2.py +4 -1
  8. {geoai_py-0.26.0 → geoai_py-0.28.0}/geoai/extract.py +10 -7
  9. {geoai_py-0.26.0 → geoai_py-0.28.0}/geoai/hf.py +3 -3
  10. {geoai_py-0.26.0 → geoai_py-0.28.0}/geoai/moondream.py +2 -2
  11. geoai_py-0.28.0/geoai/onnx.py +1155 -0
  12. {geoai_py-0.26.0 → geoai_py-0.28.0}/geoai/prithvi.py +92 -7
  13. {geoai_py-0.26.0 → geoai_py-0.28.0}/geoai/sam.py +2 -1
  14. {geoai_py-0.26.0 → geoai_py-0.28.0}/geoai/segment.py +10 -1
  15. geoai_py-0.28.0/geoai/timm_regress.py +1652 -0
  16. {geoai_py-0.26.0 → geoai_py-0.28.0}/geoai/train.py +1 -1
  17. {geoai_py-0.26.0 → geoai_py-0.28.0}/geoai/utils.py +550 -1
  18. {geoai_py-0.26.0 → geoai_py-0.28.0}/geoai_py.egg-info/PKG-INFO +9 -7
  19. {geoai_py-0.26.0 → geoai_py-0.28.0}/geoai_py.egg-info/SOURCES.txt +4 -0
  20. {geoai_py-0.26.0 → geoai_py-0.28.0}/geoai_py.egg-info/requires.txt +7 -3
  21. {geoai_py-0.26.0 → geoai_py-0.28.0}/mkdocs.yml +5 -0
  22. {geoai_py-0.26.0 → geoai_py-0.28.0}/pyproject.toml +4 -2
  23. {geoai_py-0.26.0 → geoai_py-0.28.0}/qgis_plugin/README.md +3 -0
  24. geoai_py-0.28.0/qgis_plugin/geoai_plugin/dialogs/deepforest_panel.py +1737 -0
  25. {geoai_py-0.26.0 → geoai_py-0.28.0}/qgis_plugin/geoai_plugin/dialogs/moondream.py +241 -42
  26. {geoai_py-0.26.0 → geoai_py-0.28.0}/qgis_plugin/geoai_plugin/dialogs/samgeo.py +288 -80
  27. {geoai_py-0.26.0 → geoai_py-0.28.0}/qgis_plugin/geoai_plugin/dialogs/segmentation.py +23 -4
  28. {geoai_py-0.26.0 → geoai_py-0.28.0}/qgis_plugin/geoai_plugin/geoai_plugin.py +119 -0
  29. geoai_py-0.28.0/qgis_plugin/geoai_plugin/icons/deepforest.svg +8 -0
  30. {geoai_py-0.26.0 → geoai_py-0.28.0}/qgis_plugin/geoai_plugin/metadata.txt +7 -1
  31. {geoai_py-0.26.0 → geoai_py-0.28.0}/requirements.txt +0 -3
  32. {geoai_py-0.26.0 → geoai_py-0.28.0}/.dockerignore +0 -0
  33. {geoai_py-0.26.0 → geoai_py-0.28.0}/.editorconfig +0 -0
  34. {geoai_py-0.26.0 → geoai_py-0.28.0}/.pre-commit-config.yaml +0 -0
  35. {geoai_py-0.26.0 → geoai_py-0.28.0}/CITATION.cff +0 -0
  36. {geoai_py-0.26.0 → geoai_py-0.28.0}/Dockerfile +0 -0
  37. {geoai_py-0.26.0 → geoai_py-0.28.0}/LICENSE +0 -0
  38. {geoai_py-0.26.0 → geoai_py-0.28.0}/MANIFEST.in +0 -0
  39. {geoai_py-0.26.0 → geoai_py-0.28.0}/geoai/agents/__init__.py +0 -0
  40. {geoai_py-0.26.0 → geoai_py-0.28.0}/geoai/agents/catalog_models.py +0 -0
  41. {geoai_py-0.26.0 → geoai_py-0.28.0}/geoai/agents/catalog_tools.py +0 -0
  42. {geoai_py-0.26.0 → geoai_py-0.28.0}/geoai/agents/geo_agents.py +0 -0
  43. {geoai_py-0.26.0 → geoai_py-0.28.0}/geoai/agents/map_tools.py +0 -0
  44. {geoai_py-0.26.0 → geoai_py-0.28.0}/geoai/agents/stac_models.py +0 -0
  45. {geoai_py-0.26.0 → geoai_py-0.28.0}/geoai/agents/stac_tools.py +0 -0
  46. {geoai_py-0.26.0 → geoai_py-0.28.0}/geoai/classify.py +0 -0
  47. {geoai_py-0.26.0 → geoai_py-0.28.0}/geoai/dinov3.py +0 -0
  48. {geoai_py-0.26.0 → geoai_py-0.28.0}/geoai/download.py +0 -0
  49. {geoai_py-0.26.0 → geoai_py-0.28.0}/geoai/geoai.py +0 -0
  50. {geoai_py-0.26.0 → geoai_py-0.28.0}/geoai/landcover_train.py +0 -0
  51. {geoai_py-0.26.0 → geoai_py-0.28.0}/geoai/landcover_utils.py +0 -0
  52. {geoai_py-0.26.0 → geoai_py-0.28.0}/geoai/map_widgets.py +0 -0
  53. {geoai_py-0.26.0 → geoai_py-0.28.0}/geoai/segmentation.py +0 -0
  54. {geoai_py-0.26.0 → geoai_py-0.28.0}/geoai/timm_segment.py +0 -0
  55. {geoai_py-0.26.0 → geoai_py-0.28.0}/geoai/timm_train.py +0 -0
  56. {geoai_py-0.26.0 → geoai_py-0.28.0}/geoai/tools/__init__.py +0 -0
  57. {geoai_py-0.26.0 → geoai_py-0.28.0}/geoai/tools/cloudmask.py +0 -0
  58. {geoai_py-0.26.0 → geoai_py-0.28.0}/geoai/tools/multiclean.py +0 -0
  59. {geoai_py-0.26.0 → geoai_py-0.28.0}/geoai/tools/sr.py +0 -0
  60. {geoai_py-0.26.0 → geoai_py-0.28.0}/geoai_py.egg-info/dependency_links.txt +0 -0
  61. {geoai_py-0.26.0 → geoai_py-0.28.0}/geoai_py.egg-info/entry_points.txt +0 -0
  62. {geoai_py-0.26.0 → geoai_py-0.28.0}/geoai_py.egg-info/top_level.txt +0 -0
  63. {geoai_py-0.26.0 → geoai_py-0.28.0}/pytest.ini +0 -0
  64. {geoai_py-0.26.0 → geoai_py-0.28.0}/qgis_plugin/geoai_plugin/LICENSE +0 -0
  65. {geoai_py-0.26.0 → geoai_py-0.28.0}/qgis_plugin/geoai_plugin/__init__.py +0 -0
  66. {geoai_py-0.26.0 → geoai_py-0.28.0}/qgis_plugin/geoai_plugin/_geoai_lib.py +0 -0
  67. {geoai_py-0.26.0 → geoai_py-0.28.0}/qgis_plugin/geoai_plugin/dialogs/__init__.py +0 -0
  68. {geoai_py-0.26.0 → geoai_py-0.28.0}/qgis_plugin/geoai_plugin/dialogs/map_tools.py +0 -0
  69. {geoai_py-0.26.0 → geoai_py-0.28.0}/qgis_plugin/geoai_plugin/dialogs/update_checker.py +0 -0
  70. {geoai_py-0.26.0 → geoai_py-0.28.0}/qgis_plugin/geoai_plugin/icons/about.svg +0 -0
  71. {geoai_py-0.26.0 → geoai_py-0.28.0}/qgis_plugin/geoai_plugin/icons/gpu.svg +0 -0
  72. {geoai_py-0.26.0 → geoai_py-0.28.0}/qgis_plugin/geoai_plugin/icons/icon.png +0 -0
  73. {geoai_py-0.26.0 → geoai_py-0.28.0}/qgis_plugin/geoai_plugin/icons/moondream.svg +0 -0
  74. {geoai_py-0.26.0 → geoai_py-0.28.0}/qgis_plugin/geoai_plugin/icons/samgeo.png +0 -0
  75. {geoai_py-0.26.0 → geoai_py-0.28.0}/qgis_plugin/geoai_plugin/icons/segment.svg +0 -0
  76. {geoai_py-0.26.0 → geoai_py-0.28.0}/qgis_plugin/install.py +0 -0
  77. {geoai_py-0.26.0 → geoai_py-0.28.0}/qgis_plugin/install.sh +0 -0
  78. {geoai_py-0.26.0 → geoai_py-0.28.0}/qgis_plugin/package_plugin.py +0 -0
  79. {geoai_py-0.26.0 → geoai_py-0.28.0}/requirements_docs.txt +0 -0
  80. {geoai_py-0.26.0 → geoai_py-0.28.0}/setup.cfg +0 -0
  81. {geoai_py-0.26.0 → geoai_py-0.28.0}/tests/__init__.py +0 -0
  82. {geoai_py-0.26.0 → geoai_py-0.28.0}/tests/create_test_data.py +0 -0
  83. {geoai_py-0.26.0 → geoai_py-0.28.0}/tests/test_classify.py +0 -0
  84. {geoai_py-0.26.0 → geoai_py-0.28.0}/tests/test_download.py +0 -0
  85. {geoai_py-0.26.0 → geoai_py-0.28.0}/tests/test_extract.py +0 -0
  86. {geoai_py-0.26.0 → geoai_py-0.28.0}/tests/test_fixtures.py +0 -0
  87. {geoai_py-0.26.0 → geoai_py-0.28.0}/tests/test_geoai.py +0 -0
  88. {geoai_py-0.26.0 → geoai_py-0.28.0}/tests/test_moondream.py +0 -0
  89. {geoai_py-0.26.0 → geoai_py-0.28.0}/tests/test_segment.py +0 -0
  90. {geoai_py-0.26.0 → geoai_py-0.28.0}/tests/test_utils.py +0 -0
@@ -32,6 +32,9 @@ docs/workshops/**/*.jpg
32
32
  docs/workshops/**/*.png
33
33
  docs/examples/data/
34
34
  docs/workshops/data/
35
+ docs/examples/ndvi_regression_output/
36
+ docs/examples/timm_regression_output/
37
+ docs/examples/ndvi_model/
35
38
  *.pth
36
39
 
37
40
  # Distribution / packaging
@@ -135,3 +138,4 @@ ENV/
135
138
  .vscode/
136
139
  .DS_Store
137
140
  CLAUDE.md
141
+ lightning_logs/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: geoai-py
3
- Version: 0.26.0
3
+ Version: 0.28.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
@@ -17,10 +17,8 @@ Requires-Python: >=3.10
17
17
  Description-Content-Type: text/markdown
18
18
  License-File: LICENSE
19
19
  Requires-Dist: albumentations
20
- Requires-Dist: buildingregulariser
21
20
  Requires-Dist: contextily
22
21
  Requires-Dist: datasets>=3.0
23
- Requires-Dist: ever-beta
24
22
  Requires-Dist: geopandas
25
23
  Requires-Dist: huggingface_hub
26
24
  Requires-Dist: jupyter-server-proxy
@@ -31,7 +29,6 @@ Requires-Dist: maplibre
31
29
  Requires-Dist: opencv-python-headless
32
30
  Requires-Dist: overturemaps
33
31
  Requires-Dist: planetary-computer
34
- Requires-Dist: psutil
35
32
  Requires-Dist: pyarrow
36
33
  Requires-Dist: pystac-client
37
34
  Requires-Dist: rasterio
@@ -53,12 +50,17 @@ Requires-Dist: lightly-train; extra == "extra"
53
50
  Requires-Dist: multiclean; extra == "extra"
54
51
  Requires-Dist: omnicloudmask; extra == "extra"
55
52
  Requires-Dist: smoothify; extra == "extra"
53
+ Provides-Extra: building
54
+ Requires-Dist: buildingregulariser; extra == "building"
56
55
  Provides-Extra: agents
57
56
  Requires-Dist: strands-agents; extra == "agents"
58
57
  Requires-Dist: strands-agents-tools; extra == "agents"
59
58
  Requires-Dist: strands-agents[ollama]; extra == "agents"
60
59
  Requires-Dist: strands-agents[anthropic]; extra == "agents"
61
60
  Requires-Dist: strands-agents[openai]; extra == "agents"
61
+ Provides-Extra: onnx
62
+ Requires-Dist: onnx; extra == "onnx"
63
+ Requires-Dist: onnxruntime; extra == "onnx"
62
64
  Provides-Extra: sr
63
65
  Requires-Dist: opensr-model; extra == "sr"
64
66
  Dynamic: license-file
@@ -71,7 +73,7 @@ Dynamic: license-file
71
73
  [![Conda Downloads](https://img.shields.io/conda/dn/conda-forge/geoai.svg)](https://anaconda.org/conda-forge/geoai)
72
74
  [![Conda Recipe](https://img.shields.io/badge/recipe-geoai-green.svg)](https://github.com/conda-forge/geoai-py-feedstock)
73
75
  [![image](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
74
- [![image](https://img.shields.io/badge/YouTube-Tutorials-red)](https://tinyurl.com/GeoAI-Tutorials)
76
+ [![image](https://img.shields.io/badge/YouTube-Tutorials-red)](https://www.youtube.com/playlist?list=PLAxJ4-o7ZoPcvENqwaPa_QwbbkZ5sctZE)
75
77
  [![QGIS](https://img.shields.io/badge/QGIS-plugin-orange.svg)](https://opengeoai.org/qgis_plugin)
76
78
 
77
79
  [![logo](https://raw.githubusercontent.com/opengeos/geoai/master/docs/assets/logo_rect.png)](https://github.com/opengeos/geoai/blob/master/docs/assets/logo.png)
@@ -91,7 +93,7 @@ The package provides five core capabilities:
91
93
  5. Interactive visualization through integration with [Leafmap](https://github.com/opengeos/leafmap/) and [MapLibre](https://github.com/eoda-dev/py-maplibregl).
92
94
  6. Seamless QGIS integration via a dedicated GeoAI plugin, enabling users to run AI-powered geospatial workflows directly within the QGIS desktop environment, without writing code.
93
95
 
94
- GeoAI addresses the growing demand for accessible AI tools in geospatial research by providing high-level APIs that abstract complex machine learning workflows while maintaining flexibility for advanced users. The package supports multiple data formats (GeoTIFF, JPEG2000,GeoJSON, Shapefile, GeoPackage) and includes automatic device management for GPU acceleration when available. With over 10 modules and extensive notebook examples, GeoAI serves as both a research tool and educational resource for the geospatial AI community.
96
+ GeoAI addresses the growing demand for accessible AI tools in geospatial research by providing high-level APIs that abstract complex machine learning workflows while maintaining flexibility for advanced users. The package supports multiple data formats (GeoTIFF, JPEG2000, GeoJSON, Shapefile, GeoPackage) and includes automatic device management for GPU acceleration when available. With over 10 modules and extensive notebook examples, GeoAI serves as both a research tool and educational resource for the geospatial AI community.
95
97
 
96
98
  ## 📝 Statement of Need
97
99
 
@@ -130,7 +132,7 @@ If you find GeoAI useful in your research, please consider citing the following
130
132
 
131
133
  - Integration with [PyTorch Segmentation Models](https://github.com/qubvel-org/segmentation_models.pytorch) for automatic feature extraction
132
134
  - Specialized segmentation algorithms optimized for satellite and aerial imagery
133
- - Streamlined workflows for segmenting buildings, water bodies, wetlands,solar panels, etc.
135
+ - Streamlined workflows for segmenting buildings, water bodies, wetlands, solar panels, etc.
134
136
  - Export capabilities to standard geospatial formats (GeoJSON, Shapefile, GeoPackage, GeoParquet)
135
137
 
136
138
  ### 🔍 Image Classification
@@ -6,7 +6,7 @@
6
6
  [![Conda Downloads](https://img.shields.io/conda/dn/conda-forge/geoai.svg)](https://anaconda.org/conda-forge/geoai)
7
7
  [![Conda Recipe](https://img.shields.io/badge/recipe-geoai-green.svg)](https://github.com/conda-forge/geoai-py-feedstock)
8
8
  [![image](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
9
- [![image](https://img.shields.io/badge/YouTube-Tutorials-red)](https://tinyurl.com/GeoAI-Tutorials)
9
+ [![image](https://img.shields.io/badge/YouTube-Tutorials-red)](https://www.youtube.com/playlist?list=PLAxJ4-o7ZoPcvENqwaPa_QwbbkZ5sctZE)
10
10
  [![QGIS](https://img.shields.io/badge/QGIS-plugin-orange.svg)](https://opengeoai.org/qgis_plugin)
11
11
 
12
12
  [![logo](https://raw.githubusercontent.com/opengeos/geoai/master/docs/assets/logo_rect.png)](https://github.com/opengeos/geoai/blob/master/docs/assets/logo.png)
@@ -26,7 +26,7 @@ The package provides five core capabilities:
26
26
  5. Interactive visualization through integration with [Leafmap](https://github.com/opengeos/leafmap/) and [MapLibre](https://github.com/eoda-dev/py-maplibregl).
27
27
  6. Seamless QGIS integration via a dedicated GeoAI plugin, enabling users to run AI-powered geospatial workflows directly within the QGIS desktop environment, without writing code.
28
28
 
29
- GeoAI addresses the growing demand for accessible AI tools in geospatial research by providing high-level APIs that abstract complex machine learning workflows while maintaining flexibility for advanced users. The package supports multiple data formats (GeoTIFF, JPEG2000,GeoJSON, Shapefile, GeoPackage) and includes automatic device management for GPU acceleration when available. With over 10 modules and extensive notebook examples, GeoAI serves as both a research tool and educational resource for the geospatial AI community.
29
+ GeoAI addresses the growing demand for accessible AI tools in geospatial research by providing high-level APIs that abstract complex machine learning workflows while maintaining flexibility for advanced users. The package supports multiple data formats (GeoTIFF, JPEG2000, GeoJSON, Shapefile, GeoPackage) and includes automatic device management for GPU acceleration when available. With over 10 modules and extensive notebook examples, GeoAI serves as both a research tool and educational resource for the geospatial AI community.
30
30
 
31
31
  ## 📝 Statement of Need
32
32
 
@@ -65,7 +65,7 @@ If you find GeoAI useful in your research, please consider citing the following
65
65
 
66
66
  - Integration with [PyTorch Segmentation Models](https://github.com/qubvel-org/segmentation_models.pytorch) for automatic feature extraction
67
67
  - Specialized segmentation algorithms optimized for satellite and aerial imagery
68
- - Streamlined workflows for segmenting buildings, water bodies, wetlands,solar panels, etc.
68
+ - Streamlined workflows for segmenting buildings, water bodies, wetlands, solar panels, etc.
69
69
  - Export capabilities to standard geospatial formats (GeoJSON, Shapefile, GeoPackage, GeoParquet)
70
70
 
71
71
  ### 🔍 Image Classification
@@ -2,7 +2,7 @@
2
2
 
3
3
  __author__ = """Qiusheng Wu"""
4
4
  __email__ = "giswqs@gmail.com"
5
- __version__ = "0.26.0"
5
+ __version__ = "0.28.0"
6
6
 
7
7
 
8
8
  import os
@@ -101,6 +101,14 @@ def set_proj_lib_path(verbose=False):
101
101
 
102
102
  from .dinov3 import DINOv3GeoProcessor, analyze_image_patches, create_similarity_map
103
103
  from .geoai import *
104
+ from .utils import (
105
+ orthogonalize,
106
+ regularization,
107
+ hybrid_regularization,
108
+ adaptive_regularization,
109
+ flipnslide_augmentation,
110
+ export_flipnslide_tiles,
111
+ )
104
112
 
105
113
  from .timm_train import (
106
114
  get_timm_model,
@@ -122,6 +130,25 @@ from .timm_segment import (
122
130
  push_timm_model_to_hub,
123
131
  )
124
132
 
133
+ from .timm_regress import (
134
+ PixelRegressionModel,
135
+ PixelRegressionDataset,
136
+ create_regression_tiles,
137
+ train_pixel_regressor,
138
+ predict_raster,
139
+ evaluate_regression,
140
+ plot_regression_comparison,
141
+ plot_scatter,
142
+ plot_training_history,
143
+ visualize_prediction,
144
+ plot_regression_results,
145
+ # Backward compatibility aliases
146
+ TimmRegressor,
147
+ RegressionDataset,
148
+ train_timm_regressor,
149
+ create_regression_patches,
150
+ )
151
+
125
152
  # Import tools subpackage
126
153
  from . import tools
127
154
 
@@ -145,6 +172,18 @@ except ImportError:
145
172
  # super_resolution not available (missing dependency)
146
173
  pass
147
174
 
175
+ # ONNX Runtime support
176
+ try:
177
+ from .onnx import (
178
+ ONNXGeoModel,
179
+ export_to_onnx,
180
+ onnx_semantic_segmentation,
181
+ onnx_image_classification,
182
+ )
183
+ except ImportError:
184
+ # ONNX not available (missing dependency)
185
+ pass
186
+
148
187
  # Moondream Vision Language Model
149
188
  try:
150
189
  from .moondream import (
@@ -167,6 +206,7 @@ except ImportError:
167
206
  try:
168
207
  from .prithvi import (
169
208
  PrithviProcessor,
209
+ get_available_prithvi_models,
170
210
  load_prithvi_model,
171
211
  prithvi_inference,
172
212
  )
@@ -24,7 +24,6 @@ Example:
24
24
  import os
25
25
  from typing import Any, Dict, List, Optional, Tuple, Union
26
26
 
27
- import cv2
28
27
  import geopandas as gpd
29
28
  import numpy as np
30
29
  import rasterio
@@ -877,6 +876,8 @@ class AutoGeoModel:
877
876
  **kwargs: Any,
878
877
  ) -> Dict[str, Any]:
879
878
  """Run tiled inference for large images."""
879
+ import cv2 # Lazy import to avoid QGIS opencv conflicts
880
+
880
881
  if data.ndim == 3:
881
882
  _, height, width = data.shape
882
883
  else:
@@ -1872,6 +1873,7 @@ def show_segmentation(
1872
1873
  >>> result = geoai.auto.semantic_segmentation("aerial.tif", output_path="seg.tif")
1873
1874
  >>> fig = show_segmentation("aerial.tif", result["mask"])
1874
1875
  """
1876
+ import cv2 # Lazy import to avoid QGIS opencv conflicts
1875
1877
  import matplotlib.pyplot as plt
1876
1878
 
1877
1879
  img, _ = _load_image_for_display(source)
@@ -1941,6 +1943,7 @@ def show_depth(
1941
1943
  >>> result = geoai.auto.depth_estimation("aerial.tif", output_path="depth.tif")
1942
1944
  >>> fig = show_depth("aerial.tif", result["depth"])
1943
1945
  """
1946
+ import cv2 # Lazy import to avoid QGIS opencv conflicts
1944
1947
  import matplotlib.pyplot as plt
1945
1948
 
1946
1949
  img, _ = _load_image_for_display(source)
@@ -3,7 +3,6 @@
3
3
  import os
4
4
  from typing import Any, Dict, List, Optional, Tuple, Union
5
5
 
6
- import cv2
7
6
  import matplotlib.pyplot as plt
8
7
  import numpy as np
9
8
  import rasterio
@@ -736,6 +735,7 @@ class ChangeDetection:
736
735
  output_path="split_comparison.png",
737
736
  ):
738
737
  """Create a split comparison visualization showing before/after with change overlay."""
738
+ import cv2 # Lazy import to avoid QGIS opencv conflicts
739
739
 
740
740
  # Load data
741
741
  with rasterio.open(image1_path) as src:
@@ -6,7 +6,6 @@ import os
6
6
  import warnings
7
7
  from typing import Dict, List, Optional, Tuple, Union
8
8
 
9
- import cv2
10
9
  import numpy as np
11
10
  import rasterio
12
11
  import torch
@@ -135,6 +134,8 @@ def detectron2_segment(
135
134
  Returns:
136
135
  Dict containing segmentation results and output file paths
137
136
  """
137
+ import cv2 # Lazy import to avoid QGIS opencv conflicts
138
+
138
139
  check_detectron2()
139
140
 
140
141
  # Load the model
@@ -315,6 +316,8 @@ def visualize_detectron2_results(
315
316
  Returns:
316
317
  Visualization image as numpy array
317
318
  """
319
+ import cv2 # Lazy import to avoid QGIS opencv conflicts
320
+
318
321
  check_detectron2()
319
322
 
320
323
  # Load the image
@@ -6,7 +6,6 @@ import time
6
6
  from typing import Any, Dict, Generator, List, Optional, Tuple, Union
7
7
 
8
8
  # Third-Party Libraries
9
- import cv2
10
9
  import geopandas as gpd
11
10
  import matplotlib.pyplot as plt
12
11
  import numpy as np
@@ -440,6 +439,7 @@ class ObjectDetector:
440
439
  Returns:
441
440
  List of polygons as lists of (x, y) coordinates
442
441
  """
442
+ import cv2 # Lazy import to avoid QGIS opencv conflicts
443
443
 
444
444
  # Get parameters from kwargs or use instance defaults
445
445
  simplify_tolerance = kwargs.get("simplify_tolerance", self.simplify_tolerance)
@@ -637,6 +637,8 @@ class ObjectDetector:
637
637
  Returns:
638
638
  GeoDataFrame with objects
639
639
  """
640
+ import cv2 # Lazy import to avoid QGIS opencv conflicts
641
+
640
642
  # Use class defaults if parameters not provided
641
643
  simplify_tolerance = (
642
644
  simplify_tolerance
@@ -1715,21 +1717,21 @@ class ObjectDetector:
1715
1717
  confidence = None
1716
1718
  try:
1717
1719
  confidence = row.confidence
1718
- except:
1720
+ except Exception:
1719
1721
  pass
1720
1722
 
1721
1723
  # Method 2: Try dictionary-style access
1722
1724
  if confidence is None:
1723
1725
  try:
1724
1726
  confidence = row["confidence"]
1725
- except:
1727
+ except Exception:
1726
1728
  pass
1727
1729
 
1728
1730
  # Method 3: Try accessing by index from the GeoDataFrame
1729
1731
  if confidence is None:
1730
1732
  try:
1731
1733
  confidence = gdf.iloc[idx]["confidence"]
1732
- except:
1734
+ except Exception:
1733
1735
  pass
1734
1736
 
1735
1737
  if confidence is not None:
@@ -1877,19 +1879,19 @@ class ObjectDetector:
1877
1879
  confidence = None
1878
1880
  try:
1879
1881
  confidence = row.confidence
1880
- except:
1882
+ except Exception:
1881
1883
  pass
1882
1884
 
1883
1885
  if confidence is None:
1884
1886
  try:
1885
1887
  confidence = row["confidence"]
1886
- except:
1888
+ except Exception:
1887
1889
  pass
1888
1890
 
1889
1891
  if confidence is None:
1890
1892
  try:
1891
1893
  confidence = visible_gdf.iloc[idx]["confidence"]
1892
- except:
1894
+ except Exception:
1893
1895
  pass
1894
1896
 
1895
1897
  if confidence is not None:
@@ -2165,6 +2167,7 @@ class ObjectDetector:
2165
2167
  Returns:
2166
2168
  GeoDataFrame with car detections and confidence values
2167
2169
  """
2170
+ import cv2 # Lazy import to avoid QGIS opencv conflicts
2168
2171
 
2169
2172
  def _process_single_component(
2170
2173
  component_mask: np.ndarray,
@@ -343,7 +343,7 @@ def mask_generation(
343
343
  # Try to convert from tensor or other format if needed
344
344
  try:
345
345
  mask_data = np.array(mask_data)
346
- except:
346
+ except Exception:
347
347
  print(f"Could not convert mask at index {i} to numpy array")
348
348
  continue
349
349
 
@@ -395,7 +395,7 @@ def mask_generation(
395
395
  try:
396
396
  mask_data = np.array(mask_result)
397
397
  score = 1.0 # Default score
398
- except:
398
+ except Exception:
399
399
  print(f"Could not process mask at index {i}")
400
400
  continue
401
401
 
@@ -404,7 +404,7 @@ def mask_generation(
404
404
  if not isinstance(mask_data, np.ndarray):
405
405
  try:
406
406
  mask_data = np.array(mask_data)
407
- except:
407
+ except Exception:
408
408
  print(f"Could not convert mask at index {i} to numpy array")
409
409
  continue
410
410
 
@@ -1305,7 +1305,7 @@ class MoondreamGeo:
1305
1305
  try:
1306
1306
  summary_result = self.model.query(question=summary_prompt)
1307
1307
  combined_answer = summary_result.get("answer", "")
1308
- except:
1308
+ except Exception:
1309
1309
  # Fall back to concatenation if summarization fails
1310
1310
  combined_answer = " ".join([ta["answer"] for ta in tile_answers])
1311
1311
  else:
@@ -1411,7 +1411,7 @@ class MoondreamGeo:
1411
1411
  try:
1412
1412
  summary_result = self.model.query(question=summary_prompt)
1413
1413
  combined_caption = summary_result.get("answer", "")
1414
- except:
1414
+ except Exception:
1415
1415
  # Fall back to concatenation if summarization fails
1416
1416
  combined_caption = " ".join([tc["caption"] for tc in tile_captions])
1417
1417
  else: