TuberVision / README.md
cisdeli
Space build: prepend README frontmatter
56fa555
|
Raw History Blame Contribute Delete
5.15 kB
metadata
title: TuberVision
sdk: docker
app_port: 7860
pinned: false
short_description: Tuber segmentation, morphometrics, and yield prediction

Seeing beyond yield: distribution-aware image phenotyping reveals plot-level tuber profiles in potato breeding

Gustavo Nandi, Matheus Martins de Sousa, Pedro Cisdeli, Fernando Angelo Piotto, Joseph Coombs, David S. Douches,

Preprint


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 for environment and dependency management.

# 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:

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.

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.

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.

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.

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.

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.

uv run python scripts/fit_final_models.py \
    --input outputs/df_model_yield_by_plot.csv \
    --out app/m3_coefficients.json

License

TBD.