Skip to content

Commit 7ac295c

Browse files
committed
⚡ added tensorflow
1 parent 15ab27f commit 7ac295c

File tree

15 files changed

+760
-22
lines changed

15 files changed

+760
-22
lines changed

.vscode/launch.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
// Use IntelliSense to learn about possible attributes.
3+
// Hover to view descriptions of existing attributes.
4+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5+
"version": "0.2.0",
6+
"configurations": [
7+
{
8+
"name": "Dart: Attach to Process",
9+
"type": "dart",
10+
"request": "attach"
11+
},
12+
13+
{
14+
"name": "Flutter",
15+
"type": "dart",
16+
"request": "launch",
17+
"program": "lib/main.dart"
18+
}
19+
]
20+
}

android/app/build.gradle

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ android {
3939
defaultConfig {
4040
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
4141
applicationId "com.example.face_mask_detection"
42-
minSdkVersion 16
42+
minSdkVersion 21
4343
targetSdkVersion 28
4444
versionCode flutterVersionCode.toInteger()
4545
versionName flutterVersionName
@@ -52,6 +52,14 @@ android {
5252
signingConfig signingConfigs.debug
5353
}
5454
}
55+
aaptOptions {
56+
noCompress 'tflite'
57+
noCompress 'lite'
58+
}
59+
compileOptions {
60+
sourceCompatibility = 1.8
61+
targetCompatibility = 1.8
62+
}
5563
}
5664

5765
flutter {

assets/fonts/Gilroy-Light.ttf

53.4 KB
Binary file not shown.

assets/images/illustrator.jpeg

22.2 KB
Loading

assets/models/model.tflite

9.85 MB
Binary file not shown.

assets/texts/lables.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
with_mask
2+
without_mask

lib/main.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ class MyApp extends StatelessWidget {
99
@override
1010
Widget build(BuildContext context) {
1111
return MaterialApp(
12-
home: HomePage(),
12+
debugShowCheckedModeBanner:false,
13+
home: HomeScreen(),
1314
);
1415
}
1516
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import 'dart:io';
2+
import 'package:camera/camera.dart';
3+
import 'package:tflite/tflite.dart';
4+
5+
class TensorFlowServices {
6+
loadModel() async {
7+
await Tflite.loadModel(
8+
model: "assets/models/model.tflite",
9+
labels: "assets/texts/lables.txt",
10+
);
11+
}
12+
13+
predictImage(File image) async {
14+
var recog = await Tflite.runModelOnImage(
15+
path: image.path,
16+
numResults: 2,
17+
threshold: 0.5,
18+
imageMean: 127.5,
19+
imageStd: 127.5,
20+
);
21+
return recog;
22+
}
23+
24+
runModelonFrame(CameraImage img) {
25+
var run = Tflite.runModelOnFrame(
26+
bytesList: img.planes.map((Plane plane) {
27+
return plane.bytes;
28+
}).toList(),
29+
imageWidth: img.width,
30+
imageHeight: img.height,
31+
numResults: 2,
32+
);
33+
return run;
34+
}
35+
}

lib/ui/camera_screen.dart

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
import 'dart:math';
2+
3+
import 'package:camera/camera.dart';
4+
import 'package:face_mask_detection/services/tensorflow_services.dart';
5+
import 'package:face_mask_detection/utils/overlay.dart' as ol;
6+
import 'package:flutter/material.dart';
7+
8+
class CameraPage extends StatefulWidget {
9+
@override
10+
_CameraPageState createState() => _CameraPageState();
11+
}
12+
13+
class _CameraPageState extends State<CameraPage> with WidgetsBindingObserver {
14+
final TensorFlowServices _services = TensorFlowServices();
15+
CameraController _controller;
16+
bool _isDetecting = false;
17+
18+
bool _rear = false;
19+
List<CameraDescription> _cameras = [];
20+
List<dynamic> _recognitions;
21+
22+
loadModel() async {
23+
_services.loadModel();
24+
}
25+
26+
@override
27+
void didChangeAppLifecycleState(AppLifecycleState state) {
28+
if (_controller == null || !_controller.value.isInitialized) {
29+
return;
30+
}
31+
if (state == AppLifecycleState.inactive) {
32+
_controller?.dispose();
33+
} else if (state == AppLifecycleState.resumed) {
34+
if (_controller != null) {
35+
_setupCamera();
36+
}
37+
}
38+
}
39+
40+
@override
41+
void dispose() {
42+
WidgetsBinding.instance.removeObserver(this);
43+
_controller?.dispose();
44+
super.dispose();
45+
}
46+
47+
@override
48+
void initState() {
49+
super.initState();
50+
WidgetsBinding.instance.addObserver(this);
51+
loadModel();
52+
_setupCamera();
53+
}
54+
55+
void _setupCamera() async {
56+
_cameras = await availableCameras();
57+
if (_cameras == null || _cameras.isEmpty) {
58+
print('Looks like there are no cameras');
59+
} else {
60+
_controller = CameraController(
61+
_cameras[_rear ? 0 : 1],
62+
ResolutionPreset.max,
63+
);
64+
_controller.initialize().then((_) {
65+
if (_updateCamera()) {
66+
_readFrames();
67+
}
68+
});
69+
}
70+
}
71+
72+
Future<void> _switchCameraLens() async {
73+
_rear = !_rear;
74+
await _controller?.dispose();
75+
_setupCamera();
76+
}
77+
78+
bool _updateCamera() {
79+
if (!mounted) {
80+
return false;
81+
}
82+
setState(() {});
83+
return true;
84+
}
85+
86+
void _updateRecognitions({
87+
List<dynamic> recognitions,
88+
}) {
89+
setState(() {
90+
_recognitions = recognitions;
91+
});
92+
}
93+
94+
void _readFrames() {
95+
_controller.startImageStream(
96+
(CameraImage img) {
97+
if (!_isDetecting) {
98+
_isDetecting = true;
99+
_services.runModelonFrame(img).then((List<dynamic> recognitions) {
100+
_updateRecognitions(
101+
recognitions: recognitions,
102+
);
103+
_isDetecting = false;
104+
});
105+
}
106+
},
107+
);
108+
}
109+
110+
@override
111+
Widget build(BuildContext context) {
112+
if (_controller == null || !_controller.value.isInitialized) {
113+
return Container();
114+
}
115+
116+
final Size screen = MediaQuery.of(context).size;
117+
final double screenH = max(screen.height, screen.width);
118+
final double screenW = min(screen.height, screen.width);
119+
120+
final Size previewSize = _controller.value.previewSize;
121+
final double previewH = max(previewSize.height, previewSize.width);
122+
final double previewW = min(previewSize.height, previewSize.width);
123+
final double screenRatio = screenH / screenW;
124+
final double previewRatio = previewH / previewW;
125+
126+
return Scaffold(
127+
body: Stack(
128+
children: <Widget>[
129+
OverflowBox(
130+
maxHeight: screenRatio > previewRatio
131+
? screenH
132+
: screenW / previewW * previewH,
133+
maxWidth: screenRatio > previewRatio
134+
? screenH / previewH * previewW
135+
: screenW,
136+
child: CameraPreview(_controller),
137+
),
138+
ol.Overlay(
139+
results: _recognitions ?? <dynamic>[],
140+
),
141+
Positioned(
142+
right: 30,
143+
bottom: MediaQuery.of(context).size.height / 2,
144+
child: Transform.rotate(
145+
angle: -pi / 2,
146+
child: Text(_recognitions[0]["confidence"].toString())
147+
),
148+
),
149+
Positioned(
150+
bottom: 30,
151+
left: 30,
152+
child: Container(
153+
padding: EdgeInsets.all(15),
154+
decoration: BoxDecoration(
155+
borderRadius: BorderRadius.circular(80), color: Colors.green),
156+
child: GestureDetector(
157+
onTap: () async => _switchCameraLens(),
158+
child: Icon(
159+
_rear ? Icons.camera_front : Icons.camera_rear,
160+
size: 30,
161+
color: Colors.white,
162+
)),
163+
),
164+
),
165+
Positioned(
166+
bottom: 30,
167+
right: 30,
168+
child: Container(
169+
padding: EdgeInsets.all(15),
170+
decoration: BoxDecoration(
171+
borderRadius: BorderRadius.circular(80), color: Colors.red),
172+
child: GestureDetector(
173+
onTap: () => Navigator.pop(context),
174+
child: Icon(
175+
Icons.exit_to_app,
176+
size: 30,
177+
color: Colors.white,
178+
)),
179+
),
180+
),
181+
],
182+
),
183+
);
184+
}
185+
}

lib/ui/homepage.dart

Lines changed: 97 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,103 @@
1+
import 'package:face_mask_detection/ui/camera_screen.dart';
2+
import 'package:face_mask_detection/ui/local_storage.dart';
13
import 'package:flutter/material.dart';
4+
import 'package:url_launcher/url_launcher.dart';
25

3-
class HomePage extends StatefulWidget {
4-
@override
5-
_HomePageState createState() => _HomePageState();
6-
}
7-
8-
class _HomePageState extends State<HomePage> {
6+
class HomeScreen extends StatelessWidget {
97
@override
108
Widget build(BuildContext context) {
11-
return Container();
9+
return Scaffold(
10+
appBar: AppBar(
11+
elevation: 0.0,
12+
centerTitle: true,
13+
actions: [
14+
IconButton(
15+
icon: Icon(
16+
Icons.code,
17+
color: Colors.green,
18+
size: 25,
19+
semanticLabel: "Code",
20+
),
21+
onPressed: () {
22+
gotoWebPage();
23+
},
24+
)
25+
],
26+
backgroundColor: Colors.yellow.withOpacity(0.6),
27+
title: Text(
28+
'Face Mask Detection',
29+
style: TextStyle(color: Colors.black, fontFamily: "Gilroy"),
30+
),
31+
),
32+
body: Container(
33+
height: MediaQuery.of(context).size.height,
34+
decoration: BoxDecoration(
35+
color: Colors.yellow.withOpacity(0.4),
36+
border: Border.all(color: Colors.yellow, width: 5)),
37+
child: Column(
38+
mainAxisAlignment: MainAxisAlignment.center,
39+
children: <Widget>[
40+
Image.asset("assets/images/illustrator.jpeg"),
41+
SizedBox(
42+
height: 30,
43+
),
44+
GestureDetector(
45+
onTap: () {
46+
Navigator.push(context,
47+
MaterialPageRoute(builder: (context) => CameraPage()));
48+
},
49+
child: Container(
50+
padding: EdgeInsets.all(10),
51+
decoration: BoxDecoration(
52+
color: Colors.yellow,
53+
borderRadius: BorderRadius.circular(15),
54+
border: Border.all(width: 3, color: Colors.white)),
55+
child: Text(
56+
"Live camera",
57+
style: TextStyle(
58+
color: Colors.green,
59+
fontFamily: "Gilroy",
60+
fontSize: 15,
61+
fontWeight: FontWeight.w200),
62+
),
63+
),
64+
),
65+
SizedBox(
66+
height: 30,
67+
),
68+
GestureDetector(
69+
onTap: () {
70+
Navigator.push(context,
71+
MaterialPageRoute(builder: (context) => LocalStorage()));
72+
},
73+
child: Container(
74+
padding: EdgeInsets.fromLTRB(15, 10, 15, 10),
75+
decoration: BoxDecoration(
76+
color: Colors.yellow,
77+
borderRadius: BorderRadius.circular(15),
78+
border: Border.all(width: 3, color: Colors.white)),
79+
child: Text(
80+
"From Gallery",
81+
style: TextStyle(
82+
color: Colors.green,
83+
fontFamily: "Gilroy",
84+
fontSize: 15,
85+
fontWeight: FontWeight.w200),
86+
),
87+
),
88+
)
89+
],
90+
),
91+
),
92+
);
93+
}
94+
95+
gotoWebPage() async {
96+
const url = "https://github.com/shashiben/flutter-face-mask-detection";
97+
if (await canLaunch(url)) {
98+
await launch(url);
99+
} else {
100+
throw "Could not launch $url";
101+
}
12102
}
13103
}

0 commit comments

Comments
 (0)