1
- import 'dart:io ' ;
2
-
1
+ import 'package:camera/camera.dart ' ;
2
+ import 'package:flutter/foundation.dart' ;
3
3
import 'package:flutter/material.dart' ;
4
- import 'package:image_picker/image_picker.dart' ;
5
4
import 'package:tflite/tflite.dart' ;
6
5
7
6
void main () => runApp (MyApp ());
@@ -10,11 +9,12 @@ class MyApp extends StatelessWidget {
10
9
@override
11
10
Widget build (BuildContext context) {
12
11
return MaterialApp (
13
- title: 'Flutter Demo' ,
12
+ debugShowCheckedModeBanner: false ,
13
+ title: 'ML Room Colors' ,
14
14
theme: ThemeData (
15
15
primarySwatch: Colors .blue,
16
16
),
17
- home: MyHomePage (title: 'Flutter Demo Home Page ' ),
17
+ home: MyHomePage (title: 'Detect Room Color ' ),
18
18
);
19
19
}
20
20
}
@@ -29,99 +29,138 @@ class MyHomePage extends StatefulWidget {
29
29
}
30
30
31
31
class _MyHomePageState extends State <MyHomePage > {
32
- bool _loading;
32
+ CameraController _camera;
33
+
34
+ bool _isDetecting = false ;
35
+ CameraLensDirection _direction = CameraLensDirection .back;
36
+ Future <void > _initializeControllerFuture;
37
+
38
+ bool _modelLoaded;
33
39
List _outputs;
34
- File _image;
40
+
41
+ Future <CameraDescription > _getCamera (CameraLensDirection dir) async {
42
+ return await availableCameras ().then (
43
+ (List <CameraDescription > cameras) => cameras.firstWhere (
44
+ (CameraDescription camera) => camera.lensDirection == dir,
45
+ ),
46
+ );
47
+ }
48
+
49
+ void _initializeCamera () async {
50
+ log ("_initializeCamera" , "Initializing camera.." );
51
+
52
+ _camera = CameraController (
53
+ await _getCamera (_direction),
54
+ defaultTargetPlatform == TargetPlatform .iOS
55
+ ? ResolutionPreset .low
56
+ : ResolutionPreset .medium,
57
+ );
58
+ _initializeControllerFuture = _camera.initialize ().then ((value) {
59
+ log ("_initializeCamera" , "Camera initialized, starting camera stream.." );
60
+
61
+ _camera.startImageStream ((CameraImage image) {
62
+ if (! _modelLoaded) return ;
63
+ if (_isDetecting) return ;
64
+ _isDetecting = true ;
65
+ try {
66
+ classifyImage (image);
67
+ } catch (e) {
68
+ print (e);
69
+ }
70
+ });
71
+ });
72
+ }
35
73
36
74
void initState () {
37
75
super .initState ();
38
- _loading = true ;
76
+ _initializeCamera ();
77
+ _modelLoaded = false ;
39
78
40
79
loadModel ().then ((value) {
80
+
41
81
setState (() {
42
- _loading = false ;
82
+ _modelLoaded = true ;
43
83
});
44
84
});
45
85
}
46
86
47
87
//Load the Tflite model
48
88
loadModel () async {
89
+ log ("loadModel" , "Loading model.." );
49
90
await Tflite .loadModel (
50
91
model: "assets/model_unquant.tflite" ,
51
92
labels: "assets/labels.txt" ,
52
93
);
53
94
}
54
95
55
- //Pick an image from the gallery
56
- pickImage () async {
57
- var image = await ImagePicker .pickImage (source: ImageSource .gallery);
58
- if (image == null ) return null ;
59
- setState (() {
60
- _loading = true ;
61
- //Declare File _image in the class which is used to display the image on the screen.
62
- _image = image;
63
- });
64
- classifyImage (image);
65
- }
66
-
67
- classifyImage (File image) async {
68
- var output = await Tflite .runModelOnImage (
69
- path: image.path,
70
- numResults: 2 ,
71
- threshold: 0.5 ,
96
+ classifyImage (CameraImage image) async {
97
+ await Tflite .runModelOnFrame (
98
+ bytesList: image.planes.map ((plane) {
99
+ return plane.bytes;
100
+ }).toList (),
101
+ numResults: 3 ,
102
+ threshold: 0.3 ,
72
103
imageMean: 127.5 ,
73
104
imageStd: 127.5 ,
74
- );
75
- setState (() {
76
- _loading = false ;
77
- //Declare List _outputs in the class which will be used to show the classified classs name and confidence
78
- _outputs = output;
105
+ //asynch: true,
106
+ ).then ((value) {
107
+ _isDetecting = false ;
108
+
109
+ if (value.isNotEmpty) {
110
+ log ("classifyImage" , "Results loaded. ${value .length }" );
111
+ value.forEach ((element) {
112
+ log ("classifyImage" , "$element " );
113
+ });
114
+ }
115
+ _outputs = value;
79
116
});
80
117
}
81
118
82
119
@override
83
120
Widget build (BuildContext context) {
84
121
return Scaffold (
85
- appBar: AppBar (
86
- title: Text (widget.title),
87
- ),
88
- body: _loading
89
- ? Container (
90
- alignment: Alignment .center,
91
- child: CircularProgressIndicator (),
92
- )
93
- : Container (
94
- width: MediaQuery .of (context).size.width,
95
- child: Column (
96
- crossAxisAlignment: CrossAxisAlignment .center,
97
- mainAxisAlignment: MainAxisAlignment .center,
98
- children: [
99
- _image == null ? Container () : Image .file (_image),
100
- SizedBox (
101
- height: 20 ,
102
- ),
103
- _outputs != null
104
- ? Text (
105
- "${_outputs [0 ]["label" ]}" ,
106
- style: TextStyle (
107
- color: Colors .black,
108
- fontSize: 20.0 ,
109
- background: Paint ()..color = Colors .white,
110
- ),
111
- )
112
- : Text ("Classification Failed" )
113
- ],
114
- ),
115
- ),
116
- floatingActionButton: FloatingActionButton (
117
- onPressed: pickImage,
118
- child: Icon (Icons .image),
119
- ));
122
+ appBar: AppBar (
123
+ title: Text (widget.title),
124
+ ),
125
+ body: FutureBuilder <void >(
126
+ future: _initializeControllerFuture,
127
+ builder: (context, snapshot) {
128
+ if (snapshot.connectionState == ConnectionState .done) {
129
+ // If the Future is complete, display the preview.
130
+ return Stack (
131
+ children: < Widget > [
132
+ CameraPreview (_camera),
133
+ Center (
134
+ child: _outputs != null && _outputs.isNotEmpty
135
+ ? Text (
136
+ "${_outputs [0 ]["label" ]}" ,
137
+ style: TextStyle (
138
+ color: Colors .green,
139
+ fontSize: 26.0 ,
140
+ ),
141
+ )
142
+ : Text ("Classification Failed" ),
143
+ )
144
+ ],
145
+ );
146
+ } else {
147
+ // Otherwise, display a loading indicator.
148
+ return Center (child: CircularProgressIndicator ());
149
+ }
150
+ },
151
+ ),
152
+ );
120
153
}
121
154
122
155
@override
123
156
void dispose () {
124
157
Tflite .close ();
158
+ _camera.dispose ();
159
+ log ("dispose" , "Clear resources." );
125
160
super .dispose ();
126
161
}
162
+
163
+ void log (String methodName, String message) {
164
+ debugPrint ("{$methodName } {$message }" );
165
+ }
127
166
}
0 commit comments