segment-geospatial 1.2.2__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.2 → segment_geospatial-1.2.3}/.github/workflows/draft-pdf.yml +1 -1
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/.pre-commit-config.yaml +2 -2
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/PKG-INFO +1 -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.2 → segment_geospatial-1.2.3}/mkdocs.yml +2 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/pyproject.toml +2 -2
- segment_geospatial-1.2.3/samgeo/__init__.py +23 -0
- segment_geospatial-1.2.3/samgeo/detectree2.py +502 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/samgeo/samgeo3.py +11 -1
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/segment_geospatial.egg-info/PKG-INFO +1 -1
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/segment_geospatial.egg-info/SOURCES.txt +3 -0
- segment_geospatial-1.2.2/samgeo/__init__.py +0 -10
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/.editorconfig +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/.github/FUNDING.yml +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/.github/dependabot.yaml +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/.github/workflows/docker-image.yml +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/.github/workflows/docker-publish.yml +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/.github/workflows/docs-build.yml +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/.github/workflows/docs.yml +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/.github/workflows/macos.yml +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/.github/workflows/pypi.yml +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/.github/workflows/ubuntu.yml +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/.github/workflows/windows.yml +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/.gitignore +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/CITATION.cff +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/CODE_OF_CONDUCT.md +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/Dockerfile +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/LICENSE +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/MANIFEST.in +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/README.md +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/CNAME +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/assets/README.md +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/assets/favicon.png +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/assets/logo.png +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/assets/logo_rect.png +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/caption.md +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/changelog.md +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/changelog_update.py +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/common.md +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/contributing.md +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/examples/arcgis.ipynb +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/examples/automatic_mask_generator.ipynb +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/examples/automatic_mask_generator_hq.ipynb +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/examples/box_prompts.ipynb +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/examples/data/tree_boxes.geojson +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/examples/fast_sam.ipynb +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/examples/image_captioning.ipynb +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/examples/input_prompts.ipynb +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/examples/input_prompts_hq.ipynb +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/examples/maxar_open_data.ipynb +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/examples/sam2_automatic.ipynb +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/examples/sam2_box_prompts.ipynb +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/examples/sam2_point_prompts.ipynb +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/examples/sam2_predictor.ipynb +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/examples/sam2_text_prompts.ipynb +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/examples/sam2_video.ipynb +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/examples/sam3_automated_segmentation.ipynb +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/examples/sam3_batch_segmentation.ipynb +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/examples/sam3_box_prompts.ipynb +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/examples/sam3_image_segmentation.ipynb +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/examples/sam3_image_segmentation_jpg.ipynb +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/examples/sam3_interactive.ipynb +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/examples/sam3_object_tracking.ipynb +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/examples/sam3_point_prompts.ipynb +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/examples/sam3_point_prompts_batch.ipynb +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/examples/sam3_tiled_segmentation.ipynb +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/examples/sam3_video_masks.ipynb +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/examples/sam3_video_prompts.ipynb +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/examples/sam3_video_segmentation.ipynb +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/examples/satellite-predictor.ipynb +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/examples/satellite.ipynb +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/examples/text_prompts.ipynb +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/examples/text_prompts_batch.ipynb +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/examples/text_swimming_pools.ipynb +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/examples/tree_mapping.ipynb +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/faq.md +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/fast_sam.md +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/hq_sam.md +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/index.md +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/installation.md +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/overrides/main.html +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/samgeo.md +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/samgeo2.md +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/samgeo3.md +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/text_sam.md +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/usage.md +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/workshops/AIforGood_2025.ipynb +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/workshops/IPPN_2024.ipynb +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/workshops/cn_workshop.ipynb +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/workshops/jupytext.toml +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/docs/workshops/purdue.ipynb +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/paper/10.21105.joss.05663.pdf +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/paper/paper.bib +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/paper/paper.md +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/qgis-samgeo-plugin/LICENSE +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/qgis-samgeo-plugin/README.md +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/qgis-samgeo-plugin/__init__.py +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/qgis-samgeo-plugin/icons/icon.png +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/qgis-samgeo-plugin/install_plugin.py +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/qgis-samgeo-plugin/install_plugin.sh +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/qgis-samgeo-plugin/map_tools.py +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/qgis-samgeo-plugin/metadata.txt +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/qgis-samgeo-plugin/resources.py +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/qgis-samgeo-plugin/samgeo_plugin.py +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/qgis-samgeo-plugin/test_plugin.py +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/requirements.txt +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/requirements_dev.txt +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/requirements_docs.txt +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/samgeo/caption.py +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/samgeo/common.py +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/samgeo/fast_sam.py +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/samgeo/fer.py +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/samgeo/hq_sam.py +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/samgeo/samgeo.py +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/samgeo/samgeo2.py +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/samgeo/text_sam.py +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/samgeo/utmconv.py +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/segment_geospatial.egg-info/dependency_links.txt +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/segment_geospatial.egg-info/requires.txt +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/segment_geospatial.egg-info/top_level.txt +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/setup.cfg +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/tests/__init__.py +0 -0
- {segment_geospatial-1.2.2 → segment_geospatial-1.2.3}/tests/test_common.py +0 -0
- {segment_geospatial-1.2.2 → 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.9.
|
|
32
|
+
rev: 0.9.1
|
|
33
33
|
hooks:
|
|
34
34
|
- id: nbstripout
|
|
@@ -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
|
+
}
|
|
@@ -82,6 +82,7 @@ nav:
|
|
|
82
82
|
- examples/sam3_point_prompts_batch.ipynb
|
|
83
83
|
- examples/sam3_box_prompts.ipynb
|
|
84
84
|
- examples/sam3_tiled_segmentation.ipynb
|
|
85
|
+
- examples/detectree2.ipynb
|
|
85
86
|
- Workshops:
|
|
86
87
|
- workshops/purdue.ipynb
|
|
87
88
|
- workshops/cn_workshop.ipynb
|
|
@@ -96,4 +97,5 @@ nav:
|
|
|
96
97
|
- fast_sam module: fast_sam.md
|
|
97
98
|
- hq_sam module: hq_sam.md
|
|
98
99
|
- text_sam module: text_sam.md
|
|
100
|
+
- detectree2 module: detectree2.md
|
|
99
101
|
# - fer module: fer.md
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "segment-geospatial"
|
|
7
|
-
version = "1.2.
|
|
7
|
+
version = "1.2.3"
|
|
8
8
|
dynamic = [
|
|
9
9
|
"dependencies",
|
|
10
10
|
]
|
|
@@ -111,7 +111,7 @@ dependencies = {file = ["requirements.txt"]}
|
|
|
111
111
|
universal = true
|
|
112
112
|
|
|
113
113
|
[tool.bumpversion]
|
|
114
|
-
current_version = "1.2.
|
|
114
|
+
current_version = "1.2.3"
|
|
115
115
|
commit = true
|
|
116
116
|
tag = true
|
|
117
117
|
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""Top-level package for segment-geospatial."""
|
|
2
|
+
|
|
3
|
+
__author__ = """Qiusheng Wu"""
|
|
4
|
+
__email__ = "giswqs@gmail.com"
|
|
5
|
+
__version__ = "1.2.3"
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
from .samgeo import * # noqa: F403
|
|
9
|
+
from .samgeo2 import * # noqa: F403
|
|
10
|
+
from .samgeo3 import * # noqa: F403
|
|
11
|
+
|
|
12
|
+
# Optional detectree2 support for tree crown delineation
|
|
13
|
+
try:
|
|
14
|
+
from .detectree2 import (
|
|
15
|
+
TreeCrownDelineator,
|
|
16
|
+
tile_orthomosaic,
|
|
17
|
+
prepare_training_data,
|
|
18
|
+
stitch_predictions,
|
|
19
|
+
list_pretrained_models,
|
|
20
|
+
download_sample_data,
|
|
21
|
+
)
|
|
22
|
+
except ImportError:
|
|
23
|
+
pass # detectree2 not installed
|