# palm_oil_mobile A Flutter app that runs on-device YOLO26 (NMS-free) inference to detect palm oil fresh fruit bunch (FFB) ripeness against MPOB grading standards — fully offline, no server or network calls required. Built for FFB harvesters to scan bunches in the field and compare their own judgment against the model's. ## Detection classes `Ripe`, `Unripe`, `Underripe`, `Overripe`, `Abnormal`, `Empty_Bunch` (MPOB standard). ## Features - **Three capture modes**: - **Analyze Gallery** — pick one or more photos from the gallery and run inference on each as a batch. - **Snap & Analyze** — manual high-res camera capture. - **Live Inference** — real-time "point-and-scan": an auto-lock state machine detects a steady target, captures a high-res still, and analyzes it automatically. - **Batch reporting** — every scan is grouped into a batch (one per capture-screen visit, or per multi-image gallery pick). Batches show a KPI dashboard (frame count, total detections, avg confidence, avg inference time), an MPOB class-distribution bar, and a frame thumbnail grid. - **History Vault** — grouped, filterable, sortable history of every batch, with swipe-to-delete and date-range filtering. - **Harvester ground-truth corrections** — on any photo's detail screen, a harvester can compare the AI's inference against their own judgment and correct individual detected fruit. Corrections are additive: the AI's original inference is never edited or overwritten, and a photo can be re-corrected any number of times, each one recorded separately — intended to eventually feed a cloud-based retraining pipeline. - **Light/dark theme** — a custom teal-green/amber palette with a system-following default and an in-app toggle (Light/Dark/System), persisted across launches. ## Getting started ```bash flutter pub get flutter run # run on a connected device/emulator flutter build apk --debug # debug build flutter build apk # release build flutter analyze # static analysis ``` The bundled model (`assets/best.tflite`) and labels (`assets/labels.txt`) are loaded at runtime — no backend to start, no network required. ### Regenerating the app icon The launcher icon is generated from `assets/icon_light.png` via `flutter_launcher_icons` (config lives in `pubspec.yaml`). After changing the source image, regenerate with: ```bash dart run flutter_launcher_icons ``` ## Architecture See [CLAUDE.md](CLAUDE.md) for a detailed breakdown of the isolate-based inference pipeline, the live-capture auto-lock state machine, the SQLite schema (batches, corrections), and screen-by-screen notes — written for AI coding agents working in this repo, but equally useful as an architecture reference for humans. ## Requirements - Flutter SDK `^3.11.1` - Android (primary target — this is where the app is actively tested); iOS builds are untested (no current access to iOS hardware)