No description
  • Dart 77.2%
  • Python 22.3%
  • Swift 0.4%
Find a file
PlanNear 47f2957bc3 feat: more reliable face-to-ear handoff during capture
- Hand off to ear-locking after several face-less frames, not a
  single lost-face frame, so near-profile turns are detected reliably
- Raise fill-fraction so the ear is large enough once the user turns
- Gate ear on-screen size and coach the user closer when too small
- Add plannear architecture diagram
2026-06-27 02:00:30 +00:00
app feat: more reliable face-to-ear handoff during capture 2026-06-27 02:00:30 +00:00
ml fix(ml): repeat() dataset so training runs all epochs 2026-06-25 23:41:39 +00:00
plans feat: more reliable face-to-ear handoff during capture 2026-06-27 02:00:30 +00:00
.gitignore fix(ml): make training pipeline runnable on real dataset 2026-06-24 17:33:40 +00:00
README.md feat(app): bundle trained ear-landmark model (6.6 px test error) 2026-06-26 13:42:11 +00:00

PlanNear

A fully on-device earring planning app for iOS + Android. Capture your ear with a real-world size estimate, import earrings (gallery photo or product URL) with local background removal, then plan by placing earrings onto a saved ear that snaps to detected ear landmarks.

Privacy first: everything runs locally. The only outbound network calls are fetching a product page/image when you paste a store URL. No user images are ever uploaded; all persistence is local SQLite + on-device files.

Repository layout

nimbalyst-local/
  app/        Flutter app (iOS + Android) — see app/README.md & app/FOUNDATION_NOTES.md
  ml/         Offline Python training pipeline → ear_landmarks.tflite — see ml/README.md
  plans/      The implementation plan

App architecture

  • State: Riverpod · Navigation: go_router · DB: sqflite (+ path_provider files)
  • Layers: data/ (SQLite, DAOs, FileStorage, ScraperClient) · domain/ (models, MeasurementService, repositories, Stability) · ml/ (FaceAnalyzer, EarLandmarkDetector, BackgroundRemover, ImageOps) · features/ (capture/, library/, planner/).

Three features

  1. Capture + Measurement — ML Kit face/IPD → mm_per_px scale lock → rotation coaching → custom ear model → focus + stability + confidence gate → auto-capture (features/capture).
  2. Import + Background Removal — gallery or pasted URL → on-device cutout → Library grid + manual touch-up brush (features/library).
  3. Planner — place earrings on a saved ear, snap to keypoints, auto-scale by real size, save layouts, export flattened PNG (features/planner).

Build & run

export PATH="/config/flutter/flutter/bin:$PATH"
cd app
flutter pub get
flutter analyze        # clean
flutter test           # all green
flutter run            # on a connected device/emulator

The ear model

app/assets/models/ear_landmarks.tflite is produced offline by the ml/ pipeline (55-landmark CNN, 224×224, based on the MIT-licensed kbulutozler/ear-landmark-detection-with-CNN). A trained model (~6.9 MB, 6.6 px mean test error) is bundled. If the asset is ever missing, EarLandmarkDetector falls back to a clearly-marked synthetic placeholder so the capture/planner UX still works end-to-end. The 55-landmark outer-contour subset (indices 035) is filled as the segmentation mask — the same indices are documented in ml/README.md and mirrored in app/lib/ml/ear_landmark_detector.dart.

See app/PRIVACY.md for the privacy policy and store disclosures, and ml/LICENSE_NOTES.md for model/dataset attribution.