- Dart 77.2%
- Python 22.3%
- Swift 0.4%
- 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 |
||
|---|---|---|
| app | ||
| ml | ||
| plans | ||
| .gitignore | ||
| README.md | ||
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
- Capture + Measurement — ML Kit face/IPD →
mm_per_pxscale lock → rotation coaching → custom ear model → focus + stability + confidence gate → auto-capture (features/capture). - Import + Background Removal — gallery or pasted URL → on-device cutout →
Library grid + manual touch-up brush (
features/library). - 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 0–35) 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.