Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .pubignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
# Demo media
doc/

# The example's bundled ML model (git-tracked so the example runs, but ~5 MB —
# kept out of the published package).
**/*.tflite

# Build & tooling artifacts (mirrors .gitignore)
build/
**/build/
Expand Down
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# Changelog

## 0.0.6

* **New:** `CameraController.previewRectFromFrame(rect, sourceRotationDegrees:)` maps a normalized
detection box from a frame's coordinate space into preview-display space, accounting for the live preview
rotation and the front-camera mirror — so ML overlays line up with the preview **at any device
orientation** (the preview rotation and frame orientation are tracked independently, so boxes drawn
without it drift as the phone turns).
* **Example:** added a real-time **Object Detector** page — the FFI frame pipeline drives an on-device
EfficientDet-Lite0 detector (90 COCO classes) in a background isolate, with labelled boxes and a
cat-certainty voting trigger. Demonstrates YUV→RGB preprocessing, isolate inference, and
`previewRectFromFrame` for correctly-oriented overlays.

## 0.0.5

* **Docs:** added demo GIFs to the README (live preview + orientation, barcode/QR scanning with overlay,
Expand Down
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,24 @@ frame.incrementRefCount(); // keep the buffer alive
frame.decrementRefCount(); // release it (mandatory)
```

### Drawing ML detection boxes on the preview

Detection boxes are in the frame's coordinate space; the preview is rotated (and
maybe mirrored) for display, and the two are tracked **independently** — so a box
drawn naively drifts as the device turns. Map it with `previewRectFromFrame`:

```dart
final previewRect = controller.previewRectFromFrame(
detection.boundingBox, // normalized 0..1 from your model
sourceRotationDegrees: frame.orientation.degrees, // rotation you fed the model
);
// Scale previewRect onto the preview widget's rect (use displayPreviewSize for BoxFit).
```

It accounts for the live `previewRotation` and the front-camera mirror, so boxes
stay aligned at any orientation. See the example's **Object Detector** page for a
full EfficientDet-Lite0 overlay.

### High-performance native C/C++ plugin

For the heaviest work, hook the synchronous frame loop in C++ (`src/VisionCamera.hpp`):
Expand Down
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// The Android Gradle Plugin builds the native code with the Android NDK.

group = "dev.jentejan.flutter_native_vision_camera"
version = "0.0.5"
version = "0.0.6"

buildscript {
repositories {
Expand Down
4 changes: 4 additions & 0 deletions example/android/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError
android.useAndroidX=true
android.enableJetifier=true
# Some plugins (e.g. tflite_flutter 0.11.x) leave Java at 1.8 while Kotlin uses
# the toolchain's 21. On Android everything dexes to the same level, so downgrade
# the JVM-target consistency check from a hard error to a warning.
kotlin.jvm.target.validation.mode=warning
# This builtInKotlin flag was added automatically by Flutter migrator
android.builtInKotlin=false
# This newDsl flag was added automatically by Flutter migrator
Expand Down
90 changes: 90 additions & 0 deletions example/assets/coco_labels.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
person
bicycle
car
motorcycle
airplane
bus
train
truck
boat
traffic light
fire hydrant
???
stop sign
parking meter
bench
bird
cat
dog
horse
sheep
cow
elephant
bear
zebra
giraffe
???
backpack
umbrella
???
???
handbag
tie
suitcase
frisbee
skis
snowboard
sports ball
kite
baseball bat
baseball glove
skateboard
surfboard
tennis racket
bottle
???
wine glass
cup
fork
knife
spoon
bowl
banana
apple
sandwich
orange
broccoli
carrot
hot dog
pizza
donut
cake
chair
couch
potted plant
bed
???
dining table
???
???
toilet
???
tv
laptop
mouse
remote
keyboard
cell phone
microwave
oven
toaster
sink
refrigerator
???
book
clock
vase
scissors
teddy bear
hair drier
toothbrush
Binary file added example/assets/efficientdet.tflite
Binary file not shown.
37 changes: 35 additions & 2 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,14 +1,42 @@
PODS:
- Flutter (1.0.0)
- flutter_native_vision_camera (0.0.4):
- flutter_native_vision_camera (0.0.5):
- Flutter
- permission_handler_apple (9.3.0):
- Flutter
- TensorFlowLiteC (2.12.0):
- TensorFlowLiteC/Core (= 2.12.0)
- TensorFlowLiteC/Core (2.12.0)
- TensorFlowLiteC/CoreML (2.12.0):
- TensorFlowLiteC/Core
- TensorFlowLiteC/Metal (2.12.0):
- TensorFlowLiteC/Core
- TensorFlowLiteSwift (2.12.0):
- TensorFlowLiteSwift/Core (= 2.12.0)
- TensorFlowLiteSwift/Core (2.12.0):
- TensorFlowLiteC (= 2.12.0)
- TensorFlowLiteSwift/CoreML (2.12.0):
- TensorFlowLiteC/CoreML (= 2.12.0)
- TensorFlowLiteSwift/Core (= 2.12.0)
- TensorFlowLiteSwift/Metal (2.12.0):
- TensorFlowLiteC/Metal (= 2.12.0)
- TensorFlowLiteSwift/Core (= 2.12.0)
- tflite_flutter (0.0.1):
- Flutter
- TensorFlowLiteSwift (= 2.12.0)
- TensorFlowLiteSwift/CoreML (= 2.12.0)
- TensorFlowLiteSwift/Metal (= 2.12.0)

DEPENDENCIES:
- Flutter (from `Flutter`)
- flutter_native_vision_camera (from `.symlinks/plugins/flutter_native_vision_camera/ios`)
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
- tflite_flutter (from `.symlinks/plugins/tflite_flutter/ios`)

SPEC REPOS:
trunk:
- TensorFlowLiteC
- TensorFlowLiteSwift

EXTERNAL SOURCES:
Flutter:
Expand All @@ -17,11 +45,16 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/flutter_native_vision_camera/ios"
permission_handler_apple:
:path: ".symlinks/plugins/permission_handler_apple/ios"
tflite_flutter:
:path: ".symlinks/plugins/tflite_flutter/ios"

SPEC CHECKSUMS:
Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467
flutter_native_vision_camera: f9cae7b27180d93bf6fafad999e37e5086ae477a
flutter_native_vision_camera: 241fc00d5a123d3e560daa047824120dd6af5c03
permission_handler_apple: 4ed2196e43d0651e8ff7ca3483a069d469701f2d
TensorFlowLiteC: 20785a69299185a379ba9852b6625f00afd7984a
TensorFlowLiteSwift: 3a4928286e9e35bdd3e17970f48e53c80d25e793
tflite_flutter: 64b192e11352fe36943ab6656e1d49207f1a5595

PODFILE CHECKSUM: 3c63482e143d1b91d2d2560aee9fb04ecc74ac7e

Expand Down
14 changes: 14 additions & 0 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'package:flutter_native_vision_camera/flutter_native_vision_camera.dart';
import 'native_camera_page.dart';
import 'standard_camera_page.dart';
import 'code_scanner_page.dart';
import 'object_detector_page.dart';

import 'package:flutter/services.dart';

Expand Down Expand Up @@ -83,6 +84,19 @@ class _HomePageState extends State<HomePage> {
},
),
const SizedBox(height: 16),
_buildFeatureCard(
context,
title: 'Object Detector',
subtitle: 'Frame processor → EfficientDet (90 classes) + boxes',
icon: Icons.center_focus_strong,
color: Colors.deepPurple,
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (_) => const ObjectDetectorPage()),
);
},
),
const SizedBox(height: 16),
_buildFeatureCard(
context,
title: 'Standard Camera',
Expand Down
Loading
Loading