Spaces:
Sleeping
Sleeping
File size: 5,151 Bytes
56fa555 a384164 5181d0e a384164 5181d0e a384164 5181d0e a384164 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | ---
title: TuberVision
sdk: docker
app_port: 7860
pinned: false
short_description: Tuber segmentation, morphometrics, and yield prediction
---
<div align="center">
# Seeing beyond yield: distribution-aware image phenotyping reveals plot-level tuber profiles in potato breeding
<h3>
<a href="https://orcid.org/0000-0002-8830-8952">Gustavo Nandi</a>,
<a href="https://orcid.org/0009-0008-6511-3600">Matheus Martins de Sousa</a>,
<a href="https://www.cisdeli.dev/">Pedro Cisdeli</a>,
<a href="https://orcid.org/0000-0001-9728-6938 ">Fernando Angelo Piotto</a>,
<a href="https://orcid.org/0000-0001-5164-6467">Joseph Coombs</a>,
<a href="https://orcid.org/0000-0002-0636-5356">David S. Douches</a>,
</h3>
[](#)
</div>
---
## Overview
Companion code for the paper *"Seeing beyond yield: distribution-aware image phenotyping reveals plot-level tuber profiles in potato breeding"*.
The pipeline ingests top-down RGB images of harvested tubers on a conveyor belt and runs YOLOv11-seg instance segmentation, per-tuber polygon morphometrics, USDA commercial size classification (B, A1, A2, OV), plot-level aggregation of distributional features, and yield prediction with a linear model fit under a leave-one-trial-out (LOTO) framework.
Two ways to use this repository:
1. A **Gradio app** that runs the full pipeline on a single image.
2. A set of **reproducibility scripts** that re-create the per-tuber, per-plot, and per-fold modeling outputs.
---
## Installation
The project uses [uv](https://docs.astral.sh/uv/) for environment and dependency management.
```bash
# install uv (see https://docs.astral.sh/uv/getting-started/installation/)
curl -LsSf https://astral.sh/uv/install.sh | sh
# clone and enter the repo
git clone <repo-url-REPLACE_AFTER_CHANGES> potatopheno
cd potatopheno
# create the project venv and install the core dependencies
uv sync
# add the optional demo deps (gradio) when running the app
uv sync --extra app
```
All scripts are launched with `uv run python <script>`. Python 3.12 or newer is required.
---
## Demo app
The Gradio app runs the full pipeline on one image at a time. It supports two input modes: pick a bundled dataset image, or upload your own.
Required artifacts:
- `bestModel.pt`: trained YOLOv11-seg weights.
- `m3_coefficients.json`: in-sample M3 coefficients. Produced by `scripts/fit_final_models.py` (see below).
Launch:
```bash
uv run app/app.py
```
The same app runs as a Hugging Face Space. Maintainers deploy it with
`./scripts/deploy_space.sh`, which pushes this repository to the Space remote and
prepends the Space's README frontmatter from [app/space_header.md](app/space_header.md).
Environment variables (all optional):
| Variable | Default | Purpose |
|---|---|---|
| `POTATOPHENO_WEIGHTS` | `app/bestModel.pt` | YOLO weights file |
| `POTATOPHENO_COEFS` | `app/m3_coefficients.json` | M3 coefficients JSON |
| `POTATOPHENO_DATASET` | `app/dataset` | Root with `2025<TRIAL>/*.JPG` subfolders |
| `POTATOPHENO_BELT_IN` | `30.0` | Conveyor belt width in inches |
---
## Reproducibility
**Image Dataset**: Possibly going to be uploaded to the releases page later or zenodo.
The pipeline is split into stages, each driven by a script under `scripts/`. Run them in order. Every script accepts `--help` for the full argument list.
### 1. YOLO inference
Produces one YOLO-seg `.txt` file per image with normalized polygon coordinates per tuber.
```bash
uv run python scripts/run_yolo_inference.py \
--weights path/to/bestModel.pt \
--images-root path/to/rawData/images \
--out-root outputs/preds
```
### 2. Per-tuber morphometrics
Reads the `.txt` predictions and source images, computes polygon morphometrics (area, perimeter, circularity, eccentricity, bounding-box dimensions), converts to real-scale via the 30" belt calibration, and assigns the USDA size class.
```bash
uv run python scripts/extract_morphometrics.py \
--preds-root outputs/preds \
--images-root path/to/rawData/images \
--out outputs/df_class_real_scale_ALL.csv
```
### 3. Plot-level modeling dataset
Applies QC filters, aggregates to (trial, plot), merges with the cleaned harvest ground truth, and computes the regression target `obs_sum_B_A1_A2_OV`.
```bash
uv run python scripts/build_plot_model_dataset.py \
--tubers outputs/df_class_real_scale_ALL.csv \
--gt path/to/gt_clean_for_yield_modeling.csv \
--out outputs/df_model_yield_by_plot.csv
```
### 4. Leave-one-trial-out yield models
Runs M1, M2, M3, and Random Forest under LOTO. Writes per-fold metrics, per-plot predictions, and the cross-fold summary.
```bash
uv run python scripts/run_loto_models.py \
--input outputs/df_model_yield_by_plot.csv \
--out-dir outputs/loto/
```
### 5. M3 coefficients for the demo (optional)
Fits M1, M2, and M3 in-sample on the full plot-level dataset and writes the coefficients used by the Gradio app.
```bash
uv run python scripts/fit_final_models.py \
--input outputs/df_model_yield_by_plot.csv \
--out app/m3_coefficients.json
```
---
## License
TBD.
|