alexp97 commited on
Commit
2cce711
·
1 Parent(s): f514b00

docs: elimina docs _mvp y _modelo_conteo_plantas (a pedido) + corrige enlaces

Browse files

- Borra architecture_agrovision_mvp.md, architecture_modelo_conteo_plantas.md,
description_proyecto_agrovision_mvp.md, description_proyecto_modelo_conteo_plantas.md.
- Relativiza/quita los enlaces a esos archivos en README, description/architecture/db/ejecucion
(el modelo de conteo vive en un repo separado).

README.md CHANGED
@@ -4,7 +4,7 @@ Plataforma de [AgroVisión](docs/reference/description_proyecto_agrovision.md) p
4
 
5
  > **Modelo BYOK, credenciales efímeras.** Las llaves del usuario (Supabase, Copernicus, Groq) viven **solo en memoria de sesión** y se envían por cabeceras `X-User-*`; nunca se persisten. Refrescar borra todo.
6
  >
7
- > **Conteo por dron — EN DESARROLLO.** Arranca deshabilitado (`COUNTING_ENABLED=false`); la cola/worker/tabla existen pero inactivos hasta que el [repo del modelo](docs/reference/description_proyecto_modelo_conteo_plantas.md) publique el artefacto `agrovision-plantcount` en Hugging Face Hub. **Licencia: AGPL-3.0.**
8
 
9
  ## Módulos (6)
10
 
 
4
 
5
  > **Modelo BYOK, credenciales efímeras.** Las llaves del usuario (Supabase, Copernicus, Groq) viven **solo en memoria de sesión** y se envían por cabeceras `X-User-*`; nunca se persisten. Refrescar borra todo.
6
  >
7
+ > **Conteo por dron — EN DESARROLLO.** Arranca deshabilitado (`COUNTING_ENABLED=false`); la cola/worker/tabla existen pero inactivos hasta que el **repo del modelo** (proyecto separado) publique el artefacto `agrovision-plantcount` en Hugging Face Hub. **Licencia: AGPL-3.0.**
8
 
9
  ## Módulos (6)
10
 
docs/architect/architecture_agrovision.md CHANGED
@@ -1,7 +1,7 @@
1
  # Arquitectura — AgroVisión (Plataforma Completa)
2
 
3
  > **Audiencia:** Arquitectos de solución, líderes técnicos, desarrolladores.
4
- > **Alcance:** Estructura fundamental del sistema, interacciones de alto nivel (C4), esquema de datos y modelo de despliegue de la **plataforma completa** (**6 módulos**). Para especificaciones funcionales, ver [`description_proyecto_agrovision.md`](../reference/description_proyecto_agrovision.md). Para el alcance reducido, ver [`architecture_agrovision_mvp.md`](architecture_agrovision_mvp.md).
5
  >
6
  > **Estilo arquitectónico:** **monolito modular** (un solo backend FastAPI con límites por dominio bien aislados — `api/` HTTP + `services/` negocio), **microservices-ready**: cada dominio puede extraerse a un servicio propio sin reescribir la UI. Elegido sobre microservicios reales por la realidad de la **capa gratuita** (Render free duerme a 15 min y multiplica cold-starts/CORS por servicio). Ver ADR en §7.
7
  >
 
1
  # Arquitectura — AgroVisión (Plataforma Completa)
2
 
3
  > **Audiencia:** Arquitectos de solución, líderes técnicos, desarrolladores.
4
+ > **Alcance:** Estructura fundamental del sistema, interacciones de alto nivel (C4), esquema de datos y modelo de despliegue de la **plataforma completa** (**6 módulos**). Para especificaciones funcionales, ver [`description_proyecto_agrovision.md`](../reference/description_proyecto_agrovision.md).
5
  >
6
  > **Estilo arquitectónico:** **monolito modular** (un solo backend FastAPI con límites por dominio bien aislados — `api/` HTTP + `services/` negocio), **microservices-ready**: cada dominio puede extraerse a un servicio propio sin reescribir la UI. Elegido sobre microservicios reales por la realidad de la **capa gratuita** (Render free duerme a 15 min y multiplica cold-starts/CORS por servicio). Ver ADR en §7.
7
  >
docs/architect/architecture_agrovision_mvp.md DELETED
@@ -1,158 +0,0 @@
1
- # Arquitectura — AgroVisión MVP (Conteo por Dron)
2
-
3
- > **Audiencia:** Arquitectos de solución, líderes técnicos, desarrolladores.
4
- > **Alcance:** Estructura del **MVP** (conteo por dron + credenciales efímeras). Topología simplificada y síncrona. Para especificaciones funcionales, ver [`description_proyecto_agrovision_mvp.md`](../reference/description_proyecto_agrovision_mvp.md). Para la arquitectura objetivo completa, ver [`architecture_agrovision.md`](architecture_agrovision.md).
5
-
6
- ---
7
-
8
- ## 1. Visión General del Sistema (C4 – Nivel Contexto)
9
-
10
- ```mermaid
11
- flowchart TB
12
- subgraph Actores["Actores Principales"]
13
- U1["👤 Agrónomo / Productor"]
14
- end
15
-
16
- subgraph Sistema["Sistema Central (MVP)"]
17
- direction TB
18
- APP["AgroVisión MVP<br/>─────────────────<br/>Carga de ortomosaico RGB +<br/>conteo de plantas con modelo predeterminado"]
19
- end
20
-
21
- subgraph Externos["Dependencias"]
22
- MODEL["Modelo predeterminado<br/>─────────────<br/>agrovision-plantcount-v2.0.0.onnx (empaquetado, NO externo)"]
23
- end
24
-
25
- U1 -->|"Sube ortomosaico y obtiene conteo"| APP
26
- APP -->|"Carga al iniciar (solo inferencia)"| MODEL
27
- ```
28
-
29
- **Decisiones arquitectónicas clave (Nivel Macro):**
30
- - **Sin dependencias externas para la función núcleo:** el conteo corre con el modelo empaquetado; no requiere llaves de API.
31
- - **Inferencia síncrona:** sin cola ni worker — máxima simplicidad para validar el flujo.
32
- - **Sin base de datos:** todo es efímero (memoria de sesión); refrescar borra todo.
33
- - **Credenciales efímeras (placeholder):** la pestaña existe como base para módulos futuros, con el aviso de no-persistencia.
34
-
35
- ---
36
-
37
- ## 2. Componentes Internos (C4 – Nivel Contenedor)
38
-
39
- ```mermaid
40
- flowchart LR
41
- subgraph Cliente["Capa de Presentación"]
42
- UI["UI — Shiny for Python<br/>──────────<br/>2 nav_panel: Conteo · Credenciales<br/>ui.input_file · estado efímero<br/>Host: ShinyApps.io"]
43
- end
44
-
45
- subgraph Backend["Capa de Aplicación"]
46
- direction TB
47
- API["Backend — FastAPI<br/>──────────<br/>POST /api/count (SÍNCRONO)<br/>Inferencia en proceso"]
48
- MODEL["Modelo predeterminado<br/>agrovision-plantcount-v2.0.0.onnx (empaquetado)"]
49
- end
50
-
51
- UI -->|"HTTPS multipart (imagen)"| API
52
- API -->|"carga al iniciar"| MODEL
53
- ```
54
-
55
- **Flujo de una interacción típica:**
56
- 1. El agrónomo sube un ortomosaico en la UI y pulsa "Iniciar Conteo".
57
- 2. La UI envía `POST /api/count` (multipart) al backend.
58
- 3. El backend ejecuta RF-DETR-Nano **en proceso** (con *tiling* si es grande) y devuelve conteo + overlay (base64).
59
- 4. La UI renderiza métricas y overlay. **Nada se persiste.**
60
-
61
- > **Variante monolítica:** para máxima simplicidad, UI + inferencia pueden vivir en **un solo contenedor** (Shiny llamando al modelo en proceso), evitando CORS y dos servicios.
62
-
63
- ---
64
-
65
- ## 3. Lógica Core / Procesos Críticos
66
-
67
- ```mermaid
68
- flowchart TB
69
- IN(["Ortomosaico RGB"])
70
- P1["Validación (formato/tamaño) + tiling por GSD"]
71
- P2["Inferencia RF-DETR-Nano (CPU, en proceso)"]
72
- P3["Reensamble + NMS + heurística de fallas"]
73
- P4["Conteo, densidad pl/Ha, malezas, % fallas"]
74
- OUT(["Respuesta JSON + overlay base64"])
75
- IN --> P1 --> P2 --> P3 --> P4 --> OUT
76
- ```
77
-
78
- ---
79
-
80
- ## 4. Flujo de Secuencia (Conteo Síncrono)
81
-
82
- ```mermaid
83
- sequenceDiagram
84
- actor U as Agrónomo
85
- participant C as UI (Shiny)
86
- participant S as Backend (FastAPI)
87
- participant M as Modelo (RF-DETR-Nano)
88
-
89
- U->>C: Sube ortomosaico + clic "Iniciar Conteo"
90
- C->>S: POST /api/count (multipart, area_ha?)
91
- S->>M: Inferencia en proceso (tiling)
92
- M-->>S: boxes + count
93
- S->>S: Calcula densidad, malezas, fallas + overlay
94
- S-->>C: {count, density, weeds, failures, overlay_b64}
95
- C-->>U: Render métricas + overlay (efímero)
96
- ```
97
-
98
- ---
99
-
100
- ## 5. Modelo de Dominio / Entidad-Relación
101
-
102
- **El MVP no persiste datos.** No hay base de datos: la información de cada corrida vive en `reactive.value` de la sesión Shiny y se descarta al refrescar/cerrar.
103
-
104
- > **Futuro:** al evolucionar a la plataforma completa, los conteos se persistirían en la tabla `plant_counts` definida en [`docs/db/diseno_db.md`](../db/diseno_db.md).
105
-
106
- **Políticas de Datos (MVP):**
107
- - **Efimeralidad total:** sin disco, sin BD, sin `localStorage`.
108
- - **Aislamiento por sesión:** cada WebSocket Shiny es independiente.
109
-
110
- ---
111
-
112
- ## 6. Arquitectura de Despliegue (Infraestructura)
113
-
114
- ```mermaid
115
- flowchart LR
116
- subgraph Local["Entorno de Desarrollo"]
117
- direction TB
118
- DEV["docker-compose<br/>ui · api"]
119
- SAMPLE[("sample_data/ + models/")]
120
- DEV --- SAMPLE
121
- end
122
-
123
- subgraph Pipeline["CI/CD"]
124
- direction TB
125
- LINT["Ruff + pytest"]
126
- BUILD["Build Docker images<br/>(modelo empaquetado)"]
127
- LINT --> BUILD
128
- end
129
-
130
- subgraph Prod["Producción (Capa Gratuita)"]
131
- direction TB
132
- SHINY["ShinyApps.io (UI)"]
133
- RENDER["Render (FastAPI + modelo)"]
134
- SHINY -->|"HTTPS + CORS"| RENDER
135
- end
136
-
137
- Local -->|"git push"| Pipeline
138
- Pipeline -->|"deploy"| Prod
139
- ```
140
-
141
- **Notas de despliegue:**
142
- - Dos servicios (UI + backend) **o** un único contenedor monolítico (Shiny + inferencia) en Render / Hugging Face Spaces.
143
- - El modelo `agrovision-plantcount-v2.0.0.onnx` (ONNX ligero, **agnóstico** a la arquitectura: YOLO26/RF-DETR) cabe holgado en los 512 MB de Render.
144
- - El **módulo de conteo arranca en standby** (`COUNTING_ENABLED=false`) hasta que el repo del modelo publique el artefacto en Hugging Face Hub. Licencia: AGPL-3.0 aceptada (app open-source).
145
-
146
- ---
147
-
148
- ## 7. Decisiones Arquitectónicas Relevantes (ADRs Resumidos)
149
-
150
- | Decisión Tomada | Alternativa Descartada | Razón Principal |
151
- | :--- | :--- | :--- |
152
- | **Inferencia síncrona en proceso** | Cola PGMQ + worker (plataforma completa) | El MVP valida el flujo con mínima complejidad; el modelo ligero responde en segundos. |
153
- | **Sin base de datos (efímero)** | Supabase PostGIS desde el inicio | El núcleo de valor (conteo) no requiere persistencia; evita configurar BYOK para la demo. |
154
- | **Conteo sin llaves de API** | BYOK obligatorio | El modelo corre local; el usuario obtiene valor sin configurar credenciales. |
155
- | **UI en Shiny for Python** | Streamlit / Astro | Coherencia con la plataforma completa; reutiliza la misma base de código de UI. |
156
- | **Opción monolítica de despliegue** | Siempre dos servicios | Para el MVP, un contenedor único reduce CORS y complejidad operativa. |
157
-
158
- > Todos los componentes del MVP son un **subconjunto estricto** de la [arquitectura completa](architecture_agrovision.md); evolucionar es activar módulos, no reescribir.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
docs/architect/architecture_modelo_conteo_plantas.md DELETED
@@ -1,192 +0,0 @@
1
- # Arquitectura — Modelo de Conteo de Plantas (Repo Separado)
2
-
3
- > **Audiencia:** Ingenieros de ML/visión, líderes técnicos.
4
- > **Alcance:** Estructura del **repositorio de modelado** (pipeline ML), no de una app productiva. Su salida es **UN artefacto** (`agrovision-plantcount-*.onnx`) publicado en **Hugging Face Hub** y consumido por AgroVisión. Para especificaciones, ver [`description_proyecto_modelo_conteo_plantas.md`](../reference/description_proyecto_modelo_conteo_plantas.md).
5
- > **Modelo (multi-candidato):** se evalúan **YOLO26** (AGPL-3.0, NMS-free), **RF-DETR** (Apache 2.0, NMS-free) y **DINOv3**; se publica **el mejor** (menor MAE). **AGPL aceptada** (app open-source) → YOLO26 usable. **Multi-cultivo** (arándano primero). DeepForest (MIT) para satélite. **Sin BD transaccional** (persistencia = datasets/artefactos versionados).
6
-
7
- ---
8
-
9
- ## 1. Visión General del Sistema (C4 – Nivel Contexto)
10
-
11
- ```mermaid
12
- flowchart TB
13
- subgraph Actores["Actores Principales"]
14
- U1["👤 Ingeniero ML / Visión"]
15
- end
16
-
17
- subgraph Sistema["Sistema Central"]
18
- APP["Repo de Modelo de Conteo<br/>─────────────────<br/>Notebooks + pipeline .py<br/>Entrena candidatos (YOLO26/RF-DETR), publica el mejor (1 modelo)"]
19
- end
20
-
21
- subgraph Externos["Dependencias Externas"]
22
- DATA["Fuentes de Datos<br/>─────────────<br/>Roboflow (COCO) · Kaggle · DeepForest/NEON · MAXAR/Planet"]
23
- GPU["Cómputo Gratuito<br/>─────────────<br/>Google Colab / Kaggle (GPU T4)"]
24
- HF["Hugging Face Hub<br/>─────────────<br/>repo de modelos (artefacto versionado)"]
25
- AV["AgroVisión (consumidor)<br/>─────────────<br/>hf_hub_download en build (solo inferencia)"]
26
- end
27
-
28
- U1 -->|"experimenta, entrena, exporta"| APP
29
- APP <-->|"descarga datasets (COCO)"| DATA
30
- APP <-->|"entrena en GPU"| GPU
31
- APP -->|"publica 1 artefacto"| HF
32
- HF -->|"build descarga el modelo"| AV
33
- ```
34
-
35
- **Decisiones arquitectónicas clave (Nivel Macro):**
36
- - **Notebooks-first:** validar viabilidad en notebooks (Colab/Kaggle) antes de promover a `.py`.
37
- - **1 solo artefacto publicado:** se entrenan varios candidatos, se selecciona el mejor y **solo ese** se sube a HF Hub.
38
- - **RF-DETR (Apache 2.0) NMS-free** como primario (permisivo, CPU) + **DINOv3/DeepForest** (satélite).
39
- - **Nombre desacoplado:** `agrovision-plantcount` (no depende de la arquitectura interna).
40
-
41
- ---
42
-
43
- ## 2. Componentes Internos (C4 – Nivel Contenedor)
44
-
45
- ```mermaid
46
- flowchart LR
47
- subgraph Exp["Capa de Experimentación"]
48
- NB["notebooks/<br/>──────────<br/>01 explore · 02 SAM→COCO · 03 RF-DETR · 04 satélite"]
49
- end
50
-
51
- subgraph Pipe["Capa de Pipeline (.py reproducible)"]
52
- direction TB
53
- ING["ingest.py (Roboflow COCO/Kaggle)"]
54
- ANN["annotate_sam.py (SAM → COCO)"]
55
- PRE["preprocess.py (tiling/splits/augment COCO)"]
56
- TRN["train.py (RF-DETR detect/seg)"]
57
- EVL["evaluate.py (mAP/F1/MAE + selección)"]
58
- EXP2["export.py (.pth → ONNX + model card)"]
59
- PUB["publish.py (→ Hugging Face Hub)"]
60
- SAT["satellite/ (DeepForest + DINOv3)"]
61
- end
62
-
63
- subgraph Store["Almacenes / Artefactos"]
64
- RAW[("data/raw")]
65
- PROC[("data/processed (COCO)")]
66
- MOD[("models/ (.onnx) + metrics.json")]
67
- end
68
-
69
- NB -.promueve.-> Pipe
70
- ING --> RAW --> ANN --> PROC
71
- PRE --> PROC
72
- PROC --> TRN --> EVL --> EXP2 --> MOD --> PUB
73
- SAT --> EVL
74
- ```
75
-
76
- **Flujo de una interacción típica:**
77
- 1. El ingeniero **explora** datos y valida un conteo base en `03_train_rfdetr.ipynb`.
78
- 2. Promueve la lógica a `src/*.py`: `ingest` → `annotate_sam` (→ COCO) → `preprocess` → `train` → `evaluate` (**selecciona el mejor**) → `export` → `publish`.
79
- 3. `export.py` genera `agrovision-plantcount-vX.Y.Z.onnx`; `publish.py` lo sube a **HF Hub**.
80
- 4. El build de AgroVisión lo descarga con `hf_hub_download` como modelo predeterminado.
81
-
82
- ---
83
-
84
- ## 3. Lógica Core / Proceso Crítico (Pipeline ML)
85
-
86
- ```mermaid
87
- flowchart TB
88
- IN(["Datasets públicos (dron/satélite)"])
89
- P1["Anotación SAM → formato COCO"]
90
- P2["Preprocesamiento: tiling por GSD + augmentations + splits COCO"]
91
- P3["Entrenamiento RF-DETR (transfer, NMS-free)"]
92
- P4["Evaluación + SELECCIÓN del mejor (MAE/tamaño/latencia)"]
93
- P5["Exportación ONNX + model card"]
94
- P6["Publicación en Hugging Face Hub (1 artefacto)"]
95
- OUT(["agrovision-plantcount-*.onnx (contrato §6)"])
96
- IN --> P1 --> P2 --> P3 --> P4 --> P5 --> P6 --> OUT
97
- P4 -.->|"si MAE > umbral"| P2
98
- ```
99
-
100
- ---
101
-
102
- ## 4. Flujo de Secuencia (Experimentación → Producción → Handoff)
103
-
104
- ```mermaid
105
- sequenceDiagram
106
- actor E as Ingeniero ML
107
- participant NB as Notebook (Colab/Kaggle)
108
- participant PY as Pipeline .py
109
- participant GPU as GPU T4 (gratis)
110
- participant HF as Hugging Face Hub
111
- participant AV as AgroVisión (build)
112
-
113
- E->>NB: PoC de conteo con dataset COCO público
114
- NB->>GPU: entrena RFDETRNano (rápido)
115
- GPU-->>NB: métricas base (mAP/MAE)
116
- Note over NB,PY: viabilidad validada → promover lógica
117
- E->>PY: ejecuta pipeline reproducible (seeds fijas)
118
- PY->>GPU: train + eval completos
119
- PY->>PY: evaluate.py SELECCIONA el mejor candidato
120
- PY->>PY: export.py → agrovision-plantcount-v2.0.0.onnx
121
- PY->>HF: publish.py sube 1 artefacto + model card
122
- AV->>HF: hf_hub_download en docker build
123
- AV-->>E: integrado como modelo predeterminado (MODEL_PATH)
124
- ```
125
-
126
- ---
127
-
128
- ## 5. Modelo de Dominio / Artefactos (no hay BD transaccional)
129
-
130
- ```mermaid
131
- flowchart TB
132
- subgraph Datos["Datos"]
133
- DS["Dataset<br/>─────────<br/>fuente · licencia · clases (COCO)"]
134
- ANN["Anotaciones COCO<br/>─────────<br/>_annotations.coco.json"]
135
- end
136
- subgraph Artefactos["Artefactos de Modelo"]
137
- RUN["Run de Entrenamiento<br/>─────────<br/>hiperparámetros · seed · métricas"]
138
- MOD["Modelo publicado (1)<br/>─────────<br/>agrovision-plantcount.onnx · model_version · architecture"]
139
- CARD["Model Card<br/>─────────<br/>datos · licencia (Apache 2.0) · métricas"]
140
- end
141
- DS -->|"se anota"| ANN
142
- ANN -->|"entrena"| RUN
143
- RUN -->|"se selecciona el mejor → produce"| MOD
144
- MOD -->|"documenta"| CARD
145
- ```
146
-
147
- **Políticas de Datos:**
148
- - **Versionado de datos:** `data/` no se commitea; se versiona el *manifiesto* (fuente, hash, licencia) y opcionalmente con **DVC**.
149
- - **1 artefacto:** solo el modelo seleccionado se publica (HF Hub); su `model_version` (SemVer) enlaza run/dataset/métricas.
150
- - **Reproducibilidad:** semillas fijas y config declarativa.
151
-
152
- ---
153
-
154
- ## 6. Arquitectura de Despliegue (Publicación de Artefactos)
155
-
156
- ```mermaid
157
- flowchart LR
158
- subgraph Local["Desarrollo"]
159
- DEV["IDE + notebooks (CPU local)"]
160
- end
161
- subgraph Cloud["Cómputo Gratuito"]
162
- COLAB["Colab / Kaggle (GPU T4)"]
163
- end
164
- subgraph CI["CI / Publicación"]
165
- TEST["pytest (contrato + paridad)"]
166
- PUB["publish.py → Hugging Face Hub vX.Y.Z"]
167
- TEST --> PUB
168
- end
169
- subgraph Consumo["Consumo"]
170
- AVB["Build de AgroVisión<br/>hf_hub_download → imagen backend"]
171
- end
172
-
173
- DEV -->|"PoC"| COLAB
174
- COLAB -->|"checkpoint_best.pth"| CI
175
- Local -->|"git push"| CI
176
- PUB -->|"descarga artefacto"| AVB
177
- ```
178
-
179
- ---
180
-
181
- ## 7. Decisiones Arquitectónicas Relevantes (ADRs Resumidos)
182
-
183
- | Decisión Tomada | Alternativa Descartada | Razón Principal |
184
- | :--- | :--- | :--- |
185
- | **Multi-candidato: YOLO26 + RF-DETR + DINOv3, se publica el mejor** | Fijar un solo modelo de entrada | Gana el de **menor MAE** (tamaño/latencia OK). **AGPL-3.0 aceptada** (app open-source) habilita YOLO26; RF-DETR (Apache) queda como alternativa permisiva. App **agnóstica por contrato**. |
186
- | **Anotar a COCO + YOLO** | Un solo formato | Se anota una vez y se exporta a **COCO** (para RF-DETR) y **YOLO** (para YOLO26), permitiendo entrenar ambos candidatos. |
187
- | **Publicar en Hugging Face Hub** | GitHub Releases / object storage | Hosting de modelos versionado y estándar; `hf_hub_download` integra en el build de AgroVisión. |
188
- | **1 solo artefacto, el mejor** | Publicar todos los tracks | Simplicidad para el consumidor; los tracks son experimentos para elegir al ganador. |
189
- | **Nombre desacoplado** (`agrovision-plantcount`) | Nombre por arquitectura (`rfdetr_nano`) | Permite cambiar de modelo sin tocar la app; el contrato es lo estable. |
190
- | **DINOv3 + DeepForest** (satélite) | Entrenar conteo de árboles desde cero | DeepForest (MIT) preentrenado + DINOv3 satelital sin fine-tuning aceleran el track. |
191
- | **Notebooks-first** | Ir directo a `.py` | Validar viabilidad barato antes de endurecer; cada notebook tiene su par `.py` testeado. |
192
- | **Sin BD transaccional** | Postgres/registro pesado | El dominio son datasets/artefactos versionados (manifiestos + DVC + HF Hub). |
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
docs/db/diseno_db.md CHANGED
@@ -2,7 +2,7 @@
2
 
3
  > **Propósito:** Definir el modelo físico y lógico de persistencia de AgroVisión, justificar la elección del motor y servir como mapa de referencia para migraciones e implementación.
4
  > **Origen:** Se construye a partir de [`docs/reference/description_proyecto_agrovision.md`](../reference/description_proyecto_agrovision.md).
5
- > **Aplicabilidad:** Solo la **plataforma completa**. El [MVP](../reference/description_proyecto_agrovision_mvp.md) opera en **modo efímero sin base de datos** (todo en memoria de sesión).
6
  >
7
  > **Alcance de construcción (esta iteración):** se implementan **todas** las tablas, pero con dos matices:
8
  > - **`fields`, `ndvi_timeseries`, `chat_messages`** se usan activamente (parcelas, teledetección 5 años, agente).
 
2
 
3
  > **Propósito:** Definir el modelo físico y lógico de persistencia de AgroVisión, justificar la elección del motor y servir como mapa de referencia para migraciones e implementación.
4
  > **Origen:** Se construye a partir de [`docs/reference/description_proyecto_agrovision.md`](../reference/description_proyecto_agrovision.md).
5
+ > **Aplicabilidad:** Solo la **plataforma completa**. (El MVP histórico operaba en modo efímero sin base de datos.)
6
  >
7
  > **Alcance de construcción (esta iteración):** se implementan **todas** las tablas, pero con dos matices:
8
  > - **`fields`, `ndvi_timeseries`, `chat_messages`** se usan activamente (parcelas, teledetección 5 años, agente).
docs/ejecucion.md CHANGED
@@ -9,7 +9,7 @@
9
  > **La app abre SIN credenciales** (verás los 6 módulos). Para *usar* cada módulo necesitas las llaves BYOK (todas de capa gratuita), que pones en `.env` (local) o en la pestaña **Credenciales** (sesión):
10
  > - **Parcelas / Teledetección / Resumen** → Supabase (`DATABASE_URL`) y, para NDVI, **Copernicus** (`DEV_COPERNICUS_CLIENT_ID/SECRET`). El clima (Open-Meteo) no necesita llave.
11
  > - **Asistente** → **Groq** (`DEV_GROQ_API_KEY`).
12
- > - **Conteo** → **EN DESARROLLO** (standby): la pestaña muestra *"Módulo en preparación"*. Se habilita cuando el [repo del modelo](reference/description_proyecto_modelo_conteo_plantas.md) publique el artefacto. Para demostrar el flujo con datos de prueba (mock) — ver §3.5.
13
 
14
  ---
15
 
 
9
  > **La app abre SIN credenciales** (verás los 6 módulos). Para *usar* cada módulo necesitas las llaves BYOK (todas de capa gratuita), que pones en `.env` (local) o en la pestaña **Credenciales** (sesión):
10
  > - **Parcelas / Teledetección / Resumen** → Supabase (`DATABASE_URL`) y, para NDVI, **Copernicus** (`DEV_COPERNICUS_CLIENT_ID/SECRET`). El clima (Open-Meteo) no necesita llave.
11
  > - **Asistente** → **Groq** (`DEV_GROQ_API_KEY`).
12
+ > - **Conteo** → **EN DESARROLLO** (standby): la pestaña muestra *"Módulo en preparación"*. Se habilita cuando el **repo del modelo** (proyecto separado) publique el artefacto. Para demostrar el flujo con datos de prueba (mock) — ver §3.5.
13
 
14
  ---
15
 
docs/reference/description_proyecto_agrovision.md CHANGED
@@ -4,11 +4,10 @@
4
  >
5
  > **Stack confirmado:** UI en **Shiny for Python**, backend/gateway en **FastAPI**, base de datos en **Supabase (PostgreSQL + PostGIS + Storage + Queues/PGMQ)**, agente conversacional con **Groq (Llama 3)** y teledetección con **Copernicus Sentinel-2 / NASA POWER / Open-Meteo**. Despliegue gratuito: **ShinyApps.io + Render + Supabase**.
6
  >
7
- > **Licencia y modelo:** AgroVisión es **open-source bajo AGPL-3.0** (lo que permite usar **YOLO26**). El modelo de conteo es **agnóstico**: la app consume el artefacto `agrovision-plantcount` (multi-candidato YOLO26/RF-DETR) por **contrato**, vía un adaptador de inferencia. El **módulo de conteo arranca en _standby_** (flag `COUNTING_ENABLED=false`) hasta que el [repo del modelo](description_proyecto_modelo_conteo_plantas.md) publique el artefacto.
8
  >
9
  > **Documentos relacionados:**
10
- > - MVP reducido: [`description_proyecto_agrovision_mvp.md`](description_proyecto_agrovision_mvp.md)
11
- > - Repo del modelo de conteo (produce los pesos predeterminados): [`description_proyecto_modelo_conteo_plantas.md`](description_proyecto_modelo_conteo_plantas.md)
12
  > - Investigación base: [`Plan Detallado Data Science Agrícola.md`](../investigation/Plan%20Detallado%20Data%20Science%20Agr%C3%ADcola.md)
13
  > - Mockup interactivo: [`agrovisi_n_spa_prototype.html`](../investigation/agrovisi_n_spa_prototype.html)
14
 
@@ -453,7 +452,7 @@ uv run rsconnect deploy shiny ./frontend --name <cuenta> --title AgroVision-UI
453
 
454
  ### 7.4 Gestión del Modelo Predeterminado
455
 
456
- * AgroVisión **no entrena**: consume pesos producidos por el [repo del modelo de conteo](description_proyecto_modelo_conteo_plantas.md).
457
  * El artefacto `agrovision-plantcount-v2.0.0.onnx` (RF-DETR-Nano exportado a ONNX) se **publica en Hugging Face Hub** y se descarga con `hf_hub_download` durante el build de la imagen del backend, copiándose a `/app/models/` (`MODEL_VERSION` fija la trazabilidad). El nombre es de **marca, desacoplado de la arquitectura** interna.
458
  * **Contrato de inferencia** que el worker espera: entrada = tile RGB; salida = `{"boxes":[[x1,y1,x2,y2,conf,cls]], "count":int}` compatible con `plant_counts.result_json`.
459
 
 
4
  >
5
  > **Stack confirmado:** UI en **Shiny for Python**, backend/gateway en **FastAPI**, base de datos en **Supabase (PostgreSQL + PostGIS + Storage + Queues/PGMQ)**, agente conversacional con **Groq (Llama 3)** y teledetección con **Copernicus Sentinel-2 / NASA POWER / Open-Meteo**. Despliegue gratuito: **ShinyApps.io + Render + Supabase**.
6
  >
7
+ > **Licencia y modelo:** AgroVisión es **open-source bajo AGPL-3.0** (lo que permite usar **YOLO26**). El modelo de conteo es **agnóstico**: la app consume el artefacto `agrovision-plantcount` (multi-candidato YOLO26/RF-DETR) por **contrato**, vía un adaptador de inferencia. El **módulo de conteo arranca en _standby_** (flag `COUNTING_ENABLED=false`) hasta que el **repo del modelo** (proyecto separado) publique el artefacto.
8
  >
9
  > **Documentos relacionados:**
10
+ > - El modelo de conteo se desarrolla en un **repo separado** (produce los pesos predeterminados).
 
11
  > - Investigación base: [`Plan Detallado Data Science Agrícola.md`](../investigation/Plan%20Detallado%20Data%20Science%20Agr%C3%ADcola.md)
12
  > - Mockup interactivo: [`agrovisi_n_spa_prototype.html`](../investigation/agrovisi_n_spa_prototype.html)
13
 
 
452
 
453
  ### 7.4 Gestión del Modelo Predeterminado
454
 
455
+ * AgroVisión **no entrena**: consume pesos producidos por el **repo del modelo de conteo** (proyecto separado).
456
  * El artefacto `agrovision-plantcount-v2.0.0.onnx` (RF-DETR-Nano exportado a ONNX) se **publica en Hugging Face Hub** y se descarga con `hf_hub_download` durante el build de la imagen del backend, copiándose a `/app/models/` (`MODEL_VERSION` fija la trazabilidad). El nombre es de **marca, desacoplado de la arquitectura** interna.
457
  * **Contrato de inferencia** que el worker espera: entrada = tile RGB; salida = `{"boxes":[[x1,y1,x2,y2,conf,cls]], "count":int}` compatible con `plant_counts.result_json`.
458
 
docs/reference/description_proyecto_agrovision_mvp.md DELETED
@@ -1,237 +0,0 @@
1
- # Documento de Definición Técnica — AgroVisión MVP (Conteo por Dron)
2
-
3
- > **Propósito del documento:** Definir el alcance mínimo viable (MVP) de AgroVisión, centrado en el flujo de **carga de ortomosaico + conteo de plantas con modelo predeterminado**, más una pestaña de **credenciales efímeras**. Es la primera entrega del proyecto y la base sobre la que se construye la [plataforma completa](description_proyecto_agrovision.md).
4
- >
5
- > **Stack MVP:** UI en **Shiny for Python**, inferencia **síncrona** con un modelo predeterminado **agnóstico** (multi-candidato YOLO26/RF-DETR, definido en el repo del modelo), **sin base de datos obligatoria** (modo efímero). Despliegue gratuito en un solo servicio.
6
- >
7
- > **Standby:** el módulo de conteo **arranca en _standby_** (`COUNTING_ENABLED=false`) hasta que el [repo del modelo](description_proyecto_modelo_conteo_plantas.md) publique `agrovision-plantcount` en Hugging Face Hub. Licencia: AgroVisión **open-source AGPL-3.0** (permite YOLO26).
8
- >
9
- > **Documentos relacionados:**
10
- > - Plataforma completa (objetivo final): [`description_proyecto_agrovision.md`](description_proyecto_agrovision.md)
11
- > - Repo del modelo de conteo (produce los pesos): [`description_proyecto_modelo_conteo_plantas.md`](description_proyecto_modelo_conteo_plantas.md)
12
-
13
- ---
14
-
15
- ## 0. Resumen Ejecutivo
16
-
17
- El MVP de AgroVisión valida el **núcleo de valor** de la plataforma con la mínima complejidad: el usuario sube un ortomosaico RGB de dron y obtiene, en segundos, el **conteo de plantas, la densidad estimada y un overlay con las detecciones**, usando un modelo de visión **predeterminado** (entrenado en un repo aparte). No requiere base de datos, ni cuentas externas para la función principal.
18
-
19
- * **Propósito:** Demostrar el conteo automatizado de plantas de extremo a extremo, desplegable en capa gratuita, antes de incorporar teledetección y agente conversacional.
20
- * **Usuarios Objetivos:** Agrónomos y productores que necesitan estimar densidad/emergencia de un lote.
21
- * **Casos de Uso Core:**
22
- 1. El usuario **sube un ortomosaico RGB** del dron (`ui.input_file`).
23
- 2. El sistema ejecuta el **modelo de conteo predeterminado** (agnóstico: YOLO26/RF-DETR) y devuelve conteo, densidad (pl/Ha), malezas y % de fallas, con el overlay de *bounding boxes*.
24
- 3. El usuario revisa una pestaña de **Credenciales & APIs**: presente como base para módulos futuros (satélite, RAG), con el aviso de que **nada se guarda y que refrescar borra todo**.
25
-
26
- > **Alcance excluido del MVP (roadmap):** teledetección Sentinel-2/NDVI, agente RAG (Groq), persistencia en Supabase, procesamiento asíncrono con PGMQ. Todo esto entra en la [plataforma completa](description_proyecto_agrovision.md).
27
-
28
- ---
29
-
30
- ## 1. Arquitectura de Componentes
31
-
32
- El MVP usa una topología **simplificada**: una UI Shiny y un backend FastAPI con inferencia **síncrona** (sin worker ni cola). El modelo va empaquetado en la imagen del backend.
33
-
34
- ```mermaid
35
- flowchart TD
36
- classDef frontend fill:#BFDBFE,stroke:#2563EB,color:#1E3A8A
37
- classDef gateway fill:#FDE047,stroke:#EAB308,color:#713F12
38
- classDef service fill:#BBF7D0,stroke:#16A34A,color:#14532D
39
-
40
- UI["💻 UI — Shiny for Python<br/>2 nav_panel: Conteo · Credenciales<br/>ui.input_file · estado efímero<br/>Host: ShinyApps.io (Free)"]:::frontend
41
-
42
- GW["🔀 Backend — FastAPI<br/>POST /api/count (SÍNCRONO)<br/>Inferencia en proceso<br/>Host: Render (Free)"]:::gateway
43
-
44
- MODEL["🧠 RF-DETR-Nano (.pt / ONNX)<br/>Modelo PREDETERMINADO<br/>Empaquetado en la imagen"]:::service
45
-
46
- UI <-->|"HTTPS multipart (imagen)"| GW
47
- GW -->|"Carga al iniciar"| MODEL
48
- ```
49
-
50
- ### 1.1 Glosario de Módulos
51
-
52
- | Componente | Responsabilidad | Tecnologías | Despliegue |
53
- | :--- | :--- | :--- | :--- |
54
- | **UI (Shiny)** | Carga de imagen, disparo del conteo, render de métricas y overlay. Estado **efímero** en memoria. | Shiny for Python, `httpx`, Pillow | ShinyApps.io Free |
55
- | **Backend (FastAPI)** | Recibe la imagen, ejecuta inferencia **síncrona**, devuelve conteo + overlay (imagen anotada en base64 o multipart). | FastAPI, **adaptador de inferencia** (onnxruntime o `ultralytics` según arquitectura), OpenCV | Render Free |
56
- | **Modelo predeterminado** | Pesos de **solo inferencia**, cargados vía adaptador (**agnóstico**: YOLO26/RF-DETR). | `agrovision-plantcount` (ONNX) | Artefacto del repo del modelo (Hugging Face Hub); AGPL-3.0 aceptada |
57
-
58
- > **Alternativa monolítica:** para el MVP es válido empaquetar UI + inferencia en un **único contenedor** (Shiny llamando al modelo en proceso) y desplegarlo en un solo host Docker (p. ej. Render o Hugging Face Spaces). La versión de dos servicios se prefiere si se quiere reutilizar el backend en la plataforma completa.
59
-
60
- ---
61
-
62
- ## 2. Flujo de Datos
63
-
64
- ### 2.1 Orígenes y Destinos
65
-
66
- * **Entradas:** ortomosaico RGB (`ui.input_file`); opcionalmente parámetros de vuelo (altura, GSD) para convertir conteo a densidad; área del lote (Ha) ingresada manualmente.
67
- * **Salidas:** conteo total, densidad pl/Ha, # malezas, % fallas, imagen con *bounding boxes*. **Nada se persiste**: todo vive en la sesión y se descarta al refrescar.
68
-
69
- ### 2.2 Grafo Reactivo (síncrono)
70
-
71
- ```mermaid
72
- flowchart LR
73
- A["input.file_upload"] --> B["@reactive.calc validación"]
74
- B --> C["POST /api/count (multipart)"]
75
- C --> D["FastAPI: inferencia RF-DETR-Nano en proceso"]
76
- D --> E["conteo + overlay (base64)"]
77
- E --> F["@render.image / @render.ui métricas"]
78
- ```
79
-
80
- ---
81
-
82
- ## 3. Modelo de Datos
83
-
84
- **El MVP no requiere base de datos.** Toda la información de una corrida (imagen, conteo, métricas) vive en `reactive.value` de la sesión Shiny y se descarta al cerrar/refrescar.
85
-
86
- > **Persistencia opcional (futuro):** si el usuario configura su propio Supabase, se reutilizaría la tabla `plant_counts` definida en la [plataforma completa](description_proyecto_agrovision.md#3-modelo-de-datos-bases-de-datos). En el MVP queda fuera de alcance.
87
-
88
- ---
89
-
90
- ## 4. Contratos de API
91
-
92
- | Método | Path | Descripción | Entrada | Respuesta |
93
- | :--- | :--- | :--- | :--- | :--- |
94
- | `GET` | `/api/status` | Healthcheck + versión del modelo. | — | `{"status":"ok","model":"agrovision-plantcount","version":"2.0.0"}` |
95
- | `POST` | `/api/count` | Inferencia **síncrona** de conteo. | `multipart/form-data` (imagen) + `area_ha?` (form) | `{"count":124,"density":72400,"weeds":12,"failures":1.2,"confidence":0.91,"overlay_b64":"<png>"}` |
96
-
97
- > **CORS:** `CORSMiddleware` con `allow_origins=[<ShinyApps.io>, "http://localhost:8000"]`. En el MVP la función principal (conteo) **no requiere llaves de usuario**, porque el modelo corre local; las cabeceras `X-User-*` se reservan para módulos futuros.
98
-
99
- ---
100
-
101
- ## 5. Lógica de Negocio
102
-
103
- ### 5.1 Conteo e Inferencia
104
-
105
- El backend carga el modelo (ONNX) una sola vez al iniciar mediante un **adaptador de inferencia** — **agnóstico** a la arquitectura (onnxruntime, o `ultralytics` si el ganador es YOLO). Por cada imagen ejecuta detección (YOLO26/RF-DETR son **NMS-free**), cuenta cajas por clase (planta/arbusto, maleza), y para ortomosaicos grandes aplica *tiling* para respetar la RAM de Render (512 MB). **Mientras el módulo esté en standby**, este flujo está deshabilitado.
106
-
107
- ### 5.2 Densidad y GSD
108
-
109
- $$Densidad_{pl/Ha} = \frac{Conteo_{plantas}}{Área_{Ha}}$$
110
-
111
- El área puede ingresarse manualmente o derivarse del GSD y la cobertura de la imagen:
112
-
113
- $$GSD = \frac{S_w \times H}{f \times I_w}$$
114
-
115
- donde $S_w$ = ancho de sensor (mm), $H$ = altura de vuelo (m), $f$ = focal (mm), $I_w$ = ancho de imagen (px).
116
-
117
- ### 5.3 Reglas de Validación
118
-
119
- 1. **Formato/tamaño:** solo `JPG/PNG/TIFF`; límite de tamaño en `ui.input_file` (p. ej. ≤ 50 MB) para no agotar RAM.
120
- 2. **Confianza mínima:** detecciones bajo umbral (p. ej. `conf < 0.25`) se descartan.
121
- 3. **Fallas de siembra:** se estiman como huecos en hileras detectadas (heurística sobre el patrón de cajas).
122
-
123
- ---
124
-
125
- ## 6. Interfaz de Usuario (UI/UX)
126
-
127
- UI con **2 pestañas** (`ui.page_navbar`):
128
-
129
- 1. **Detección Dron (Conteo)** — **arranca en _standby_** (aviso "Módulo en preparación") hasta `COUNTING_ENABLED=true`. Activo: zona de carga (`ui.input_file`), botón "Iniciar Conteo", visualizador del overlay con *bounding boxes*, panel de métricas (total, densidad, malezas, fallas, confianza). El modelo es **predeterminado** y **agnóstico** (YOLO26/RF-DETR), creado en el repo aparte; cultivo inicial: arándano.
130
- 2. **Credenciales & APIs** — formularios (deshabilitados/placeholder para satélite y RAG en el MVP) con el aviso de efimeralidad.
131
-
132
- ### 6.1 Layout (Wireframe ASCII)
133
-
134
- ```text
135
- ┌──────────────────────────────────────────────────────────────────────┐
136
- │ 🌱 AgroVisión MVP [👤 Agrónomo] │
137
- ├──────────────┬───────────────────────────────────────────────────────┤
138
- │ ▸ Dron YOLO │ [📁 Subir ortomosaico] [▶ Iniciar Conteo] │
139
- │ ▸ Credenciales│ ┌───────────────────────┐ ┌─ Métricas ───────────┐ │
140
- │ │ │ Overlay con │ │ Total: 124 │ │
141
- │ │ │ bounding boxes │ │ Densidad: 72,400 /Ha │ │
142
- │ │ │ (Signed/base64) │ │ Malezas: 12 │ │
143
- │ │ └───────────────────────┘ │ Fallas: 1.2% │ │
144
- │ │ └──────────────────────┘ │
145
- └──────────────┴───────────────────────────────────────────────────────┘
146
- ```
147
-
148
- ### 6.2 Efimeralidad (idéntica a la plataforma completa)
149
-
150
- * Estado en `reactive.value` (memoria de sesión). Sin `localStorage`, sin cookies persistentes.
151
- * **Refrescar la página = nueva sesión = todo borrado.** La pestaña de Credenciales lo advierte:
152
- > ⚠️ *Tus credenciales y resultados se usan solo durante esta sesión. **No se guardan ni almacenan.** Si actualizas o cierras la página, todo se borrará.*
153
-
154
- ---
155
-
156
- ## 7. Configuración de Entornos y Despliegue
157
-
158
- ### 7.1 Variables de Entorno (`.env.example`)
159
-
160
- ```bash
161
- APP_ENV=development
162
- LOG_LEVEL=info
163
-
164
- # UI (Shiny)
165
- SHINY_PORT=8001
166
- API_BASE_URL=http://localhost:8000 # En prod: URL del backend en Render
167
-
168
- # Backend (FastAPI)
169
- API_PORT=8000
170
- ALLOWED_ORIGINS=http://localhost:8001,https://<tu-app>.shinyapps.io
171
-
172
- # Modelo predeterminado (descargado de Hugging Face Hub en el build)
173
- MODEL_PATH=/app/models/agrovision-plantcount-v2.0.0.onnx
174
- MODEL_VERSION=2.0.0
175
- HF_MODEL_REPO=<org>/agrovision-plantcount
176
- COUNTING_ENABLED=false # standby hasta que el modelo esté publicado
177
- ```
178
-
179
- ### 7.2 Docker (Local)
180
-
181
- ```yaml
182
- # docker-compose.yml (MVP)
183
- services:
184
- api:
185
- build: ./backend
186
- ports: ["8000:8000"]
187
- env_file: .env
188
- volumes: ["./models:/models:ro", "./sample_data:/data:ro"]
189
- ui:
190
- build: ./frontend
191
- ports: ["8001:8001"]
192
- environment: ["API_BASE_URL=http://api:8000"]
193
- ```
194
-
195
- > Incluye `sample_data/` con ortomosaicos de ejemplo para probar el conteo sin credenciales. El modelo se monta read-only desde `models/`.
196
-
197
- ### 7.3 Producción (Capa Gratuita)
198
-
199
- | Componente | Plataforma | Límites | Caveat |
200
- | :--- | :--- | :--- | :--- |
201
- | **UI (Shiny)** | [ShinyApps.io Free](https://support.posit.co/hc/en-us/articles/217592947-What-are-the-limits-of-the-shinyapps-io-Free-plan) | 5 apps · 25 h activas/mes | App ASGI nativa; `rsconnect deploy shiny`. |
202
- | **Backend** | [Render Free](https://render.com/docs/free) | 512 MB · duerme a 15 min · 750 h/mes | *Cold start* 30–60 s; RF-DETR-Nano (ONNX ligero) cabe holgado. |
203
-
204
- ```powershell
205
- # UI -> ShinyApps.io
206
- uv run rsconnect deploy shiny ./frontend --name <cuenta> --title AgroVision-MVP
207
-
208
- # Backend -> Render (Dockerfile detectado automáticamente)
209
- ```
210
-
211
- > **Opción aún más simple:** desplegar el MVP como **monolito** (Shiny + inferencia en proceso) en un único contenedor Docker (Render o Hugging Face Spaces), evitando CORS y dos servicios.
212
-
213
- ### 7.4 Modelo Predeterminado
214
-
215
- El MVP **no entrena**. Consume `agrovision-plantcount-v2.0.0.onnx` (arquitectura según el repo del modelo: YOLO26/RF-DETR) producido por el [repo del modelo](description_proyecto_modelo_conteo_plantas.md) y **publicado en Hugging Face Hub**; se descarga con `hf_hub_download` en el build y se carga vía el adaptador de inferencia. Contrato de inferencia: entrada = tile RGB; salida = `{"boxes":[[x1,y1,x2,y2,conf,cls]], "count":int}`.
216
-
217
- ---
218
-
219
- ## 8. Camino del MVP a la Plataforma Completa
220
-
221
- | Capacidad | MVP | Plataforma completa |
222
- | :--- | :--- | :--- |
223
- | Conteo por dron (modelo predeterminado, agnóstico) | ✅ | ✅ |
224
- | Credenciales efímeras (BYOK) | ✅ (placeholder) | ✅ (activas) |
225
- | Inferencia | Síncrona en proceso | Asíncrona (PGMQ + worker) |
226
- | Teledetección Sentinel-2 / NDVI | ❌ | ✅ |
227
- | Agente RAG (Groq/Llama 3) | ❌ | ✅ |
228
- | Persistencia (Supabase PostGIS + Storage) | ❌ | ✅ |
229
- | Módulos UI | 2 | 5 |
230
-
231
- El MVP comparte la misma base de código de UI y backend; activar los módulos restantes es incremental.
232
-
233
- ---
234
-
235
- ## Apéndice — Fuentes
236
-
237
- Basado en [`Plan Detallado Data Science Agrícola.md`](../investigation/Plan%20Detallado%20Data%20Science%20Agr%C3%ADcola.md) y el [mockup](../investigation/agrovisi_n_spa_prototype.html). Límites de capa gratuita verificados: [ShinyApps.io](https://support.posit.co/hc/en-us/articles/217592947-What-are-the-limits-of-the-shinyapps-io-Free-plan), [Render](https://render.com/docs/free).
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
docs/reference/description_proyecto_modelo_conteo_plantas.md DELETED
@@ -1,297 +0,0 @@
1
- # Documento de Definición Técnica — Modelo de Conteo de Plantas (Repo Separado)
2
-
3
- > **Propósito del documento:** Definir el repositorio **independiente** cuyo único objetivo es **crear, entrenar, evaluar y exportar el modelo de visión** que cuenta plantas a partir de imágenes RGB de **dron** (y árboles/copas desde **satélite de alta resolución**). Produce y publica **UN solo artefacto** (el mejor candidato) que consume AgroVisión; no expone una app productiva.
4
- >
5
- > **Enfoque multi-candidato (se publica el mejor):** se entrenan/evalúan **YOLO26** (Ultralytics, **AGPL-3.0**, NMS-free, detect/seg), **RF-DETR** (Roboflow, **Apache 2.0**, NMS-free, detect/seg) y **DINOv3** (backbone SSL + satelital); gana el de **menor MAE de conteo** que cumpla tamaño/latencia, y **solo ese se publica**. **DeepForest** (MIT) es baseline para árboles en satélite. Anotación con **SAM**.
6
- >
7
- > **Licencia:** AgroVisión **acepta AGPL-3.0** (la app es open-source), por lo que **YOLO26 es usable**. La licencia efectiva del artefacto publicado depende del candidato ganador (AGPL si YOLO26; Apache si RF-DETR) y se declara en la *model card*.
8
- >
9
- > **Multi-cultivo (arándano primero):** el modelo es **multi-clase/multi-cultivo**. Foco inicial: **arándano** (arbustos en hilera — relevante para Hortifrut). Se generaliza a otros cultivos cambiando **dataset + lista de clases**.
10
- >
11
- > **Publicación:** **1 artefacto** `agrovision-plantcount-vX.Y.Z.onnx` en **Hugging Face Hub**; AgroVisión lo descarga en su **build de Docker** (`hf_hub_download`) y lo consume por **contrato** (nombre de marca **desacoplado de la arquitectura**). Enfoque **notebooks-first**.
12
- >
13
- > **Documentos relacionados:** [`description_proyecto_agrovision.md`](description_proyecto_agrovision.md) · [`architecture_modelo_conteo_plantas.md`](../architect/architecture_modelo_conteo_plantas.md) · [`plan_modelo_conteo_plantas.md`](../plan/plan_modelo_conteo_plantas.md) · [`tareas_modelo_conteo_plantas.md`](../task/tareas_modelo_conteo_plantas.md) · [`Plan Detallado`](../investigation/Plan%20Detallado%20Data%20Science%20Agr%C3%ADcola.md)
14
-
15
- ---
16
-
17
- ## 0. Resumen Ejecutivo
18
-
19
- Este repositorio implementa el **pipeline de Machine Learning** para el conteo automatizado de plantas, con **dos modalidades**:
20
-
21
- 1. **Dron RGB (primaria):** conteo de plantas/arbustos individuales en ortomosaicos de baja altitud (~15–30 m) con un **detector** (candidatos: YOLO26 / RF-DETR). Cultivo inicial: **arándano**.
22
- 2. **Satélite de alta resolución (secundaria):** conteo de árboles/copas en imágenes sub-métricas (MAXAR/Planet) con **DeepForest** y/o **DINOv3 satelital**.
23
-
24
- > ⚠️ **Resolución:** el conteo individual requiere alta resolución (dron, o satélite sub-métrico). El **Sentinel-2 gratuito (10 m) NO sirve** para contar plantas; solo índices/área (eso vive en la teledetección de AgroVisión).
25
-
26
- * **Propósito:** Producir y **publicar el mejor modelo** de conteo (multi-candidato, multi-cultivo) como artefacto **predeterminado de solo inferencia** para AgroVisión.
27
- * **Estrategia "1 modelo, el mejor":** se entrenan varios candidatos (YOLO26, RF-DETR; opc. variantes seg) y `evaluate.py` **selecciona el de menor MAE de conteo** que cumpla tamaño/latencia en CPU; **solo ese se publica**. El satélite reusa pesos de **DeepForest** (no es artefacto propio).
28
- * **Multi-cultivo:** clases configurables; **arándano** primero, luego maíz/girasol/etc. (ver §2.3).
29
- * **Metodología notebooks-first:** (1) experimentar en notebooks; (2) endurecer en `.py`; (3) entrenar/evaluar/seleccionar/exportar/publicar.
30
- * **Entregable principal:** `agrovision-plantcount-vX.Y.Z.onnx` en **Hugging Face Hub** + *model card* (con arquitectura, licencia, cultivo, métricas) + contrato.
31
-
32
- > **Frontera de responsabilidad:** este repo **entrena y publica**; AgroVisión **solo infiere** (agnóstico a la arquitectura, por contrato). YOLO26 y RF-DETR son **NMS-free**, así que el contrato no requiere NMS.
33
-
34
- ---
35
-
36
- ## 1. Arquitectura del Pipeline (Modular, Notebooks-First)
37
-
38
- ```mermaid
39
- flowchart TD
40
- classDef nb fill:#FEF3C7,stroke:#D97706,color:#7C2D12
41
- classDef data fill:#BFDBFE,stroke:#2563EB,color:#1E3A8A
42
- classDef proc fill:#BBF7D0,stroke:#16A34A,color:#14532D
43
- classDef model fill:#FDE047,stroke:#EAB308,color:#713F12
44
- classDef out fill:#E9D5FF,stroke:#7C3AED,color:#4C1D95
45
-
46
- subgraph EXP["🧪 Experimentación (notebooks/ — PRIMERO)"]
47
- NB1["01_explore_data.ipynb"]:::nb
48
- NB2["02_annotate_sam.ipynb<br/>SAM → COCO/YOLO"]:::nb
49
- NB3["03_train_candidates.ipynb<br/>PoC YOLO26 + RF-DETR (Colab GPU)"]:::nb
50
- NB4["04_satellite_deepforest_dinov3.ipynb"]:::nb
51
- end
52
-
53
- D1["📦 Datasets por cultivo<br/>Arándano · Roboflow · Kaggle · DeepForest"]:::data
54
- A1["✂️ Anotación SAM → COCO + YOLO<br/>(COCO para RF-DETR, YOLO para YOLO26)"]:::proc
55
- P1["🔧 Preprocesamiento<br/>tiling por GSD · augmentations · splits · clases por cultivo"]:::proc
56
-
57
- M1["🧠 Candidato A — YOLO26 (AGPL)<br/>detect/seg, NMS-free"]:::model
58
- M2["🧠 Candidato B — RF-DETR (Apache)<br/>detect/seg, NMS-free"]:::model
59
- M3["🧠 Track C — DINOv3 / DeepForest<br/>dominio + satélite (árboles)"]:::model
60
-
61
- E1["📊 Evaluación + SELECCIÓN<br/>menor MAE / tamaño / latencia → el mejor"]:::proc
62
- X1["🚀 Exportación + Publicación<br/>1 artefacto .onnx → Hugging Face Hub"]:::out
63
- AV["⬇️ AgroVisión (build: hf_hub_download)"]:::out
64
-
65
- EXP -.promueve lógica validada.-> D1
66
- D1 --> A1 --> P1
67
- P1 --> M1 & M2 & M3
68
- M1 & M2 & M3 --> E1 --> X1 --> AV
69
- ```
70
-
71
- ### 1.1 Glosario de Etapas
72
-
73
- | Etapa | Responsabilidad | Tecnologías | Salida |
74
- | :--- | :--- | :--- | :--- |
75
- | **Experimentación (notebooks)** | Validar viabilidad por cultivo. | Jupyter, Colab/Kaggle (GPU T4) | Notebooks + hallazgos |
76
- | **Ingesta** | Descargar/versionar datasets por cultivo. | `roboflow`, `kagglehub`, `deepforest`, DVC (opc.) | `data/raw/<cultivo>/` |
77
- | **Anotación** | Etiquetado semi-automático. | **SAM**, OpenCV | **COCO** (RF-DETR) + **YOLO** (YOLO26) |
78
- | **Preprocesamiento** | Tiling por GSD, augmentations, splits, clases. | `albumentations`, `supervision` | `data/processed/<cultivo>/` |
79
- | **Entrenamiento (candidatos)** | *Fine-tuning* de YOLO26 y RF-DETR. | **`ultralytics`** (YOLO26), **`rfdetr`** | checkpoints por candidato |
80
- | **Evaluación + selección** | Métricas + elegir el mejor. | supervision, scikit-learn | candidato ganador |
81
- | **Exportación / publicación** | ONNX + model card + **HF Hub**. | `onnx`, `huggingface_hub` | `agrovision-plantcount-*.onnx` |
82
-
83
- ---
84
-
85
- ## 2. Flujo de Datos e Integración
86
-
87
- ### 2.1 Orígenes y Destinos
88
- * **Entradas:** datasets aéreos/satelitales por cultivo (RGB), parámetros de captura (GSD), anotaciones SAM.
89
- * **Salidas:** dataset anotado (COCO + YOLO), checkpoints por candidato, **1** `.onnx` publicado, métricas y *model card*.
90
-
91
- ### 2.2 Dónde Conseguir las Imágenes (sin dataset propio)
92
-
93
- | Fuente | Cultivo/Modalidad | Acceso |
94
- | :--- | :--- | :--- |
95
- | **Roboflow Universe** (aerial/agriculture) | Multi-cultivo, export **COCO y YOLO** | [universe.roboflow.com](https://universe.roboflow.com/browse/aerial/agriculture) |
96
- | **Arándano — estudios con dron** | *Bush Model* + *Berry Model* (YOLO); BerryNet | [arXiv 2501.02344](https://arxiv.org/abs/2501.02344) |
97
- | **Kaggle** | Plant Detection & Counting (maíz/girasol), Plantations | `kagglehub` |
98
- | **CitDet** | Cítricos (frutos) | [arXiv 2309.05645](https://arxiv.org/html/2309.05645v3) |
99
- | **DeepForest / NEON** | Árboles (aéreo/satélite, MIT) | [github.com/weecology/DeepForest](https://github.com/weecology/DeepForest) |
100
- | **MAXAR Open Data / Planet NICFI** | Satélite sub-métrico (árboles) | Programas gratuitos |
101
- | **Sentinel-2 / Copernicus** | ⚠️ Solo índices/área (no conteo) | API STAC |
102
-
103
- > **Datos propios de Hortifrut:** cuando existan ortomosaicos de campos de arándano, se anotan con SAM y se integran como dataset prioritario.
104
-
105
- ### 2.3 Cultivos Objetivo (multi-cultivo configurable)
106
-
107
- El modelo es **multi-clase**; cada cultivo es un dataset + `data.yaml`/`categories` propio. Cultivos validados en la literatura para conteo con dron:
108
-
109
- | Grupo | Cultivos | Paradigma |
110
- | :--- | :--- | :--- |
111
- | **Berries (foco Hortifrut)** | **Arándano** (arbustos; opc. bayas/yield), frambuesa, mora, fresa | Detección (arbusto) / densidad (bayas) |
112
- | **Hilera / plántulas** | Maíz, girasol, remolacha, sorgo, algodón, soya, trigo, arroz, frijol, papa | Detección (stand count) |
113
- | **Frutales / árboles** | Cítricos, palma, vid (racimos) | Detección / DeepForest |
114
- | **Genérico denso** | Escenas muy densas (bayas, espigas) | Densidad (tipo TasselNetV4) |
115
-
116
- > **Orden recomendado:** (1) **arándano** (detección de arbustos en hilera, MVP del modelo); (2) generalizar a maíz/girasol; (3) opcional: track de **densidad** para conteo de bayas/yield.
117
-
118
- ### 2.4 GSD
119
-
120
- $$GSD = \frac{S_w \times H}{f \times I_w}$$
121
-
122
- $S_w$ ancho de sensor (mm), $H$ altura (m), $f$ focal (mm), $I_w$ ancho de imagen (px). El GSD guía el **tamaño de *tile*** (cada planta/arbusto con suficientes píxeles). En arándano, la altura de vuelo se ajusta para que cada arbusto sea claramente resoluble.
123
-
124
- ---
125
-
126
- ## 3. Anotación Acelerada (SAM → COCO + YOLO)
127
-
128
- **SAM (Segment Anything)** genera máscaras/cajas desde clics o cajas. Se exporta a **ambos formatos**: **COCO** (`_annotations.coco.json`, para RF-DETR) y **YOLO** (`.txt`, para YOLO26). Roboflow puede exportar a los dos. **DINOv3** ayuda con *pre-clustering* (features densas) en cultivos de geometría repetitiva (hileras de arándano).
129
-
130
- > **Salida:** dataset anotado por cultivo, en COCO y YOLO, listo para entrenar cualquier candidato.
131
-
132
- ---
133
-
134
- ## 4. Candidatos de Modelo (se publica el mejor)
135
-
136
- ### 4.1 Candidato A — YOLO26 (Ultralytics, AGPL-3.0)
137
-
138
- **YOLO26** (ene 2026): NMS-free end-to-end, unifica detect/seg/pose, **~43 % más rápido en CPU**, export ONNX. Variante **nano** (`yolo26n`) para CPU. **Habilitado** porque AgroVisión acepta **AGPL-3.0** (app open-source). [Docs](https://docs.ultralytics.com/models/yolo26)
139
-
140
- ### 4.2 Candidato B — RF-DETR (Roboflow, Apache 2.0)
141
-
142
- **RF-DETR** (ICLR 2026): Detection Transformer real-time, **NMS-free**, **Apache 2.0** (permisivo), variante **Nano** para CPU, detect + **RF-DETR-Seg**. Alternativa si se quisiera evitar AGPL en el futuro. [GitHub](https://github.com/roboflow/rf-detr)
143
-
144
- ### 4.3 Track C — DINOv3 (dominio + satélite)
145
-
146
- **DINOv3** (Meta, comercial-permisiva): backbone congelado SOTA sin fine-tuning + **backbone satelital MAXAR**. Robustez de dominio/estación y conteo de árboles/copa en satélite. [GitHub](https://github.com/facebookresearch/dinov3)
147
-
148
- ### 4.4 Baseline Satélite — DeepForest (MIT)
149
-
150
- **DeepForest**: conteo de copas en RGB aéreo, modelo NEON preentrenado. Baseline del track satelital; reusa pesos publicados. [GitHub](https://github.com/weecology/DeepForest)
151
-
152
- ### 4.5 Tabla Comparativa
153
-
154
- | Atributo | YOLO26-nano (A) | RF-DETR-Nano (B) | DINOv3 (C) | DeepForest |
155
- | :--- | :--- | :--- | :--- | :--- |
156
- | **Licencia** | AGPL-3.0 | Apache 2.0 | Comercial-permisiva | MIT |
157
- | **Tarea** | detect/seg | detect/seg | backbone SSL | detect copas |
158
- | **Post-proceso** | NMS-free | NMS-free | cabezal | RetinaNet |
159
- | **Formato datos** | YOLO | COCO | — | — |
160
- | **CPU/ONNX** | ✅ | ✅ | GPU | CPU/GPU |
161
- | **Rol** | **Candidato (gana si menor MAE)** | **Candidato** | Dominio/satélite | Baseline satélite |
162
-
163
- > **Criterio de selección:** se entrena cada candidato sobre el cultivo objetivo; gana el de **menor MAE de conteo** cumpliendo tamaño/latencia en CPU. La *model card* declara el ganador, su `architecture` y su licencia.
164
-
165
- ---
166
-
167
- ## 5. Entrenamiento, Hiperparámetros y Selección
168
-
169
- ### 5.1 Estrategia (notebooks-first, multi-candidato, multi-cultivo)
170
-
171
- 1. **PoC en notebooks** por cultivo (arándano primero): entrenar YOLO26 y RF-DETR cortos en Colab/Kaggle.
172
- 2. **Promoción a `.py`** con config declarativa y semillas fijas.
173
- 3. **Transfer learning** desde pesos COCO de cada candidato; *tiling* por GSD + augmentations.
174
- 4. **Selección**: comparar candidatos por MAE/tamaño/latencia → publicar el mejor.
175
-
176
- ### 5.2 Configuración de Referencia
177
-
178
- ```yaml
179
- # configs/train.yaml (referencia)
180
- crop: blueberry # cultivo objetivo (multi-cultivo)
181
- candidates: [yolo26n, rfdetr_nano]
182
- classes: ["arbusto"] # arándano: 1 clase (arbusto). Multi-clase si aplica
183
- imgsz: 640 # YOLO26; RF-DETR usa múltiplos de 56 (p. ej. 560)
184
- epochs: 100
185
- seed: 42
186
- ```
187
-
188
- ### 5.3 Métricas y Selección
189
- * **Detección:** Precision, Recall, mAP@0.5, mAP@0.5-0.95, F1.
190
- * **Conteo (negocio):** **MAE/RMSE** entre conteo predicho y real → **criterio de selección**.
191
- * **Por cultivo:** métricas reportadas por cultivo en `metrics.json`.
192
-
193
- ---
194
-
195
- ## 6. Contrato de Inferencia y Publicación (Handoff a AgroVisión)
196
-
197
- ### 6.1 Exportación a ONNX (según el candidato ganador)
198
-
199
- ```bash
200
- # YOLO26 (si gana)
201
- uv run yolo detect export model=runs/.../best.pt format=onnx opset=12 simplify=True
202
- # RF-DETR (si gana)
203
- uv pip install "rfdetr[onnx]" && python -c "from rfdetr import RFDETRNano; RFDETRNano(pretrain_weights='output/checkpoint_best.pth').export(format='onnx')"
204
- # renombrar a marca: agrovision-plantcount-vX.Y.Z.onnx
205
- ```
206
-
207
- ### 6.2 Publicación en Hugging Face Hub (1 artefacto)
208
-
209
- ```python
210
- from huggingface_hub import HfApi
211
- HfApi().upload_file(path_or_fileobj="models/agrovision-plantcount-v2.0.0.onnx",
212
- path_in_repo="agrovision-plantcount-v2.0.0.onnx",
213
- repo_id="<org>/agrovision-plantcount", repo_type="model")
214
- # + README.md (model card: arquitectura ganadora, licencia, cultivo, métricas)
215
- ```
216
-
217
- ### 6.3 Contrato de Inferencia (estable, agnóstico a la arquitectura)
218
-
219
- ```json
220
- {
221
- "boxes": [[x1, y1, x2, y2, conf, cls]],
222
- "count": 124,
223
- "classes": {"0": "arbusto"},
224
- "crop": "blueberry",
225
- "model_version": "2.0.0",
226
- "architecture": "yolo26n", // o "rfdetr_nano" — el ganador
227
- "license": "AGPL-3.0", // o "Apache-2.0"
228
- "nms_free": true
229
- }
230
- ```
231
-
232
- * **Agnóstico:** AgroVisión lee `architecture` y aplica el **adaptador de decode** correspondiente; el nombre del artefacto es de marca (`agrovision-plantcount`), no cambia al cambiar de modelo.
233
- * **Multi-cultivo:** `crop` y `classes` describen el cultivo/clases del modelo publicado.
234
-
235
- ### 6.4 Consumo en AgroVisión (build de Docker)
236
-
237
- ```dockerfile
238
- RUN uv run python -c "from huggingface_hub import hf_hub_download; \
239
- hf_hub_download(repo_id='<org>/agrovision-plantcount', \
240
- filename='agrovision-plantcount-v2.0.0.onnx', local_dir='/app/models')"
241
- ENV MODEL_PATH=/app/models/agrovision-plantcount-v2.0.0.onnx
242
- ENV MODEL_VERSION=2.0.0
243
- ```
244
-
245
- ---
246
-
247
- ## 7. Estructura del Repo, Docker y Reproducibilidad
248
-
249
- ```
250
- agrovision-plant-count-model/
251
- ├── notebooks/ # 01_explore · 02_annotate_sam · 03_train_candidates · 04_satellite
252
- ├── src/
253
- │ ├── ingest.py # descarga por cultivo (COCO + YOLO)
254
- │ ├── annotate_sam.py # SAM → COCO + YOLO
255
- �� ├── preprocess.py # tiling/splits/augment + clases por cultivo
256
- │ ├── train.py # entrena candidatos (yolo26 / rfdetr)
257
- │ ├── evaluate.py # métricas + SELECCIÓN del mejor
258
- │ ├── export.py # ganador → ONNX + model card
259
- │ ├── publish.py # → Hugging Face Hub
260
- │ └── satellite/ # deepforest_count.py · dinov3_features.py
261
- ├── configs/ # train.yaml (crop, candidates, classes)
262
- ├── data/ # raw/<cultivo>/ · processed/<cultivo>/ (NO commitear)
263
- ├── models/ # .onnx + metrics.json
264
- ├── tests/ # test_contract · test_preprocess · test_parity
265
- ├── Dockerfile · pyproject.toml · .gitignore · README.md
266
- ```
267
-
268
- ### 7.1 Dependencias
269
- ```toml
270
- "ultralytics>=8.3", # YOLO26 (AGPL — uso aceptado)
271
- "rfdetr[onnx]>=1.4", # RF-DETR (Apache 2.0)
272
- "torch>=2.2", "torchvision>=0.17",
273
- "onnx>=1.16", "onnxruntime>=1.18",
274
- "opencv-python-headless>=4.9", "numpy>=2.1",
275
- "albumentations>=1.4", "supervision>=0.20",
276
- "segment-anything-2", # SAM (anotación)
277
- "deepforest>=1.4", # baseline árboles (MIT)
278
- "kagglehub", "roboflow", # ingesta (COCO + YOLO)
279
- "huggingface_hub", # publicación
280
- # DINOv3 vía torch.hub / facebookresearch/dinov3
281
- ```
282
- > **Python ≥ 3.10** (requisito de `rfdetr`) y **`uv`**. Entrenamiento en Colab/Kaggle (GPU T4 gratis); CPU local para preproceso/validación.
283
-
284
- ---
285
-
286
- ## 8. Reglas de Validación y Pruebas
287
- 1. **Contrato:** `tests/test_contract.py` valida el JSON §6.3 (incl. `architecture`, `crop`, `license`, `nms_free`).
288
- 2. **Sanity de conteo:** MAE bajo umbral por cultivo.
289
- 3. **Determinismo:** seeds fijas → reproducible.
290
- 4. **Selección:** se documenta el candidato ganador y por qué.
291
- 5. **Paridad notebook↔script** y **publicación** descargable de HF Hub.
292
-
293
- ---
294
-
295
- ## Apéndice — Fuentes
296
-
297
- YOLO26 ([Ultralytics](https://docs.ultralytics.com/models/yolo26)); RF-DETR ([GitHub](https://github.com/roboflow/rf-detr)); DINOv3 ([Meta](https://ai.meta.com/blog/dinov3-self-supervised-vision-model/)); DeepForest ([GitHub](https://github.com/weecology/DeepForest)); **arándano con dron** ([arXiv 2501.02344](https://arxiv.org/abs/2501.02344)); cultivos UAV ([bioRxiv 2021](https://www.biorxiv.org/content/10.1101/2021.04.27.441631v2.full)); CitDet ([arXiv 2309.05645](https://arxiv.org/html/2309.05645v3)); TasselNetV4 ([arXiv 2509.20857](https://arxiv.org/pdf/2509.20857)); Hugging Face Hub ([docs](https://huggingface.co/docs/hub/en/models-downloading)).