Skip to content

Instantly share code, notes, and snippets.

@navarasu
Last active April 23, 2019 09:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save navarasu/467cff53192f32601dfbe229c33ac246 to your computer and use it in GitHub Desktop.
Save navarasu/467cff53192f32601dfbe229c33ac246 to your computer and use it in GitHub Desktop.
Main Dart for TF Lite object detection
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:camera/camera.dart';
import 'package:object_detector/object_detector.dart';
List<CameraDescription> cameras;
var labels, colors;
Future<void> main() async {
try {
cameras = await availableCameras();
} on CameraException catch (e) {
print('Error: $e.code\nError Message: $e.message');
}
await _loadModel();
runApp(ObjectDetectApp());
}
Future<Null> _loadModel() async {
try {
const platform = const MethodChannel('francium.tech/tensorflow');
var jsonString = await rootBundle.loadString('assets/yolov2-tiny.meta');
var metaData = json.decode(jsonString);
labels = metaData["labels"];
colors = metaData["colors"];
metaData["blockSize"] = 32;
metaData["threshold"] = 0.5;
metaData["overlap_threshold"] = 0.7;
metaData["max_result"] = 15;
final String result = await platform.invokeMethod('loadModel',
{"modal_path": "assets/yolov2_graph.lite", "meta_data": metaData});
print(result);
} on PlatformException catch (e) {
print('Error: $e.code\nError Message: $e.message');
}
}
class ObjectDetectApp extends StatefulWidget {
@override
_ObjectDetectAppState createState() => new _ObjectDetectAppState();
}
class _ObjectDetectAppState extends State<ObjectDetectApp>
with WidgetsBindingObserver {
final ObjectDetecter detector = ObjectDetecter.instance;
CameraController controller;
GlobalKey _keyCameraPreview = GlobalKey();
@override
void initState() {
super.initState();
controller = CameraController(cameras[0], ResolutionPreset.medium);
controller.initialize().then((_) {
if (!mounted) {
return;
}
setState(() {});
detector.addListener(() {
setState(() {});
});
detector.init(controller);
});
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
controller?.dispose();
detector.dispose();
super.dispose();
}
@override
void dispose() {
controller?.dispose();
detector.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return new MaterialApp(
theme: ThemeData(primarySwatch: Colors.blueGrey),
home: Scaffold(
appBar: AppBar(
title: Center(
child: Text('Object Detector'),
)),
body: new Center(
child: Column(children: [
_cameraPreviewWidget(detector.value),
]),
)));
}
Widget _cameraPreviewWidget(List value) {
if (controller == null || !controller.value.isInitialized) {
return const Text(
'Loading Camera',
style: TextStyle(
color: Colors.white,
fontSize: 24.0,
fontWeight: FontWeight.w900,
),
);
} else {
return new Stack(alignment: FractionalOffset.center, children: <Widget>[
new AspectRatio(
key: _keyCameraPreview,
aspectRatio: controller.value.aspectRatio,
child: new CameraPreview(controller)),
new Positioned.fill(
child: new CustomPaint(
painter: new DrawObjects(value, _keyCameraPreview),
)),
]);
}
}
}
class DrawObjects extends CustomPainter {
List values;
GlobalKey<State<StatefulWidget>> keyCameraPreview;
DrawObjects(this.values, this.keyCameraPreview);
@override
void paint(Canvas canvas, Size size) {
print(values);
if (values==null && values.isNotEmpty && values[0] == null) return;
final RenderBox renderPreview =
keyCameraPreview.currentContext.findRenderObject();
final sizeRed = renderPreview.size;
var ratioW = sizeRed.width / 416;
var ratioH = sizeRed.height / 416;
for (var value in values) {
var index = value["classIndex"];
var rgb = colors[index];
Paint paint = new Paint();
paint.color =new Color.fromRGBO(rgb[0].toInt(), rgb[1].toInt(), rgb[2].toInt(), 1);
paint.strokeWidth = 2;
var rect = value["rect"];
double x1 = rect["left"] * ratioW,
x2 = rect["right"] * ratioW,
y1 = rect["top"] * ratioH,
y2 = rect["bottom"] * ratioH;
TextSpan span = new TextSpan(
style: new TextStyle(
color: Colors.black,
background: paint,
fontWeight: FontWeight.bold,
fontSize: 14),
text: " " +labels[index] +" " +(value["confidence"] * 100).round().toString() +" % ");
TextPainter tp = new TextPainter(text: span, textAlign: TextAlign.left,
textDirection: TextDirection.ltr);
tp.layout();
tp.paint(canvas, new Offset(x1 + 1, y1 + 1));
canvas.drawLine(new Offset(x1, y1), new Offset(x2, y1), paint);
canvas.drawLine(new Offset(x1, y1), new Offset(x1, y2), paint);
canvas.drawLine(new Offset(x1, y2), new Offset(x2, y2), paint);
canvas.drawLine(new Offset(x2, y1), new Offset(x2, y2), paint);
}
}
@override
bool shouldRepaint(DrawObjects oldDelegate) {
return true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment