opencropphenotyping 0.2.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.
- opencropphenotyping-0.2.0/LICENSE +21 -0
- opencropphenotyping-0.2.0/PKG-INFO +695 -0
- opencropphenotyping-0.2.0/README.md +671 -0
- opencropphenotyping-0.2.0/pyproject.toml +53 -0
- opencropphenotyping-0.2.0/setup.cfg +4 -0
- opencropphenotyping-0.2.0/src/opencropphenotyping/batch_processing.py +128 -0
- opencropphenotyping-0.2.0/src/opencropphenotyping/cli.py +218 -0
- opencropphenotyping-0.2.0/src/opencropphenotyping/coco.py +175 -0
- opencropphenotyping-0.2.0/src/opencropphenotyping/evaluation.py +352 -0
- opencropphenotyping-0.2.0/src/opencropphenotyping/indices.py +253 -0
- opencropphenotyping-0.2.0/src/opencropphenotyping/io.py +540 -0
- opencropphenotyping-0.2.0/src/opencropphenotyping/pipeline.py +393 -0
- opencropphenotyping-0.2.0/src/opencropphenotyping/segmentation.py +1320 -0
- opencropphenotyping-0.2.0/src/opencropphenotyping/statistics.py +17 -0
- opencropphenotyping-0.2.0/src/opencropphenotyping/traits.py +60 -0
- opencropphenotyping-0.2.0/src/opencropphenotyping/visualization.py +467 -0
- opencropphenotyping-0.2.0/src/opencropphenotyping.egg-info/PKG-INFO +695 -0
- opencropphenotyping-0.2.0/src/opencropphenotyping.egg-info/SOURCES.txt +32 -0
- opencropphenotyping-0.2.0/src/opencropphenotyping.egg-info/dependency_links.txt +1 -0
- opencropphenotyping-0.2.0/src/opencropphenotyping.egg-info/entry_points.txt +2 -0
- opencropphenotyping-0.2.0/src/opencropphenotyping.egg-info/requires.txt +15 -0
- opencropphenotyping-0.2.0/src/opencropphenotyping.egg-info/top_level.txt +1 -0
- opencropphenotyping-0.2.0/tests/test_batch_processing.py +217 -0
- opencropphenotyping-0.2.0/tests/test_cli.py +359 -0
- opencropphenotyping-0.2.0/tests/test_coco.py +289 -0
- opencropphenotyping-0.2.0/tests/test_evaluation.py +341 -0
- opencropphenotyping-0.2.0/tests/test_indices.py +425 -0
- opencropphenotyping-0.2.0/tests/test_io.py +570 -0
- opencropphenotyping-0.2.0/tests/test_pipeline.py +564 -0
- opencropphenotyping-0.2.0/tests/test_segmentation.py +1464 -0
- opencropphenotyping-0.2.0/tests/test_statistics.py +52 -0
- opencropphenotyping-0.2.0/tests/test_toy_dataset.py +37 -0
- opencropphenotyping-0.2.0/tests/test_traits.py +82 -0
- opencropphenotyping-0.2.0/tests/test_visualization.py +105 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Aurelien-Peter
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,695 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: opencropphenotyping
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Open-source tools for crop phenotyping using multispectral geospatial imagery
|
|
5
|
+
Author: Aurélien Peter
|
|
6
|
+
Requires-Python: >=3.11
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Requires-Dist: numpy
|
|
10
|
+
Requires-Dist: pandas
|
|
11
|
+
Requires-Dist: scipy
|
|
12
|
+
Requires-Dist: rasterio
|
|
13
|
+
Requires-Dist: geopandas
|
|
14
|
+
Requires-Dist: matplotlib
|
|
15
|
+
Requires-Dist: pillow
|
|
16
|
+
Requires-Dist: typer
|
|
17
|
+
Provides-Extra: dev
|
|
18
|
+
Requires-Dist: pytest; extra == "dev"
|
|
19
|
+
Requires-Dist: pytest-cov; extra == "dev"
|
|
20
|
+
Requires-Dist: ruff; extra == "dev"
|
|
21
|
+
Requires-Dist: jupyter; extra == "dev"
|
|
22
|
+
Requires-Dist: plotly; extra == "dev"
|
|
23
|
+
Dynamic: license-file
|
|
24
|
+
|
|
25
|
+
# OpenCropPhenotyping
|
|
26
|
+
|
|
27
|
+
[](https://github.com/Aurelien-Peter/OpenCropPhenotyping/actions/workflows/ci.yml)
|
|
28
|
+
[](https://codecov.io/github/Aurelien-Peter/OpenCropPhenotyping)
|
|
29
|
+
|
|
30
|
+
**An open-source Python framework for high-throughput crop phenotyping using drone and satellite imagery.**
|
|
31
|
+
|
|
32
|
+
## About the project
|
|
33
|
+
|
|
34
|
+
OpenCropPhenotyping is an open-source project dedicated to reproducible high-throughput crop phenotyping using remote sensing data.
|
|
35
|
+
The objective is to provide reproducible workflows to extract agronomic traits from UAV and Sentinel-2 imagery, from raw image preprocessing to trait extraction, statistical analysis and visualization.
|
|
36
|
+
The project currently combines multispectral Sentinel-2 processing with classical RGB UAV image analysis. The first UAV developments focus on crop-row detection, vegetation segmentation and plant-position analysis, with the objective of progressively extending the framework toward more advanced high-throughput phenotyping workflows.
|
|
37
|
+
|
|
38
|
+
## Current Features:
|
|
39
|
+
**Sentinel-2**
|
|
40
|
+
- [X] Sentinel-2 imagery reading
|
|
41
|
+
- [X] Sentinel-2 band selection and resampling
|
|
42
|
+
- [X] NDVI computation
|
|
43
|
+
- [X] NDRE computation
|
|
44
|
+
- [X] GNDVI computation
|
|
45
|
+
- [X] SAVI computation
|
|
46
|
+
- [X] Generic vegetation index computation
|
|
47
|
+
- [X] Vegetation masking
|
|
48
|
+
- [X] Crop cover estimation
|
|
49
|
+
- [X] Statistical analysis
|
|
50
|
+
- [X] Sentinel-2 processing pipeline
|
|
51
|
+
- [X] Processing results export
|
|
52
|
+
- [X] Batch processing of multiple Sentinel-2 products
|
|
53
|
+
- [X] Visualization
|
|
54
|
+
- [X] Unit Tests
|
|
55
|
+
- [X] Command-Line Interface (CLI)
|
|
56
|
+
|
|
57
|
+
**UAV RGB**
|
|
58
|
+
- [X] RGB UAV imagery reading
|
|
59
|
+
- [X] RGB vegetation indices
|
|
60
|
+
- [X] Vegetation segmentation
|
|
61
|
+
- [X] Crop-row orientation estimation
|
|
62
|
+
- [X] Crop-row detection
|
|
63
|
+
- [X] Crop-row boundary detection
|
|
64
|
+
- [X] Planting position estimation from plot geometry
|
|
65
|
+
- [X] Vegetation based plant occupancy estimation
|
|
66
|
+
- [X] Georeferenced UAV Image support
|
|
67
|
+
- [X] Experimental plot metadata integration
|
|
68
|
+
- [X] UAV RGB workflow demonstration
|
|
69
|
+
|
|
70
|
+
**Software quality**
|
|
71
|
+
- [X] Visualization utilities
|
|
72
|
+
- [X] Unit tests
|
|
73
|
+
- [X] Code quality checks with Ruff
|
|
74
|
+
- [X] Reproducible toy datasets
|
|
75
|
+
|
|
76
|
+
## Case studies
|
|
77
|
+
|
|
78
|
+
The project includes reproducible case studies based on real agricultural areas in Southern France.
|
|
79
|
+
|
|
80
|
+
Current case studies:
|
|
81
|
+
|
|
82
|
+
- Maize monitoring with Sentinel-2 (Occitanie)
|
|
83
|
+
- UAV RGB crop-row and plant-position analysis on a toy dataset
|
|
84
|
+
|
|
85
|
+
## Roadmap
|
|
86
|
+
|
|
87
|
+
### Version 0.1
|
|
88
|
+
#### Sentinel-2
|
|
89
|
+
|
|
90
|
+
- Read Sentinel-2 imagery
|
|
91
|
+
- NDVI computation
|
|
92
|
+
- Visualization
|
|
93
|
+
- GeoTIFF export
|
|
94
|
+
- PNG export
|
|
95
|
+
- Toy dataset
|
|
96
|
+
- Unit tests
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
### Version 0.2
|
|
101
|
+
#### Vegetation indices and processing pipeline
|
|
102
|
+
|
|
103
|
+
- NDRE computation
|
|
104
|
+
- SAVI computation
|
|
105
|
+
- GNDVI computation
|
|
106
|
+
- Generic vegetation index computation
|
|
107
|
+
- Statistics
|
|
108
|
+
- Vegetation masking
|
|
109
|
+
- Trait Extraction (Crop cover)
|
|
110
|
+
- Sentinel-2 processing pipeline
|
|
111
|
+
- Processing results export
|
|
112
|
+
- Batch processing
|
|
113
|
+
- Command-line interface (CLI)
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
### Version 0.3
|
|
118
|
+
#### Drone imagery
|
|
119
|
+
|
|
120
|
+
- RGB UAV imagery reading
|
|
121
|
+
- RGB vegetation indices
|
|
122
|
+
- Vegetation segmentation
|
|
123
|
+
- Crop-row orientation estimation
|
|
124
|
+
- Crop-row detection
|
|
125
|
+
- Plant-position estimation
|
|
126
|
+
- Experimental plot geometry integration
|
|
127
|
+
- Georeferenced UAV image support
|
|
128
|
+
- UAV image tiling
|
|
129
|
+
- Batch processing of large UAV images
|
|
130
|
+
|
|
131
|
+
Current v0.3 development includes a classical, interpretable workflow for crop-row and plant-position analysis. Plant occupancy estimation currently relies on vegetation fraction within theoretical planting positions and is sensitive to plant development stage and image quality.
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
### Version 0.4
|
|
136
|
+
#### Machine Learning
|
|
137
|
+
|
|
138
|
+
- Feature extraction
|
|
139
|
+
- Dataset preparation
|
|
140
|
+
- Classical classifiers (Random Forest, SVM)
|
|
141
|
+
- Crop classification
|
|
142
|
+
- Model evaluation
|
|
143
|
+
- Model persistence
|
|
144
|
+
|
|
145
|
+
### Version 0.5
|
|
146
|
+
#### Deep Learning
|
|
147
|
+
|
|
148
|
+
- PyTorch support
|
|
149
|
+
- CNN semantic segmentation
|
|
150
|
+
- U-Net implementation
|
|
151
|
+
- Training pipeline
|
|
152
|
+
- Inference pipeline
|
|
153
|
+
- Model visualization
|
|
154
|
+
|
|
155
|
+
### Version 1.0
|
|
156
|
+
|
|
157
|
+
Complete crop phenotyping workflow
|
|
158
|
+
|
|
159
|
+
## For which users?
|
|
160
|
+
|
|
161
|
+
This project is intended for researchers, agronomists, engineers working in remote sensing, as well as for UAV practitioners and interested students.
|
|
162
|
+
The project is also suitable for anyone wishing to learn how to process drone or Sentinel-2 imagery using Python.
|
|
163
|
+
|
|
164
|
+
## Installation
|
|
165
|
+
|
|
166
|
+
git clone ...
|
|
167
|
+
|
|
168
|
+
cd OpenCropPhenotyping
|
|
169
|
+
|
|
170
|
+
conda env create -f environment.yml
|
|
171
|
+
|
|
172
|
+
conda activate opencropphenotyping
|
|
173
|
+
|
|
174
|
+
pip install -e .
|
|
175
|
+
|
|
176
|
+
## How to use
|
|
177
|
+
|
|
178
|
+
The repository already includes a small Sentinel-2 toy dataset.
|
|
179
|
+
|
|
180
|
+
No additional data download is required to run the examples
|
|
181
|
+
|
|
182
|
+
## Command-line interface
|
|
183
|
+
|
|
184
|
+
OpenCropPhenotyping provides a command-line interface to process Sentinel-2 products directly from a terminal.
|
|
185
|
+
|
|
186
|
+
After installing the package, the opencropphenotyping command provides two main operations:
|
|
187
|
+
|
|
188
|
+
- process: process a single Sentinel-2 product.
|
|
189
|
+
- batch: process multiple Sentinel-2 products contained in a directory.
|
|
190
|
+
|
|
191
|
+
### Process a single product
|
|
192
|
+
|
|
193
|
+
```python
|
|
194
|
+
opencropphenotyping process \
|
|
195
|
+
--input-dir path/to/Sentinel2_product \
|
|
196
|
+
--output-dir path/to/results \
|
|
197
|
+
--processed-dir path/to/processed \
|
|
198
|
+
--indices ndvi \
|
|
199
|
+
--ndvi-threshold 0.3 \
|
|
200
|
+
--resolution 10
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
The command processes the Sentinel-2 product, computes the requested vegetation indices, generates the vegetation mask and crop-cover statistics, and exports the results.
|
|
204
|
+
|
|
205
|
+
### Process multiple products
|
|
206
|
+
|
|
207
|
+
```python
|
|
208
|
+
opencropphenotyping batch \
|
|
209
|
+
--input-dir path/to/sentinel2_products \
|
|
210
|
+
--output-dir path/to/results \
|
|
211
|
+
--processed-dir path/to/processed \
|
|
212
|
+
--indices ndvi \
|
|
213
|
+
--ndvi-threshold 0.3 \
|
|
214
|
+
--resolution 10
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
The input directory should contain one Sentinel-2 product per subdirectory. Each product is processed independently and its results are stored in a dedicated subdirectory.
|
|
218
|
+
|
|
219
|
+
For example:
|
|
220
|
+
|
|
221
|
+
input/
|
|
222
|
+
├── S2A_MSIL2A_product_1.SAFE/
|
|
223
|
+
└── S2B_MSIL2A_product_2.SAFE/
|
|
224
|
+
|
|
225
|
+
produces:
|
|
226
|
+
|
|
227
|
+
results/
|
|
228
|
+
├── S2A_MSIL2A_product_1.SAFE/
|
|
229
|
+
└── S2B_MSIL2A_product_2.SAFE/
|
|
230
|
+
|
|
231
|
+
### Get help
|
|
232
|
+
|
|
233
|
+
General help is available with:
|
|
234
|
+
|
|
235
|
+
```python
|
|
236
|
+
opencropphenotyping --help
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Help for an individual command can be obtained with:
|
|
240
|
+
|
|
241
|
+
```python
|
|
242
|
+
opencropphenotyping process --help
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
```python
|
|
246
|
+
opencropphenotyping batch --help
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
```python
|
|
250
|
+
opencropphenotyping segment_uav --help
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
```python
|
|
254
|
+
opencropphenotyping process_uav_segmentation --help
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
If an error occurs while processing a product, the CLI reports the error and exits with a non-zero status code.
|
|
258
|
+
|
|
259
|
+
## Example workflow
|
|
260
|
+
|
|
261
|
+
OpenCropPhenotyping currently provides two complementary image-processing workflows:
|
|
262
|
+
|
|
263
|
+
- Sentinel-2 multispectral processing
|
|
264
|
+
- UAV RGB crop-row and plant-position analysis
|
|
265
|
+
|
|
266
|
+
## Sentinel-2 workflow
|
|
267
|
+
|
|
268
|
+
The Sentinel-2 workflow processes multispectral bands to compute vegetation indices, derive vegetation masks and estimate crop cover.
|
|
269
|
+
|
|
270
|
+
### Sentinel-2 input bands
|
|
271
|
+
|
|
272
|
+
#### Sentinel-2 Red band (B04)
|
|
273
|
+
|
|
274
|
+

|
|
275
|
+
|
|
276
|
+
#### Sentinel-2 Near Infra Red band (B08)
|
|
277
|
+
|
|
278
|
+

|
|
279
|
+
|
|
280
|
+
#### Green band (B03)
|
|
281
|
+
|
|
282
|
+

|
|
283
|
+
|
|
284
|
+
#### Red Edge band (B05)
|
|
285
|
+
|
|
286
|
+

|
|
287
|
+
|
|
288
|
+
↓
|
|
289
|
+
|
|
290
|
+
### Vegetation indices
|
|
291
|
+
|
|
292
|
+
The selected Sentinel-2 bands are combined to compute several vegetation indices:
|
|
293
|
+
|
|
294
|
+
B04 Red ───────┬──→ NDVI
|
|
295
|
+
                  └──→ SAVI
|
|
296
|
+
|
|
297
|
+
B08 NIR ───────┬──→ NDVI
|
|
298
|
+
                  ├──→ SAVI
|
|
299
|
+
                  ├──→ GNDVI
|
|
300
|
+
                  └──→ NDRE
|
|
301
|
+
|
|
302
|
+
B03 Green ────────→ GNDVI
|
|
303
|
+
|
|
304
|
+
B05 Red Edge ──────→ NDRE
|
|
305
|
+
|
|
306
|
+
#### NDVI — Normalized Difference Vegetation Index
|
|
307
|
+
|
|
308
|
+

|
|
309
|
+
|
|
310
|
+
#### NDRE — Normalized Difference Red Edge Index
|
|
311
|
+
|
|
312
|
+

|
|
313
|
+
|
|
314
|
+
#### GNDVI — Green Normalized Difference Vegetation Index
|
|
315
|
+
|
|
316
|
+

|
|
317
|
+
|
|
318
|
+
#### SAVI — Soil-Adjusted Vegetation Index
|
|
319
|
+
|
|
320
|
+

|
|
321
|
+
|
|
322
|
+
↓
|
|
323
|
+
|
|
324
|
+
### Statistics and visualization
|
|
325
|
+
|
|
326
|
+
Statistics are computed for each vegetation index to characterize the distribution of pixel values.
|
|
327
|
+
|
|
328
|
+
#### NDVI distribution
|
|
329
|
+
|
|
330
|
+

|
|
331
|
+
|
|
332
|
+
#### NDVI boxplot
|
|
333
|
+
|
|
334
|
+

|
|
335
|
+
|
|
336
|
+
↓
|
|
337
|
+
|
|
338
|
+
### Trait extraction
|
|
339
|
+
|
|
340
|
+
The NDVI image is used to create a vegetation mask and estimate crop cover.
|
|
341
|
+
|
|
342
|
+
#### Vegetation mask
|
|
343
|
+
|
|
344
|
+

|
|
345
|
+
|
|
346
|
+
Crop cover: **39.24%**
|
|
347
|
+
|
|
348
|
+
↓
|
|
349
|
+
|
|
350
|
+
### Export
|
|
351
|
+
|
|
352
|
+
The processing results can be exported to a dedicated output directory.
|
|
353
|
+
For batch processing, each Sentinel-2 product is exported to its own subdirectory.
|
|
354
|
+
|
|
355
|
+
The exported files include:
|
|
356
|
+
|
|
357
|
+
- GeoTIFF files for the computed vegetation indices;
|
|
358
|
+
- a GeoTIFF file containing the vegetation mask;
|
|
359
|
+
- a CSV file containing statistics for each vegetation index;
|
|
360
|
+
- a text file containing the estimated crop cover.
|
|
361
|
+
|
|
362
|
+
The results directory is organized as follows:
|
|
363
|
+
|
|
364
|
+
results/
|
|
365
|
+
├── indices/
|
|
366
|
+
│    ├── ndvi.tif
|
|
367
|
+
│    ├── savi.tif
|
|
368
|
+
│    ├── ndre.tif
|
|
369
|
+
│    └── gndvi.tif
|
|
370
|
+
├── vegetation_mask.tif
|
|
371
|
+
├── statistics.csv
|
|
372
|
+
└── crop_cover.txt
|
|
373
|
+
|
|
374
|
+
### Processing pipeline
|
|
375
|
+
|
|
376
|
+
The Sentinel-2 processing pipeline provides a high-level interface to process Sentinel-2 imagery and extract vegetation-related traits.
|
|
377
|
+
|
|
378
|
+
```python
|
|
379
|
+
from pathlib import Path
|
|
380
|
+
|
|
381
|
+
from opencropphenotyping.pipeline import (
|
|
382
|
+
process_sentinel2,
|
|
383
|
+
export_results,
|
|
384
|
+
)
|
|
385
|
+
|
|
386
|
+
input_dir = Path("data/raw")
|
|
387
|
+
output_dir = Path("data/processed")
|
|
388
|
+
|
|
389
|
+
result = process_sentinel2(
|
|
390
|
+
input_dir=input_dir,
|
|
391
|
+
indices=["ndvi", "ndre"],
|
|
392
|
+
resolution=10,
|
|
393
|
+
ndvi_threshold=0.3,
|
|
394
|
+
)
|
|
395
|
+
|
|
396
|
+
export_results(
|
|
397
|
+
result,
|
|
398
|
+
output_dir=output_dir,
|
|
399
|
+
)
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
The indices parameter can be used to select which vegetation indices are computed:
|
|
403
|
+
|
|
404
|
+
```python
|
|
405
|
+
indices=["ndvi"]
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
or:
|
|
409
|
+
|
|
410
|
+
```python
|
|
411
|
+
indices=["ndvi", "savi", "ndre", "gndvi"]
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
If ```python indices=None```, all available vegetation indices are requested.
|
|
415
|
+
|
|
416
|
+
If the bands required for a requested index are unavailable, that index is not computed and the pipeline continues processing the other available indices.
|
|
417
|
+
|
|
418
|
+
When NDVI is available, the pipeline also creates a vegetation mask and estimates crop cover.
|
|
419
|
+
|
|
420
|
+
### Processing results
|
|
421
|
+
|
|
422
|
+
The process_sentinel2() function returns a ProcessingResult object containing:
|
|
423
|
+
|
|
424
|
+
- the computed vegetation indices;
|
|
425
|
+
- the raster profile;
|
|
426
|
+
- statistics for each computed index;
|
|
427
|
+
- the vegetation mask, when NDVI is available;
|
|
428
|
+
- the crop cover estimate, when NDVI is available.
|
|
429
|
+
|
|
430
|
+
The results can then be exported using export_results().
|
|
431
|
+
|
|
432
|
+
## RGB UAV imagery
|
|
433
|
+
|
|
434
|
+
OpenCropPhenotyping also provides a classical RGB UAV workflow for crop-row and plant-position analysis.
|
|
435
|
+
|
|
436
|
+
The workflow is designed around a combination of:
|
|
437
|
+
|
|
438
|
+
- RGB image analysis
|
|
439
|
+
- ExG vegetation segmentation
|
|
440
|
+
- crop-row geometry
|
|
441
|
+
- georeferenced raster data
|
|
442
|
+
- experimental plot geometry
|
|
443
|
+
- plot-level metadata
|
|
444
|
+
- theoretical planting positions
|
|
445
|
+
- vegetation fraction within planting positions
|
|
446
|
+
|
|
447
|
+
The workflow can be demonstrated step by step or accessed through the high-level plant-detection function.
|
|
448
|
+
|
|
449
|
+
#### Load UAV RGB image
|
|
450
|
+
|
|
451
|
+
The workflow starts from an RGB UAV image.
|
|
452
|
+
|
|
453
|
+

|
|
454
|
+
|
|
455
|
+
|
|
456
|
+
↓
|
|
457
|
+
|
|
458
|
+
#### Georeferenced UAV image and experimental plot
|
|
459
|
+
|
|
460
|
+
To integrate experimental plot information into the image-processing workflow, the UAV image is converted into a georeferenced GeoTIFF.
|
|
461
|
+
|
|
462
|
+
The GeoTIFF stores both the RGB raster data and the spatial information required to relate image pixels to spatial coordinates.
|
|
463
|
+
|
|
464
|
+
The corresponding experimental plot is stored in a GeoPackage containing the plot geometry and experimental metadata, including:
|
|
465
|
+
|
|
466
|
+
- ```image_id```
|
|
467
|
+
- ```n_rows```
|
|
468
|
+
- ```n_plants```
|
|
469
|
+
- ```geometry```
|
|
470
|
+
|
|
471
|
+
The plot geometry is validated against the GeoTIFF to ensure that the experimental plot is correctly aligned with the image.
|
|
472
|
+
|
|
473
|
+
The plot geometry is then rasterized and transformed using the same crop-row rotation as the UAV image. This provides the spatial boundaries used to define crop-row regions and theoretical planting positions.
|
|
474
|
+
|
|
475
|
+
↓
|
|
476
|
+
|
|
477
|
+
#### Vegetation segmentation
|
|
478
|
+
|
|
479
|
+
RGB imagery is converted into an Excess Green (ExG) vegetation index and thresholded to produce a vegetation mask.
|
|
480
|
+
|
|
481
|
+

|
|
482
|
+
|
|
483
|
+
|
|
484
|
+
↓
|
|
485
|
+
|
|
486
|
+
#### Crop-row detection
|
|
487
|
+
|
|
488
|
+
The vegetation profile is used to estimate crop-row orientation and identify crop-row positions.
|
|
489
|
+
Experimental plot metadata are then used to define the expected number of crop rows and their spatial boundaries.
|
|
490
|
+
|
|
491
|
+

|
|
492
|
+
|
|
493
|
+
↓
|
|
494
|
+
|
|
495
|
+
#### Plant occupancy estimation
|
|
496
|
+
|
|
497
|
+
The experimental plot geometry and ```n_plants``` metadata are used to define theoretical planting positions along each crop row.
|
|
498
|
+
|
|
499
|
+
Vegetation fraction within each theoretical planting position is then used as an indicator of plant occupancy.
|
|
500
|
+
|
|
501
|
+

|
|
502
|
+
|
|
503
|
+
|
|
504
|
+
The current approach provides an interpretable classical baseline for UAV crop phenotyping. Its performance is influenced by plant development stage and the strength of the vegetation signal in the RGB imagery.
|
|
505
|
+
|
|
506
|
+
#### UAV workflow demonstration
|
|
507
|
+
|
|
508
|
+
A dedicated notebook demonstrates the complete workflow and the use of the package functions:
|
|
509
|
+
|
|
510
|
+
notebooks/
|
|
511
|
+
└── 06_UAV RGB workflow demonstration.ipynb
|
|
512
|
+
|
|
513
|
+
The notebook also contains examples of intermediate visualizations and exported figures used for project documentation with batch processing function.
|
|
514
|
+
|
|
515
|
+
#### RGB UAV imagery
|
|
516
|
+
|
|
517
|
+
RGB images are loaded as three NumPy arrays corresponding to the red, green and blue channels:
|
|
518
|
+
```python
|
|
519
|
+
from opencropphenotyping.rgb import read_rgb_image
|
|
520
|
+
|
|
521
|
+
red, green, blue = read_rgb_image(image_path)
|
|
522
|
+
```
|
|
523
|
+
The three returned arrays have the same spatial dimensions as the input image.
|
|
524
|
+
|
|
525
|
+
This functionality provides the foundation for RGB-based vegetation segmentation, crop-row detection and plant-position analysis.
|
|
526
|
+
|
|
527
|
+
### UAV RGB processing
|
|
528
|
+
|
|
529
|
+
The UAV RGB processing pipeline provides a high-level interface for plant occupancy estimation from RGB drone imagery.
|
|
530
|
+
|
|
531
|
+
A UAV dataset is composed of:
|
|
532
|
+
|
|
533
|
+
* an RGB image;
|
|
534
|
+
* a georeferenced GeoTIFF corresponding to the image;
|
|
535
|
+
* a GeoPackage containing the experimental plot geometry and metadata.
|
|
536
|
+
|
|
537
|
+
The GeoPackage contains the plot geometry together with the `image_id`, `n_rows` and `n_plants` attributes used by the pipeline.
|
|
538
|
+
|
|
539
|
+
A single UAV dataset can be processed using the `detect_plants()` function:
|
|
540
|
+
|
|
541
|
+
```python
|
|
542
|
+
from pathlib import Path
|
|
543
|
+
|
|
544
|
+
from opencropphenotyping.plants import detect_plants
|
|
545
|
+
from opencropphenotyping.io import export_uav_results
|
|
546
|
+
|
|
547
|
+
image_path = Path("data/raw/uav/image.png")
|
|
548
|
+
geotiff_path = Path("data/raw/uav/image_georef.tif")
|
|
549
|
+
geopackage_path = Path("data/raw/uav/plots.gpkg")
|
|
550
|
+
|
|
551
|
+
result = detect_plants(
|
|
552
|
+
image_path=image_path,
|
|
553
|
+
geotiff_path=geotiff_path,
|
|
554
|
+
geopackage_path=geopackage_path,
|
|
555
|
+
threshold=25,
|
|
556
|
+
vegetation_fraction_threshold=0.04,
|
|
557
|
+
)
|
|
558
|
+
|
|
559
|
+
export_uav_results(
|
|
560
|
+
result,
|
|
561
|
+
output_dir=Path("data/processed/uav"),
|
|
562
|
+
)
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
The pipeline:
|
|
566
|
+
|
|
567
|
+
* reads the RGB UAV image and computes the Excess Green (ExG) vegetation index;
|
|
568
|
+
* estimates the crop-row orientation and rotates the image and plot geometry accordingly;
|
|
569
|
+
* segments vegetation from the ExG image;
|
|
570
|
+
* detects crop rows;
|
|
571
|
+
* determines crop-row boundaries from the experimental plot geometry;
|
|
572
|
+
* estimates theoretical planting positions from the `n_plants` metadata;
|
|
573
|
+
* calculates vegetation fraction around each expected planting position;
|
|
574
|
+
* identifies potential missing plants using the vegetation-fraction threshold.
|
|
575
|
+
|
|
576
|
+
The `threshold` parameter controls vegetation segmentation from ExG values.
|
|
577
|
+
|
|
578
|
+
The `vegetation_fraction_threshold` parameter is used to classify potential missing plants. Lower values require less vegetation to classify a planting position as occupied.
|
|
579
|
+
|
|
580
|
+
### Processing results
|
|
581
|
+
|
|
582
|
+
The `detect_plants()` function returns a `UAVSegmentationResult` object containing:
|
|
583
|
+
|
|
584
|
+
* the plant-level dataframe;
|
|
585
|
+
* the estimated crop-row positions;
|
|
586
|
+
* the crop-row boundaries;
|
|
587
|
+
* the estimated row orientation;
|
|
588
|
+
* the vegetation mask;
|
|
589
|
+
* the rotated RGB image;
|
|
590
|
+
* the rotated ExG image.
|
|
591
|
+
|
|
592
|
+
The results can be exported using `export_uav_results()`.
|
|
593
|
+
|
|
594
|
+
By default, the export includes the plant-level results and the detected crop-row positions and boundaries. Intermediate raster outputs can also be exported with:
|
|
595
|
+
|
|
596
|
+
```python
|
|
597
|
+
export_uav_results(
|
|
598
|
+
result,
|
|
599
|
+
output_dir=output_dir,
|
|
600
|
+
export_intermediate=True,
|
|
601
|
+
)
|
|
602
|
+
```
|
|
603
|
+
|
|
604
|
+
### UAV batch processing
|
|
605
|
+
|
|
606
|
+
Several UAV datasets can be processed from a parent directory using `process_uav_batch()`.
|
|
607
|
+
|
|
608
|
+
Each dataset must be stored in a separate subdirectory containing one RGB image, one georeferenced GeoTIFF and one GeoPackage:
|
|
609
|
+
|
|
610
|
+
```text
|
|
611
|
+
data/raw/uav/
|
|
612
|
+
├── plot_103_DSC01167/
|
|
613
|
+
│ ├── image.png
|
|
614
|
+
│ ├── image_georef.tif
|
|
615
|
+
│ └── plots.gpkg
|
|
616
|
+
├── plot_104_DSC09694/
|
|
617
|
+
│ ├── image.png
|
|
618
|
+
│ ├── image_georef.tif
|
|
619
|
+
│ └── plots.gpkg
|
|
620
|
+
└── plot_108_DSC01166/
|
|
621
|
+
├── image.png
|
|
622
|
+
├── image_georef.tif
|
|
623
|
+
└── plots.gpkg
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
The batch function processes each dataset independently and stores the results in a corresponding output subdirectory:
|
|
627
|
+
|
|
628
|
+
```python
|
|
629
|
+
from pathlib import Path
|
|
630
|
+
|
|
631
|
+
from opencropphenotyping.batch_processing import process_uav_batch
|
|
632
|
+
|
|
633
|
+
process_uav_batch(
|
|
634
|
+
input_dir=Path("data/raw/uav"),
|
|
635
|
+
output_dir=Path("data/processed/uav"),
|
|
636
|
+
threshold=25,
|
|
637
|
+
vegetation_fraction_threshold=0.04,
|
|
638
|
+
export_intermediate=True,
|
|
639
|
+
)
|
|
640
|
+
```
|
|
641
|
+
|
|
642
|
+
If one dataset cannot be processed, the error is reported and processing continues with the remaining datasets.
|
|
643
|
+
|
|
644
|
+
### Command-line interface
|
|
645
|
+
|
|
646
|
+
The UAV processing pipeline is also available through the command-line interface.
|
|
647
|
+
|
|
648
|
+
To process a single UAV dataset:
|
|
649
|
+
|
|
650
|
+
```bash
|
|
651
|
+
opencropphenotyping segment-uav \
|
|
652
|
+
--image-path data/raw/uav/image.png \
|
|
653
|
+
--geotiff-path data/raw/uav/image_georef.tif \
|
|
654
|
+
--geopackage-path data/raw/uav/plots.gpkg \
|
|
655
|
+
--output-dir data/processed/uav
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+
To process several UAV datasets from a parent directory:
|
|
659
|
+
|
|
660
|
+
```bash
|
|
661
|
+
opencropphenotyping batch-uav \
|
|
662
|
+
--input-dir data/raw/uav \
|
|
663
|
+
--output-dir data/processed/uav
|
|
664
|
+
```
|
|
665
|
+
|
|
666
|
+
Optional parameters can be used to modify the vegetation segmentation and plant-occupancy thresholds:
|
|
667
|
+
|
|
668
|
+
```bash
|
|
669
|
+
opencropphenotyping batch-uav \
|
|
670
|
+
--input-dir data/raw/uav \
|
|
671
|
+
--output-dir data/processed/uav \
|
|
672
|
+
--threshold 25 \
|
|
673
|
+
--vegetation-fraction-threshold 0.04 \
|
|
674
|
+
--export-intermediate
|
|
675
|
+
```
|
|
676
|
+
|
|
677
|
+
The CLI follows the same processing pipeline as the Python API and can therefore be used for reproducible processing of individual UAV datasets or complete directories of datasets.
|
|
678
|
+
|
|
679
|
+
## Contributing
|
|
680
|
+
|
|
681
|
+
Contributions are welcome. If you have ideas for improvements, bug fixes or new features, feel free to open an issue or submit a pull request.
|
|
682
|
+
|
|
683
|
+
## Documentation
|
|
684
|
+
|
|
685
|
+
Documentation will be progressively added as the project evolves.
|
|
686
|
+
The repository currently provides detailed notebooks illustrating the development and application of the processing workflows.
|
|
687
|
+
|
|
688
|
+
## Version
|
|
689
|
+
|
|
690
|
+
This project follows Semantic Versioning (SemVer).
|
|
691
|
+
See the Releases page for available versions and change logs.
|
|
692
|
+
|
|
693
|
+
## LICENSE
|
|
694
|
+
|
|
695
|
+
See the LICENSE file.
|