Scan a food product, confirm what it is, and discover recipes from a structured catalog.
Kotlin · Jetpack Compose · Python · FastAPI · OpenCV · EasyOCR · SQLite
Features · Architecture · Quick start · API · Testing
NutriW is a full-stack product-recognition project with a native Android scanner, a Python API, and browser tools for maintaining the recognition dataset and recipe catalog.
The recognition workflow combines barcode matching, visual similarity, OCR, and product metadata. Users can confirm or correct uncertain results; confirmed examples can become additional training samples. Recipe suggestions are matched against catalog products rather than relying only on unstructured ingredient text.
The project explores a practical engineering problem: connecting an imperfect recognition pipeline to a usable mobile experience with explicit user feedback.
| Surface | Capabilities |
|---|---|
| Android app | Product-photo capture, scan results, candidate confirmation/correction, recipe browsing, and server discovery/manual configuration |
| Recognition API | Barcode lookup, image-quality checks, visual features, OCR, metadata-aware ranking, and rejection/confirmation of uncertain matches |
| Mobile web trainer | Capture or upload a photo, inspect candidates, correct product metadata, and save labeled examples |
| Catalog and admin UI | Search products and recipes, inspect recipe details, manage samples and recipe ingredients |
| Data model | SQLite product and recipe records, linked ingredients, brands, aliases, measurements, and stored image samples |
| Operations | Health endpoint, OpenAPI documentation, configurable upload limits, CORS settings, and optional admin-token protection |
flowchart LR
A[Android app] -->|Product photo| B[FastAPI]
C[Browser trainer] -->|Labeled samples| B
B --> D[Barcode and image-quality checks]
D --> E[Visual similarity and OCR ranking]
E --> F[Candidates and user confirmation]
F --> G[SQLite catalog and image samples]
G --> H[Recipe matching]
H --> A
- EXIF-aware image decoding and preprocessing.
- Visual features describing color layout, edges, and image structure.
- Barcode lookup and OCR text as complementary signals.
- Reranking with product aliases, measurement hints, and visual evidence.
- Background OCR warm-up and refresh of saved image embeddings on startup.
- Explicit handling of low-confidence, low-quality, and ambiguous inputs.
This is a hybrid recognition pipeline, not a claim of a universally trained food-recognition model. Performance depends on the catalog, image samples, packaging, and photo quality; no benchmark accuracy is asserted here.
android-studio-app/ Android Studio project
app/src/main/ Kotlin app, Compose UI, networking, and view model
pycharm-server/
api/ FastAPI endpoints, recognition, OCR, data access
api/templates/ Trainer, catalog, admin, and documentation pages
data/ SQLite database and local image samples
scripts/ Catalog import, seed, evaluation, and launch tools
tests/ Backend regression tests
Use a Python environment compatible with the pinned packages in pycharm-server/requirements.txt.
git clone https://github.com/L1BBER/NutriW.git
cd NutriW/pycharm-server
python -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r requirements.txt
.\.venv\Scripts\python.exe -m uvicorn api.main:app --host 127.0.0.1 --port 8000On Linux/macOS, use python3 and .venv/bin/python in place of the Windows executable path.
| Page | Local URL |
|---|---|
| Interactive API documentation | Swagger UI |
| Product/recipe catalog | Catalog |
| Training workflow | Trainer |
| Administration | Admin |
| Project requirements/use cases | Project documentation |
| Health check | Health |
For access from a physical phone, bind the backend to a deliberately chosen LAN interface or 0.0.0.0, configure the firewall, and keep it on a trusted network.
- Open
android-studio-app/in Android Studio and synchronize Gradle. - Use the configured SDK toolchain: compile/target SDK 34, minimum SDK 26, and JVM target 17.
- Start the backend, then run the app on an emulator or device.
- Use server discovery or enter the backend address manually in the app. For an Android emulator, the host is typically
http://10.0.2.2:8000; a physical phone needs the backend computer's LAN address.
Connection discovery lives in ServerDiscovery.kt; Retrofit clients are created by NetworkModule.kt. There is no need to replace a fixed server constant in NetworkModule.kt.
| Method | Endpoint | Purpose |
|---|---|---|
| POST | /scan/confirm |
Analyze a product photo and return candidates, warnings, and recipes |
| POST | /scan/confirm_user_edit |
Accept a corrected product selection |
| POST | /trainer/predict |
Analyze a photo in the training workflow |
| POST | /trainer/confirm |
Save a confirmed/corrected training example |
| POST | /train/add |
Add a training sample through the admin flow |
| GET | /train/products |
List trained products and metadata |
| GET | /recipes/list |
List recipes |
| POST | /recipes/add |
Add a recipe |
| PUT | /recipes/{recipe_id} |
Update a recipe |
| POST | /recipes/parse-ingredients |
Match ingredient text against known products |
| GET | /health |
Check service health |
Use the running server's /docs for request schemas and the complete endpoint list.
| Variable | Purpose |
|---|---|
NUTRIW_ADMIN_TOKEN |
Optional protection for admin/trainer/catalog and protected write endpoints |
NUTRIW_CORS_ORIGINS |
Comma-separated allowed browser origins |
NUTRIW_MAX_IMAGE_MB |
Upload size limit; default 12 MB |
Prefer an Authorization: Bearer or X-NutriW-Admin-Token header over putting tokens in shareable URLs. Restrict network access and CORS before exposing the backend. If an admin token is enabled, clients calling protected endpoints must supply it.
The database is pycharm-server/data/nutriw.db. Training images live in data/images/; temporary uploads use pending directories. The entire runtime data/ directory is local and excluded from Git, along with diagnostic logs, screenshots, and IDE state. A fresh checkout starts with an empty catalog; add products and your own permitted images through the catalog/trainer before evaluating recognition. Existing local data is not deleted by this repository cleanup. Review image rights and personal-data exposure before sharing any dataset. See SECURITY.md.
The public backend suite runs without private images, a pre-filled catalog or OCR model downloads. From pycharm-server/:
.\.venv\Scripts\python.exe -m pip install -r requirements-test.txt
.\.venv\Scripts\python.exe -m compileall -q api scripts tests
.\.venv\Scripts\python.exe -m pytest -c pytest-public.ini -qThe suite covers HTTP contracts, authorization, validation, recipe persistence, upload limits, catalog behavior, barcode/image quality, hardening, OCR warm-up, product categories, and scan rejection. QA plan and known limitations explain the synthetic fixtures and manual checks still needed. Backend tests run on pushes and pull requests.
test_catalog_data.py is a separate local-dataset acceptance suite: full discovery with python -m pytest -q tests requires a permitted catalog with at least 100 products, a water product and 40 recipes. It is not a fresh-checkout validation command. Android's included example tests are not a comprehensive app test suite.
For a Kotlin compilation check, from android-studio-app/:
.\gradlew.bat :app:compileDebugKotlinThese are reproducible validation commands, not a claim that every platform and live recognition flow has been verified. OCR initialization may need model downloads; a missing OCR engine reduces text-based recognition.
NutriW demonstrates mobile/backend integration, multimodal recognition heuristics, human feedback in a data pipeline, structured relational data, and practical handling of uncertain predictions. Recognition quality and recipe relevance should be evaluated against a separate labeled test set before making quantitative claims.