segment-geospatial 1.2.1__tar.gz → 1.2.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.
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/.github/workflows/draft-pdf.yml +1 -1
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/.pre-commit-config.yaml +2 -2
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/PKG-INFO +28 -3
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/README.md +26 -1
- segment_geospatial-1.2.3/docs/detectree2.md +3 -0
- segment_geospatial-1.2.3/docs/examples/detectree2.ipynb +376 -0
- segment_geospatial-1.2.3/docs/faq.md +48 -0
- segment_geospatial-1.2.3/docs/installation.md +277 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/mkdocs.yml +2 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/pyproject.toml +3 -3
- segment_geospatial-1.2.3/samgeo/__init__.py +23 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/samgeo/common.py +54 -12
- segment_geospatial-1.2.3/samgeo/detectree2.py +502 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/samgeo/fer.py +2 -2
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/samgeo/samgeo3.py +32 -7
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/samgeo/text_sam.py +1 -1
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/segment_geospatial.egg-info/PKG-INFO +28 -3
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/segment_geospatial.egg-info/SOURCES.txt +3 -0
- segment_geospatial-1.2.1/docs/faq.md +0 -1
- segment_geospatial-1.2.1/docs/installation.md +0 -102
- segment_geospatial-1.2.1/samgeo/__init__.py +0 -10
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/.editorconfig +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/.github/FUNDING.yml +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/.github/dependabot.yaml +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/.github/workflows/docker-image.yml +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/.github/workflows/docker-publish.yml +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/.github/workflows/docs-build.yml +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/.github/workflows/docs.yml +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/.github/workflows/macos.yml +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/.github/workflows/pypi.yml +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/.github/workflows/ubuntu.yml +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/.github/workflows/windows.yml +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/.gitignore +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/CITATION.cff +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/CODE_OF_CONDUCT.md +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/Dockerfile +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/LICENSE +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/MANIFEST.in +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/CNAME +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/assets/README.md +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/assets/favicon.png +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/assets/logo.png +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/assets/logo_rect.png +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/caption.md +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/changelog.md +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/changelog_update.py +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/common.md +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/contributing.md +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/examples/arcgis.ipynb +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/examples/automatic_mask_generator.ipynb +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/examples/automatic_mask_generator_hq.ipynb +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/examples/box_prompts.ipynb +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/examples/data/tree_boxes.geojson +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/examples/fast_sam.ipynb +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/examples/image_captioning.ipynb +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/examples/input_prompts.ipynb +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/examples/input_prompts_hq.ipynb +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/examples/maxar_open_data.ipynb +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/examples/sam2_automatic.ipynb +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/examples/sam2_box_prompts.ipynb +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/examples/sam2_point_prompts.ipynb +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/examples/sam2_predictor.ipynb +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/examples/sam2_text_prompts.ipynb +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/examples/sam2_video.ipynb +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/examples/sam3_automated_segmentation.ipynb +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/examples/sam3_batch_segmentation.ipynb +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/examples/sam3_box_prompts.ipynb +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/examples/sam3_image_segmentation.ipynb +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/examples/sam3_image_segmentation_jpg.ipynb +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/examples/sam3_interactive.ipynb +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/examples/sam3_object_tracking.ipynb +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/examples/sam3_point_prompts.ipynb +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/examples/sam3_point_prompts_batch.ipynb +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/examples/sam3_tiled_segmentation.ipynb +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/examples/sam3_video_masks.ipynb +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/examples/sam3_video_prompts.ipynb +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/examples/sam3_video_segmentation.ipynb +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/examples/satellite-predictor.ipynb +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/examples/satellite.ipynb +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/examples/text_prompts.ipynb +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/examples/text_prompts_batch.ipynb +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/examples/text_swimming_pools.ipynb +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/examples/tree_mapping.ipynb +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/fast_sam.md +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/hq_sam.md +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/index.md +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/overrides/main.html +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/samgeo.md +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/samgeo2.md +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/samgeo3.md +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/text_sam.md +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/usage.md +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/workshops/AIforGood_2025.ipynb +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/workshops/IPPN_2024.ipynb +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/workshops/cn_workshop.ipynb +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/workshops/jupytext.toml +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/docs/workshops/purdue.ipynb +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/paper/10.21105.joss.05663.pdf +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/paper/paper.bib +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/paper/paper.md +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/qgis-samgeo-plugin/LICENSE +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/qgis-samgeo-plugin/README.md +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/qgis-samgeo-plugin/__init__.py +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/qgis-samgeo-plugin/icons/icon.png +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/qgis-samgeo-plugin/install_plugin.py +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/qgis-samgeo-plugin/install_plugin.sh +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/qgis-samgeo-plugin/map_tools.py +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/qgis-samgeo-plugin/metadata.txt +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/qgis-samgeo-plugin/resources.py +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/qgis-samgeo-plugin/samgeo_plugin.py +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/qgis-samgeo-plugin/test_plugin.py +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/requirements.txt +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/requirements_dev.txt +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/requirements_docs.txt +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/samgeo/caption.py +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/samgeo/fast_sam.py +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/samgeo/hq_sam.py +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/samgeo/samgeo.py +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/samgeo/samgeo2.py +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/samgeo/utmconv.py +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/segment_geospatial.egg-info/dependency_links.txt +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/segment_geospatial.egg-info/requires.txt +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/segment_geospatial.egg-info/top_level.txt +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/setup.cfg +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/tests/__init__.py +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/tests/test_common.py +0 -0
- {segment_geospatial-1.2.1 → segment_geospatial-1.2.3}/tests/test_samgeo.py +0 -0
|
@@ -14,7 +14,7 @@ jobs:
|
|
|
14
14
|
# This should be the path to the paper within your repo.
|
|
15
15
|
paper-path: paper/paper.md
|
|
16
16
|
- name: Upload
|
|
17
|
-
uses: actions/upload-artifact@
|
|
17
|
+
uses: actions/upload-artifact@v7
|
|
18
18
|
with:
|
|
19
19
|
name: paper
|
|
20
20
|
# This is the output path where Pandoc will write the compiled
|
|
@@ -12,7 +12,7 @@ repos:
|
|
|
12
12
|
args: ["--maxkb=500"]
|
|
13
13
|
|
|
14
14
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
15
|
-
rev: v0.
|
|
15
|
+
rev: v0.15.2
|
|
16
16
|
hooks:
|
|
17
17
|
- id: ruff
|
|
18
18
|
types_or: [pyi, jupyter]
|
|
@@ -29,6 +29,6 @@ repos:
|
|
|
29
29
|
]
|
|
30
30
|
|
|
31
31
|
- repo: https://github.com/kynan/nbstripout
|
|
32
|
-
rev: 0.
|
|
32
|
+
rev: 0.9.1
|
|
33
33
|
hooks:
|
|
34
34
|
- id: nbstripout
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: segment-geospatial
|
|
3
|
-
Version: 1.2.
|
|
4
|
-
Summary: Meta AI' Segment Anything Model (SAM) for Geospatial Data.
|
|
3
|
+
Version: 1.2.3
|
|
4
|
+
Summary: Meta AI's Segment Anything Model (SAM) for Geospatial Data.
|
|
5
5
|
Author-email: Qiusheng Wu <giswqs@gmail.com>
|
|
6
6
|
License: MIT license
|
|
7
7
|
Project-URL: Homepage, https://github.com/opengeos/segment-geospatial
|
|
@@ -146,6 +146,31 @@ SamGeo is also available as a [QGIS plugin](https://github.com/opengeos/qgis-sam
|
|
|
146
146
|
|
|
147
147
|
## Installation
|
|
148
148
|
|
|
149
|
+
### Install with pixi (Recommended)
|
|
150
|
+
|
|
151
|
+
For the most reliable installation experience, especially on Windows or when dealing with complex dependencies like PyTorch/CUDA and SAM 3, we recommend using [pixi](https://pixi.prefix.dev/latest). Pixi provides faster and more reliable dependency resolution than conda/mamba and avoids common numpy version conflicts. See the [full pixi installation guide](https://samgeo.gishub.org/installation/#install-with-pixi-recommended) for detailed instructions.
|
|
152
|
+
|
|
153
|
+
Quick start with pixi:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
# Install pixi (Linux/macOS)
|
|
157
|
+
curl -fsSL https://pixi.sh/install.sh | sh
|
|
158
|
+
|
|
159
|
+
# Or on Windows (PowerShell)
|
|
160
|
+
powershell -ExecutionPolicy Bypass -c "irm -useb https://pixi.sh/install.ps1 | iex"
|
|
161
|
+
|
|
162
|
+
# Create a new pixi project
|
|
163
|
+
pixi init geo
|
|
164
|
+
cd geo
|
|
165
|
+
|
|
166
|
+
# Edit pixi.toml with your configuration (see docs for GPU/CPU examples)
|
|
167
|
+
# Then install
|
|
168
|
+
pixi install
|
|
169
|
+
|
|
170
|
+
# Start Jupyter Lab
|
|
171
|
+
pixi run jupyter lab
|
|
172
|
+
```
|
|
173
|
+
|
|
149
174
|
### Install from PyPI
|
|
150
175
|
|
|
151
176
|
**segment-geospatial** is available on [PyPI](https://pypi.org/project/segment-geospatial/) and can be installed in several ways so that its dependencies can be controlled more granularly. This reduces package size for CI environments, since not every time all of the models will be used.
|
|
@@ -191,7 +216,7 @@ If your system has a GPU, but the above commands do not install the GPU version
|
|
|
191
216
|
conda install -c conda-forge segment-geospatial "pytorch=*=cuda*"
|
|
192
217
|
```
|
|
193
218
|
|
|
194
|
-
|
|
219
|
+
segment-geospatial has some optional dependencies that are not included in the default conda environment. To install these dependencies, run the following command:
|
|
195
220
|
|
|
196
221
|
```bash
|
|
197
222
|
conda install -c conda-forge groundingdino-py segment-anything-fast
|
|
@@ -47,6 +47,31 @@ SamGeo is also available as a [QGIS plugin](https://github.com/opengeos/qgis-sam
|
|
|
47
47
|
|
|
48
48
|
## Installation
|
|
49
49
|
|
|
50
|
+
### Install with pixi (Recommended)
|
|
51
|
+
|
|
52
|
+
For the most reliable installation experience, especially on Windows or when dealing with complex dependencies like PyTorch/CUDA and SAM 3, we recommend using [pixi](https://pixi.prefix.dev/latest). Pixi provides faster and more reliable dependency resolution than conda/mamba and avoids common numpy version conflicts. See the [full pixi installation guide](https://samgeo.gishub.org/installation/#install-with-pixi-recommended) for detailed instructions.
|
|
53
|
+
|
|
54
|
+
Quick start with pixi:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
# Install pixi (Linux/macOS)
|
|
58
|
+
curl -fsSL https://pixi.sh/install.sh | sh
|
|
59
|
+
|
|
60
|
+
# Or on Windows (PowerShell)
|
|
61
|
+
powershell -ExecutionPolicy Bypass -c "irm -useb https://pixi.sh/install.ps1 | iex"
|
|
62
|
+
|
|
63
|
+
# Create a new pixi project
|
|
64
|
+
pixi init geo
|
|
65
|
+
cd geo
|
|
66
|
+
|
|
67
|
+
# Edit pixi.toml with your configuration (see docs for GPU/CPU examples)
|
|
68
|
+
# Then install
|
|
69
|
+
pixi install
|
|
70
|
+
|
|
71
|
+
# Start Jupyter Lab
|
|
72
|
+
pixi run jupyter lab
|
|
73
|
+
```
|
|
74
|
+
|
|
50
75
|
### Install from PyPI
|
|
51
76
|
|
|
52
77
|
**segment-geospatial** is available on [PyPI](https://pypi.org/project/segment-geospatial/) and can be installed in several ways so that its dependencies can be controlled more granularly. This reduces package size for CI environments, since not every time all of the models will be used.
|
|
@@ -92,7 +117,7 @@ If your system has a GPU, but the above commands do not install the GPU version
|
|
|
92
117
|
conda install -c conda-forge segment-geospatial "pytorch=*=cuda*"
|
|
93
118
|
```
|
|
94
119
|
|
|
95
|
-
|
|
120
|
+
segment-geospatial has some optional dependencies that are not included in the default conda environment. To install these dependencies, run the following command:
|
|
96
121
|
|
|
97
122
|
```bash
|
|
98
123
|
conda install -c conda-forge groundingdino-py segment-anything-fast
|
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
{
|
|
2
|
+
"cells": [
|
|
3
|
+
{
|
|
4
|
+
"cell_type": "markdown",
|
|
5
|
+
"metadata": {},
|
|
6
|
+
"source": [
|
|
7
|
+
"# Tree Crown Delineation with detectree2\n",
|
|
8
|
+
"\n",
|
|
9
|
+
"[](https://colab.research.google.com/github/opengeos/segment-geospatial/blob/main/docs/examples/detectree2.ipynb)\n",
|
|
10
|
+
"\n",
|
|
11
|
+
"This notebook demonstrates how to use the detectree2 module for automatic tree crown delineation in aerial RGB imagery using Mask R-CNN.\n",
|
|
12
|
+
"\n",
|
|
13
|
+
"## Overview\n",
|
|
14
|
+
"\n",
|
|
15
|
+
"[detectree2](https://github.com/PatBall1/detectree2) is a Python package for automatic tree crown delineation based on the Detectron2 implementation of Mask R-CNN. It has been designed to delineate trees in challenging dense tropical forests and has been validated across various forest types.\n",
|
|
16
|
+
"\n",
|
|
17
|
+
"**Reference:**\n",
|
|
18
|
+
"Ball, J.G.C., et al. (2023). Accurate delineation of individual tree crowns in tropical forests from aerial RGB imagery using Mask R-CNN. Remote Sens Ecol Conserv. 9(5):641-655. https://doi.org/10.1002/rse2.332"
|
|
19
|
+
]
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"cell_type": "markdown",
|
|
23
|
+
"metadata": {},
|
|
24
|
+
"source": [
|
|
25
|
+
"## Installation\n",
|
|
26
|
+
"\n",
|
|
27
|
+
"First, install the required packages. detectree2 requires PyTorch and Detectron2 to be installed first."
|
|
28
|
+
]
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"cell_type": "code",
|
|
32
|
+
"execution_count": null,
|
|
33
|
+
"metadata": {},
|
|
34
|
+
"outputs": [],
|
|
35
|
+
"source": [
|
|
36
|
+
"# Install PyTorch (adjust for your CUDA version)\n",
|
|
37
|
+
"# %pip install torch torchvision\n",
|
|
38
|
+
"\n",
|
|
39
|
+
"# Install Detectron2\n",
|
|
40
|
+
"# %pip install 'git+https://github.com/facebookresearch/detectron2.git'\n",
|
|
41
|
+
"\n",
|
|
42
|
+
"# Install detectree2\n",
|
|
43
|
+
"# %pip install git+https://github.com/PatBall1/detectree2.git\n",
|
|
44
|
+
"\n",
|
|
45
|
+
"# Install segment-geospatial\n",
|
|
46
|
+
"# %pip install segment-geospatial"
|
|
47
|
+
]
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"cell_type": "markdown",
|
|
51
|
+
"metadata": {},
|
|
52
|
+
"source": [
|
|
53
|
+
"## Import Libraries"
|
|
54
|
+
]
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"cell_type": "code",
|
|
58
|
+
"execution_count": null,
|
|
59
|
+
"metadata": {},
|
|
60
|
+
"outputs": [],
|
|
61
|
+
"source": [
|
|
62
|
+
"import leafmap\n",
|
|
63
|
+
"from samgeo.detectree2 import (\n",
|
|
64
|
+
" TreeCrownDelineator,\n",
|
|
65
|
+
" list_pretrained_models,\n",
|
|
66
|
+
")"
|
|
67
|
+
]
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"cell_type": "markdown",
|
|
71
|
+
"metadata": {},
|
|
72
|
+
"source": [
|
|
73
|
+
"## List Available Pre-trained Models\n",
|
|
74
|
+
"\n",
|
|
75
|
+
"detectree2 provides several pre-trained models from different forest types:"
|
|
76
|
+
]
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"cell_type": "code",
|
|
80
|
+
"execution_count": null,
|
|
81
|
+
"metadata": {},
|
|
82
|
+
"outputs": [],
|
|
83
|
+
"source": [
|
|
84
|
+
"models = list_pretrained_models()\n",
|
|
85
|
+
"for name, url in models.items():\n",
|
|
86
|
+
" print(f\"{name}: {url}\")"
|
|
87
|
+
]
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"cell_type": "markdown",
|
|
91
|
+
"metadata": {},
|
|
92
|
+
"source": [
|
|
93
|
+
"## Download Sample Image\n",
|
|
94
|
+
"\n",
|
|
95
|
+
"Download a sample tree image for testing:"
|
|
96
|
+
]
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"cell_type": "code",
|
|
100
|
+
"execution_count": null,
|
|
101
|
+
"metadata": {},
|
|
102
|
+
"outputs": [],
|
|
103
|
+
"source": [
|
|
104
|
+
"image_url = (\n",
|
|
105
|
+
" \"https://github.com/opengeos/datasets/releases/download/samgeo/tree_image.tif\"\n",
|
|
106
|
+
")\n",
|
|
107
|
+
"image_path = leafmap.download_file(image_url)"
|
|
108
|
+
]
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"cell_type": "markdown",
|
|
112
|
+
"metadata": {},
|
|
113
|
+
"source": [
|
|
114
|
+
"## Visualize the Sample Image"
|
|
115
|
+
]
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
"cell_type": "code",
|
|
119
|
+
"execution_count": null,
|
|
120
|
+
"metadata": {},
|
|
121
|
+
"outputs": [],
|
|
122
|
+
"source": [
|
|
123
|
+
"m = leafmap.Map()\n",
|
|
124
|
+
"m.add_raster(image_path, layer_name=\"Tree Image\")\n",
|
|
125
|
+
"m"
|
|
126
|
+
]
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"cell_type": "markdown",
|
|
130
|
+
"metadata": {},
|
|
131
|
+
"source": [
|
|
132
|
+
"## Initialize the Tree Crown Delineator\n",
|
|
133
|
+
"\n",
|
|
134
|
+
"Initialize the `TreeCrownDelineator` with a pre-trained model. The model will be automatically downloaded on first use."
|
|
135
|
+
]
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
"cell_type": "code",
|
|
139
|
+
"execution_count": null,
|
|
140
|
+
"metadata": {},
|
|
141
|
+
"outputs": [],
|
|
142
|
+
"source": [
|
|
143
|
+
"delineator = TreeCrownDelineator(\n",
|
|
144
|
+
" model_name=\"default\", # Options: 'paracou', 'sepilok', 'danum', 'default'\n",
|
|
145
|
+
" confidence_threshold=0.5, # Minimum confidence for predictions\n",
|
|
146
|
+
" nms_threshold=0.3, # Non-maximum suppression threshold\n",
|
|
147
|
+
")"
|
|
148
|
+
]
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"cell_type": "markdown",
|
|
152
|
+
"metadata": {},
|
|
153
|
+
"source": [
|
|
154
|
+
"## Predict Tree Crowns\n",
|
|
155
|
+
"\n",
|
|
156
|
+
"Run the prediction on the sample image:"
|
|
157
|
+
]
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
"cell_type": "code",
|
|
161
|
+
"execution_count": null,
|
|
162
|
+
"metadata": {},
|
|
163
|
+
"outputs": [],
|
|
164
|
+
"source": [
|
|
165
|
+
"output_path = \"tree_crowns.gpkg\"\n",
|
|
166
|
+
"\n",
|
|
167
|
+
"crowns = delineator.predict(\n",
|
|
168
|
+
" image_path=image_path,\n",
|
|
169
|
+
" output_path=output_path,\n",
|
|
170
|
+
" tile_width=20, # Tile width in meters\n",
|
|
171
|
+
" tile_height=20, # Tile height in meters\n",
|
|
172
|
+
" buffer=30, # Buffer around tiles in meters\n",
|
|
173
|
+
" simplify_tolerance=0.2, # Simplify crown geometries\n",
|
|
174
|
+
" min_confidence=0.3, # Minimum confidence to keep\n",
|
|
175
|
+
" iou_threshold=0.6, # IoU threshold for removing overlaps\n",
|
|
176
|
+
")"
|
|
177
|
+
]
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
"cell_type": "markdown",
|
|
181
|
+
"metadata": {},
|
|
182
|
+
"source": [
|
|
183
|
+
"## Examine the Results"
|
|
184
|
+
]
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
"cell_type": "code",
|
|
188
|
+
"execution_count": null,
|
|
189
|
+
"metadata": {},
|
|
190
|
+
"outputs": [],
|
|
191
|
+
"source": [
|
|
192
|
+
"print(f\"Detected {len(crowns)} tree crowns\")\n",
|
|
193
|
+
"crowns.head()"
|
|
194
|
+
]
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
"cell_type": "markdown",
|
|
198
|
+
"metadata": {},
|
|
199
|
+
"source": [
|
|
200
|
+
"## Visualize Results on Map\n",
|
|
201
|
+
"\n",
|
|
202
|
+
"Display the detected tree crowns overlaid on the original image:"
|
|
203
|
+
]
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
"cell_type": "code",
|
|
207
|
+
"execution_count": null,
|
|
208
|
+
"metadata": {},
|
|
209
|
+
"outputs": [],
|
|
210
|
+
"source": [
|
|
211
|
+
"m = leafmap.Map()\n",
|
|
212
|
+
"m.add_raster(image_path, layer_name=\"Tree Image\")\n",
|
|
213
|
+
"m.add_vector(\n",
|
|
214
|
+
" output_path,\n",
|
|
215
|
+
" layer_name=\"Tree Crowns\",\n",
|
|
216
|
+
" style={\"color\": \"yellow\", \"fillColor\": \"yellow\", \"fillOpacity\": 0.3, \"weight\": 2},\n",
|
|
217
|
+
")\n",
|
|
218
|
+
"m"
|
|
219
|
+
]
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
"cell_type": "markdown",
|
|
223
|
+
"metadata": {},
|
|
224
|
+
"source": [
|
|
225
|
+
"## Using a Custom Model\n",
|
|
226
|
+
"\n",
|
|
227
|
+
"If you have trained your own model, you can use it instead of the pre-trained models:"
|
|
228
|
+
]
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
"cell_type": "code",
|
|
232
|
+
"execution_count": null,
|
|
233
|
+
"metadata": {},
|
|
234
|
+
"outputs": [],
|
|
235
|
+
"source": [
|
|
236
|
+
"# Initialize with a custom model\n",
|
|
237
|
+
"# delineator = TreeCrownDelineator(\n",
|
|
238
|
+
"# model_path=\"path/to/your/model.pth\",\n",
|
|
239
|
+
"# confidence_threshold=0.5,\n",
|
|
240
|
+
"# )"
|
|
241
|
+
]
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
"cell_type": "markdown",
|
|
245
|
+
"metadata": {},
|
|
246
|
+
"source": [
|
|
247
|
+
"## Tiling Orthomosaics\n",
|
|
248
|
+
"\n",
|
|
249
|
+
"For large orthomosaics, you may want to tile them first before running predictions:"
|
|
250
|
+
]
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
"cell_type": "code",
|
|
254
|
+
"execution_count": null,
|
|
255
|
+
"metadata": {},
|
|
256
|
+
"outputs": [],
|
|
257
|
+
"source": [
|
|
258
|
+
"# Tile an orthomosaic for prediction\n",
|
|
259
|
+
"# tiles_dir = tile_orthomosaic(\n",
|
|
260
|
+
"# image_path=\"path/to/orthomosaic.tif\",\n",
|
|
261
|
+
"# output_dir=\"./tiles\",\n",
|
|
262
|
+
"# tile_width=40,\n",
|
|
263
|
+
"# tile_height=40,\n",
|
|
264
|
+
"# buffer=30,\n",
|
|
265
|
+
"# mode=\"rgb\", # Use 'ms' for multispectral imagery\n",
|
|
266
|
+
"# )"
|
|
267
|
+
]
|
|
268
|
+
},
|
|
269
|
+
{
|
|
270
|
+
"cell_type": "markdown",
|
|
271
|
+
"metadata": {},
|
|
272
|
+
"source": [
|
|
273
|
+
"## Preparing Training Data\n",
|
|
274
|
+
"\n",
|
|
275
|
+
"If you want to train a custom model, you'll need to prepare your training data with manually delineated crown polygons:"
|
|
276
|
+
]
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
"cell_type": "code",
|
|
280
|
+
"execution_count": null,
|
|
281
|
+
"metadata": {},
|
|
282
|
+
"outputs": [],
|
|
283
|
+
"source": [
|
|
284
|
+
"# Prepare training and test data\n",
|
|
285
|
+
"# train_dir, test_dir = prepare_training_data(\n",
|
|
286
|
+
"# image_path=\"path/to/orthomosaic.tif\",\n",
|
|
287
|
+
"# crowns_path=\"path/to/manual_crowns.gpkg\",\n",
|
|
288
|
+
"# output_dir=\"./training_data\",\n",
|
|
289
|
+
"# tile_width=40,\n",
|
|
290
|
+
"# tile_height=40,\n",
|
|
291
|
+
"# buffer=30,\n",
|
|
292
|
+
"# threshold=0.6, # Minimum crown coverage per tile\n",
|
|
293
|
+
"# test_fraction=0.15, # Fraction for testing\n",
|
|
294
|
+
"# )"
|
|
295
|
+
]
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
"cell_type": "markdown",
|
|
299
|
+
"metadata": {},
|
|
300
|
+
"source": [
|
|
301
|
+
"## Stitching Predictions\n",
|
|
302
|
+
"\n",
|
|
303
|
+
"After running predictions on tiles, you can stitch them together:"
|
|
304
|
+
]
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
"cell_type": "code",
|
|
308
|
+
"execution_count": null,
|
|
309
|
+
"metadata": {},
|
|
310
|
+
"outputs": [],
|
|
311
|
+
"source": [
|
|
312
|
+
"# Stitch tile predictions into a single crown map\n",
|
|
313
|
+
"# crowns = stitch_predictions(\n",
|
|
314
|
+
"# geo_predictions_dir=\"./predictions_geo\",\n",
|
|
315
|
+
"# output_path=\"final_crowns.gpkg\",\n",
|
|
316
|
+
"# iou_threshold=0.6,\n",
|
|
317
|
+
"# min_confidence=0.5,\n",
|
|
318
|
+
"# simplify_tolerance=0.3,\n",
|
|
319
|
+
"# )"
|
|
320
|
+
]
|
|
321
|
+
},
|
|
322
|
+
{
|
|
323
|
+
"cell_type": "markdown",
|
|
324
|
+
"metadata": {},
|
|
325
|
+
"source": [
|
|
326
|
+
"## Tips for Best Results\n",
|
|
327
|
+
"\n",
|
|
328
|
+
"1. **Image Resolution**: detectree2 works best with high-resolution imagery (10cm or better).\n",
|
|
329
|
+
"\n",
|
|
330
|
+
"2. **Tile Size**: The default tile size of 40x40 meters works well for most applications. Adjust based on your tree sizes.\n",
|
|
331
|
+
"\n",
|
|
332
|
+
"3. **Buffer Size**: A buffer of 30 meters helps handle trees at tile edges.\n",
|
|
333
|
+
"\n",
|
|
334
|
+
"4. **Confidence Threshold**: Start with 0.5 and adjust based on your precision/recall needs.\n",
|
|
335
|
+
"\n",
|
|
336
|
+
"5. **Training Data**: If training custom models, ensure your manual crowns are:\n",
|
|
337
|
+
" - Densely clustered (not scattered)\n",
|
|
338
|
+
" - Comprehensively labeled (no missing trees in labeled areas)\n",
|
|
339
|
+
" - Accurately delineated\n",
|
|
340
|
+
"\n",
|
|
341
|
+
"6. **GPU**: For faster predictions, use a CUDA-enabled GPU."
|
|
342
|
+
]
|
|
343
|
+
},
|
|
344
|
+
{
|
|
345
|
+
"cell_type": "markdown",
|
|
346
|
+
"metadata": {},
|
|
347
|
+
"source": [
|
|
348
|
+
"## References\n",
|
|
349
|
+
"\n",
|
|
350
|
+
"- [detectree2 GitHub Repository](https://github.com/PatBall1/detectree2)\n",
|
|
351
|
+
"- [detectree2 Documentation](https://patball1.github.io/detectree2/)\n",
|
|
352
|
+
"- [Pre-trained Models (Model Garden)](https://github.com/PatBall1/detectree2/tree/master/model_garden)\n",
|
|
353
|
+
"- [Sample Data](https://zenodo.org/records/8136161)"
|
|
354
|
+
]
|
|
355
|
+
}
|
|
356
|
+
],
|
|
357
|
+
"metadata": {
|
|
358
|
+
"kernelspec": {
|
|
359
|
+
"display_name": "Python 3",
|
|
360
|
+
"language": "python",
|
|
361
|
+
"name": "python3"
|
|
362
|
+
},
|
|
363
|
+
"language_info": {
|
|
364
|
+
"codemirror_mode": {
|
|
365
|
+
"name": "ipython",
|
|
366
|
+
"version": 3
|
|
367
|
+
},
|
|
368
|
+
"file_extension": ".py",
|
|
369
|
+
"mimetype": "text/x-python",
|
|
370
|
+
"name": "python",
|
|
371
|
+
"version": "3.11.0"
|
|
372
|
+
}
|
|
373
|
+
},
|
|
374
|
+
"nbformat": 4,
|
|
375
|
+
"nbformat_minor": 4
|
|
376
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Frequently Asked Questions (FAQ)
|
|
2
|
+
|
|
3
|
+
## Coordinate Reference Systems (CRS)
|
|
4
|
+
|
|
5
|
+
### Does samgeo automatically convert my imagery to EPSG:4326?
|
|
6
|
+
|
|
7
|
+
**No.** samgeo does **NOT** automatically reproject or convert your GeoTIFF files to EPSG:4326. Your imagery stays in its native coordinate system throughout the entire segmentation process.
|
|
8
|
+
|
|
9
|
+
**Key points:**
|
|
10
|
+
- When you load a GeoTIFF with `set_image()` or use `generate_masks_tiled()`, the image data is read directly without any CRS transformation
|
|
11
|
+
- The output masks inherit the same CRS as your input imagery
|
|
12
|
+
- The `reproject()` function in `samgeo.common` has EPSG:4326 as a default parameter, but it's **only used when you explicitly call that function** - it is NOT called automatically during segmentation
|
|
13
|
+
|
|
14
|
+
**Why might you see distortion?**
|
|
15
|
+
1. Your visualization tool is displaying the results in EPSG:4326 (like some web map libraries)
|
|
16
|
+
2. You're manually calling the `reproject()` function somewhere in your workflow
|
|
17
|
+
3. Your original imagery already has CRS-related issues
|
|
18
|
+
|
|
19
|
+
**Recommendation:**
|
|
20
|
+
- Verify your input TIF has the correct CRS metadata using `gdalinfo` or rasterio (`src.crs`)
|
|
21
|
+
- The output masks will preserve the same CRS as your input
|
|
22
|
+
- If you need to reproject for visualization, do it as a separate step AFTER segmentation:
|
|
23
|
+
```python
|
|
24
|
+
from samgeo import common
|
|
25
|
+
common.reproject("input_masks.tif", "output_epsg4326.tif", dst_crs="EPSG:4326")
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### How can I check the CRS of my GeoTIFF?
|
|
29
|
+
|
|
30
|
+
Using GDAL:
|
|
31
|
+
```bash
|
|
32
|
+
gdalinfo your_file.tif
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Using Python with rasterio:
|
|
36
|
+
```python
|
|
37
|
+
import rasterio
|
|
38
|
+
with rasterio.open("your_file.tif") as src:
|
|
39
|
+
print(f"CRS: {src.crs}")
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### My imagery looks distorted during segmentation
|
|
43
|
+
|
|
44
|
+
The segmentation algorithm works on pixel values, not geographic coordinates, so CRS should not affect segmentation quality. If you're seeing distortion:
|
|
45
|
+
|
|
46
|
+
1. **Check if it's a visualization issue:** The distortion might only appear when viewing results in a different CRS
|
|
47
|
+
2. **Verify your input data:** Use `gdalinfo` to check if the CRS metadata is correct
|
|
48
|
+
3. **Try reprojecting to a more suitable CRS:** Some projections preserve shape better than others for specific regions (e.g., UTM for local areas)
|