Commit 9d6fbbbd authored by Piyumi Dayarathna's avatar Piyumi Dayarathna 💬

Conflict solved

parents d3dfbea7 3ffd8308
...@@ -35,7 +35,7 @@ android { ...@@ -35,7 +35,7 @@ android {
defaultConfig { defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.example.covidefender" applicationId "com.example.covidefender"
minSdkVersion 16 minSdkVersion 21
targetSdkVersion 30 targetSdkVersion 30
versionCode flutterVersionCode.toInteger() versionCode flutterVersionCode.toInteger()
versionName flutterVersionName versionName flutterVersionName
...@@ -48,6 +48,11 @@ android { ...@@ -48,6 +48,11 @@ android {
signingConfig signingConfigs.debug signingConfig signingConfigs.debug
} }
} }
aaptOptions {
noCompress 'tflite'
noCompress 'lite'
}
} }
flutter { flutter {
...@@ -56,4 +61,8 @@ flutter { ...@@ -56,4 +61,8 @@ flutter {
dependencies { dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.google.firebase:firebase-analytics'
} }
apply plugin: 'com.android.application'
apply plugin: 'com.google.gms.google-services'
{
"project_info": {
"project_number": "206817019032",
"firebase_url": "https://covidefender-5b8b1-default-rtdb.firebaseio.com",
"project_id": "covidefender-5b8b1",
"storage_bucket": "covidefender-5b8b1.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:206817019032:android:8c981d64ba61069de4bced",
"android_client_info": {
"package_name": "com.example.covidefender"
}
},
"oauth_client": [
{
"client_id": "206817019032-grv9328g4hup8db6vp987rt6nmrdmd3b.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyDTZ7KVRrYQylCKI58uqhe6ugoKhti1t8E"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "206817019032-grv9328g4hup8db6vp987rt6nmrdmd3b.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
}
],
"configuration_version": "1"
}
\ No newline at end of file
...@@ -8,6 +8,7 @@ buildscript { ...@@ -8,6 +8,7 @@ buildscript {
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:4.1.0' classpath 'com.android.tools.build:gradle:4.1.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.google.gms:google-services:4.3.8'
} }
} }
......
with_mask
without_mask
\ No newline at end of file
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class AddLocation extends StatefulWidget { class AddLocation extends StatefulWidget {
@override @override
...@@ -7,119 +8,113 @@ class AddLocation extends StatefulWidget { ...@@ -7,119 +8,113 @@ class AddLocation extends StatefulWidget {
class AddLocationState extends State<AddLocation> { class AddLocationState extends State<AddLocation> {
String _fName; String userName;
String _lName; String phoneNumber;
String _age; String riskLocation;
String _address; String hotelName;
String _nic; String date;
String _phoneNumber; String time;
String _riskLocation;
String _hotelName;
String _date;
String _time;
final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); getUserName(name){
this.userName= name;
}
Widget _buildFName(){ getPhoneNumber(pno){
return TextFormField( this.phoneNumber= pno;
decoration: InputDecoration(labelText: 'First Name'),
validator: (String value){
if (value.isEmpty) {
return '*First Name is Required';
}
},
onSaved: (String value){
_fName = value;
},
);
} }
Widget _buildLName(){ getRiskLocation(location){
return TextFormField( this.riskLocation= location;
decoration: InputDecoration(labelText: 'Last Name'),
validator: (String value){
if (value.isEmpty) {
return '*Last Name is Required';
}
},
onSaved: (String value){
_lName = value;
},
);
} }
Widget _buildAge(){ getHotelName(hotelname){
return TextFormField( this.hotelName= hotelname;
decoration: InputDecoration(labelText: 'Age'),
validator: (String value){
if (value.isEmpty) {
return '*Age is Required';
}
},
onSaved: (String value){
_age = value;
},
);
} }
Widget _buildAddress(){ getDate(date){
return TextFormField( this.date= date;
decoration: InputDecoration(labelText: 'Address'), }
validator: (String value){
if (value.isEmpty) { getTime(time){
return '*Address is Required'; this.time= time;
} }
},
onSaved: (String value){ createData(){
_address = value; print("object");
},
); DocumentReference documentReference = Firestore.instance.collection("RiskLocation").document(userName);
Map<String, dynamic> locations ={
"userName": userName,
"phoneNumber": phoneNumber,
"riskLocation": riskLocation,
"hotelName": hotelName,
"date": date,
"time": time
};
documentReference.setData(locations).whenComplete(() {
print("$userName created");
});
} }
Widget _buildNIC(){ final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
//---------------------------------------------User Name-----------------------------------------------------
Widget _buildName(){
return TextFormField( return TextFormField(
decoration: InputDecoration(labelText: 'NIC'), decoration: InputDecoration(labelText: 'Full Name'),
validator: (String value){ validator: (String value){
if (value.isEmpty) { if (value.isEmpty) {
return '*NIC is Required'; return '*Full Name is Required';
} }
}, },
onSaved: (String value){ // onSaved: (String value){
_nic = value; // _fName = value;
// },
onChanged: (String name){
getUserName(name);
}, },
); );
} }
Widget _buildPhoneNumber(){ //---------------------------------------------Phone Number-----------------------------------------------------
Widget _buildPNo(){
return TextFormField( return TextFormField(
decoration: InputDecoration(labelText: 'Phone Number'), decoration: InputDecoration(labelText: 'Phone Number'),
keyboardType: TextInputType.phone,
maxLength: 10,
validator: (String value){ validator: (String value){
if (value.isEmpty) { if (value.isEmpty) {
return '*Phone Number is Required'; return '*Phone Number is Required';
} }
}, },
onSaved: (String value){ // onSaved: (String value){
_phoneNumber = value; // _lName = value;
// },
onChanged: (String id){
getPhoneNumber(phoneNumber);
}, },
); );
} }
Widget _buildRiskLocation(){ //---------------------------------------------Risk Location-----------------------------------------------------
Widget _buildLocation(){
return TextFormField( return TextFormField(
decoration: InputDecoration(labelText: 'Risk Location'), decoration: InputDecoration(labelText: 'Risk Location'),
validator: (String value){ validator: (String value){
if (value.isEmpty) { if (value.isEmpty) {
return '*Location is Required'; return '*Risk Location is Required';
} }
}, },
onSaved: (String value){ // onSaved: (String value){
_riskLocation = value; // _age = value;
// },
onChanged: (String riskLocation){
getRiskLocation(riskLocation);
}, },
); );
} }
//---------------------------------------------Hotel Name-----------------------------------------------------
Widget _buildHotelName(){ Widget _buildHotelName(){
return TextFormField( return TextFormField(
decoration: InputDecoration(labelText: 'Hotel Name'), decoration: InputDecoration(labelText: 'Hotel Name'),
...@@ -128,37 +123,49 @@ Widget _buildHotelName(){ ...@@ -128,37 +123,49 @@ Widget _buildHotelName(){
return '*Hotel Name is Required'; return '*Hotel Name is Required';
} }
}, },
onSaved: (String value){ // onSaved: (String value){
_hotelName = value; // _address = value;
// },
onChanged: (String hotelName){
getHotelName(hotelName);
}, },
); );
} }
//---------------------------------------------Date-----------------------------------------------------
Widget _buildDate(){ Widget _buildDate(){
return TextFormField( return TextFormField(
decoration: InputDecoration(labelText: 'Date'), decoration: InputDecoration(labelText: 'Date'),
keyboardType: TextInputType.datetime,
validator: (String value){ validator: (String value){
if (value.isEmpty) { if (value.isEmpty) {
return '*Date is Required'; return '*Date is Required';
} }
}, },
onSaved: (String value){ // onSaved: (String value){
_date = value; // _nic = value;
// },
onChanged: (String date){
getDate(date);
}, },
); );
} }
//---------------------------------------------Time-----------------------------------------------------
Widget _buildTime(){ Widget _buildTime(){
return TextFormField( return TextFormField(
decoration: InputDecoration(labelText: 'Time'), decoration: InputDecoration(labelText: 'Time'),
keyboardType: TextInputType.phone,
maxLength: 10,
validator: (String value){ validator: (String value){
if (value.isEmpty) { if (value.isEmpty) {
return '*Time is Required'; return '*Time is Required';
} }
}, },
onSaved: (String value){ // onSaved: (String value){
_time = value; // _phoneNumber = value;
// },
onChanged: (String time){
getTime(time);
}, },
); );
} }
...@@ -177,18 +184,15 @@ Widget _buildTime(){ ...@@ -177,18 +184,15 @@ Widget _buildTime(){
child: Form( child: Form(
key: _formKey, key: _formKey,
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[ children: <Widget>[
_buildFName(), _buildName(),
_buildLName(), _buildPNo(),
_buildAge(), _buildLocation(),
_buildAddress(), _buildHotelName(),
_buildNIC(), _buildDate(),
_buildPhoneNumber(), _buildTime(),
_buildRiskLocation(),
_buildHotelName(),
_buildDate(),
_buildTime(),
SizedBox(height: 100), SizedBox(height: 100),
RaisedButton( RaisedButton(
...@@ -201,23 +205,24 @@ Widget _buildTime(){ ...@@ -201,23 +205,24 @@ Widget _buildTime(){
return; return;
} }
_formKey.currentState.save(); // _formKey.currentState.save();
print(_fName); // print(_fName);
print(_lName); // print(_lName);
print(_age); // print(_age);
print(_address); // print(_address);
print(_nic); // print(_nic);
print(_phoneNumber); // print(_phoneNumber);
print(_riskLocation); // print(_riskLocation);
print(_hotelName); // print(_hotelName);
print(_date); // print(_date);
print(_time); // print(_time);
createData();
} , } ,
) )
], ],
),), ),),
), ),
......
import 'package:covidefender/pages/heart_rate/heart_rate_screen.dart';
import 'package:covidefender/pages/mask_detect/invoker.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class I_guider extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[200],
appBar: AppBar(
title: Text('I-Guider'),
// elevation: 0,
),
body: Column(
children: [
Row(
children: [
Expanded(
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('lib/assets/images/hero.gif'),
fit: BoxFit.cover)),
height: 300,
),
),
],
),
//------------------------------------
SizedBox(
height: 50,
),
Row(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.fromLTRB(8, 0, 8, 0),
child: ButtonTheme(
minWidth: 100.0,
height: 150.0,
child: RaisedButton.icon(
icon: Icon(
Icons.bluetooth_audio_rounded,
size: 40,
color: Colors.white,
),
label: Text('',
style: TextStyle(fontWeight: FontWeight.bold)),
onPressed: () {},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)),
color: Colors.blue[200],
),
),
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.fromLTRB(8, 0, 8, 0),
child: ButtonTheme(
minWidth: 100.0,
height: 150.0,
child: RaisedButton.icon(
color: Colors.greenAccent,
icon: Icon(
Icons.face_unlock_sharp,
size: 60,
color: Colors.white,
),
label: Text(
'',
style: TextStyle(fontWeight: FontWeight.bold),
),
onPressed: () {
print('face mask detection');
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => invoker())
);
// Navigator.pushNamed(context, '/invoker');
},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)),
),
),
),
)
],
),
SizedBox(height: 30),
Row(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.fromLTRB(8, 0, 8, 0),
child: ButtonTheme(
minWidth: 100.0,
height: 150.0,
child: RaisedButton.icon(
icon: Icon(
Icons.view_stream_outlined,
size: 40,
color: Colors.white,
),
label: Text('',
style: TextStyle(fontWeight: FontWeight.bold)),
onPressed: () {
// action when button is pressed route to heart rate measurer
Navigator.push(context, MaterialPageRoute(builder: (context) => HeartRateScreen() ));
},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)),
color: Colors.redAccent,
),
),
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.fromLTRB(8, 0, 8, 0),
child: ButtonTheme(
minWidth: 100.0,
height: 150.0,
child: RaisedButton.icon(
color: Colors.purple[200],
icon: Icon(
Icons.online_prediction_sharp,
size: 60,
color: Colors.white,
),
label: Text(
'',
style: TextStyle(fontWeight: FontWeight.bold),
),
onPressed: () {},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)),
),
),
),
)
],
),
],
),
);
}
}
import 'dart:async';
import 'package:flutter/material.dart';
import 'i_guider.dart';
class SplashScreen extends StatefulWidget {
@override
_SplashScreenState createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen> {
@override
void initState() {
super.initState();
Timer(Duration(seconds: 3), () {
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (context) => I_guider(),
));
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.blue[400],
body: Center(
child: Text(
"I-GUIDER",
style: TextStyle(
fontSize: 50.0,
color: Colors.white,
),
),
),
);
}
}
with_mask
without_mask
\ No newline at end of file
import 'package:covidefender/I_GUIDER/splashIguider.dart';
import 'package:covidefender/STracker/splash.dart'; import 'package:covidefender/STracker/splash.dart';
import 'package:covidefender/EAnalyzer/Loading.dart'; import 'package:covidefender/EAnalyzer/Loading.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
...@@ -131,13 +132,18 @@ class _HomeScreenState extends State<HomeScreen> { ...@@ -131,13 +132,18 @@ class _HomeScreenState extends State<HomeScreen> {
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[ children: <Widget>[
Container( FlatButton(
height: size.height * .1, onPressed: () {
decoration: BoxDecoration( Navigator.push(
image: DecorationImage( context,
image: AssetImage( MaterialPageRoute(
'lib/assets/images/coach80.png')), builder: (context) =>
)), SplashScreen()),
);
},
child: Image.asset(
'lib/assets/images/coach80.png'),
),
Text('Intelligent Guider', Text('Intelligent Guider',
style: TextStyle(fontSize: 20.0)) style: TextStyle(fontSize: 20.0))
], ],
......
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'home_screen.dart'; import 'home_screen.dart';
void main() => runApp(MyApp()); // void main() => runApp(MyApp());
void main() async{
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
}
class MyApp extends StatelessWidget { class MyApp extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
......
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter/material.dart';
class Chart extends StatelessWidget {
final List<SensorValue> _data;
Chart(this._data);
@override
Widget build(BuildContext context) {
return new charts.TimeSeriesChart([
charts.Series<SensorValue, DateTime>(
id: 'Values',
colorFn: (_, __) => charts.MaterialPalette.green.shadeDefault,
domainFn: (SensorValue values, _) => values.time,
measureFn: (SensorValue values, _) => values.value,
data: _data,
)
],
animate: false,
primaryMeasureAxis: charts.NumericAxisSpec(
tickProviderSpec:
charts.BasicNumericTickProviderSpec(zeroBound: false),
renderSpec: charts.NoneRenderSpec(),
),
domainAxis: new charts.DateTimeAxisSpec(
renderSpec: new charts.NoneRenderSpec()));
}
}
class SensorValue {
final DateTime time;
final double value;
SensorValue(this.time, this.value);
}
import 'package:covidefender/pages/heart_rate/homePage.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class HeartRateScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Heart Rate Detector'),
),
body: Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Image.asset('lib/assets/images/pulse.gif'),
),
SizedBox(height: 20),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ElevatedButton(
onPressed: () => Navigator.push(context, MaterialPageRoute(builder: (context) => HomePage(),)),
child: Text('Measure Heart Rate'),
),
],
),
],
),
);
}
}
import 'dart:async';
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import 'package:wakelock/wakelock.dart';
import 'chart.dart';
class HomePage extends StatefulWidget {
@override
HomePageView createState() {
return HomePageView();
}
}
class HomePageView extends State<HomePage> with SingleTickerProviderStateMixin {
bool _toggled = false; // toggle button value
List<SensorValue> _data = List<SensorValue>(); // array to store the values
CameraController _controller;
double _alpha = 0.3; // factor for the mean value
AnimationController _animationController;
double _iconScale = 1;
int _bpm = 0; // beats per minute
int _fs = 30; // sampling frequency (fps)
int _windowLen = 30 * 6; // window length to display - 6 seconds
CameraImage _image; // store the last camera image
double _avg; // store the average value during calculation
DateTime _now; // store the now Datetime
Timer _timer; // timer for image processing
@override
void initState() {
super.initState();
_animationController =
AnimationController(duration: Duration(milliseconds: 500), vsync: this);
_animationController
..addListener(() {
setState(() {
_iconScale = 1.0 + _animationController.value * 0.4;
});
});
}
@override
void dispose() {
_timer?.cancel();
_toggled = false;
_disposeController();
Wakelock.disable();
_animationController?.stop();
_animationController?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: SafeArea(
child: Column(
children: <Widget>[
Expanded(
flex: 1,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Expanded(
flex: 1,
child: Padding(
padding: EdgeInsets.all(12),
child: ClipRRect(
borderRadius: BorderRadius.all(
Radius.circular(18),
),
child: Stack(
fit: StackFit.expand,
alignment: Alignment.center,
children: <Widget>[
_controller != null && _toggled
? AspectRatio(
aspectRatio:
_controller.value.aspectRatio,
child: CameraPreview(_controller),
)
: Container(
padding: EdgeInsets.all(12),
alignment: Alignment.center,
color: Colors.grey,
),
Container(
alignment: Alignment.center,
padding: EdgeInsets.all(4),
child: Text(
_toggled
? "Cover both the camera and the flash with your finger"
: "Camera feed will display here",
style: TextStyle(
backgroundColor: _toggled
? Colors.white
: Colors.transparent),
textAlign: TextAlign.center,
),
)
],
),
),
),
),
Expanded(
flex: 1,
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
"Estimated BPM",
style: TextStyle(fontSize: 18, color: Colors.grey),
),
Text(
(_bpm > 30 && _bpm < 150 ? _bpm.toString() : "--"),
style: TextStyle(
fontSize: 32, fontWeight: FontWeight.bold),
),
],
)),
),
],
)),
Expanded(
flex: 1,
child: Center(
child: Transform.scale(
scale: _iconScale,
child: IconButton(
icon:
Icon(_toggled ? Icons.favorite : Icons.favorite_border),
color: Colors.red,
iconSize: 128,
onPressed: () {
if (_toggled) {
_untoggle();
} else {
_toggle();
}
},
),
),
),
),
Expanded(
flex: 1,
child: Container(
margin: EdgeInsets.all(12),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(18),
),
color: Colors.black),
child: Chart(_data),
),
),
],
),
),
);
}
void _clearData() {
// create array of 128 ~= 255/2
_data.clear();
int now = DateTime.now().millisecondsSinceEpoch;
for (int i = 0; i < _windowLen; i++)
_data.insert(
0,
SensorValue(
DateTime.fromMillisecondsSinceEpoch(now - i * 1000 ~/ _fs), 128));
}
void _toggle() {
_clearData();
_initController().then((onValue) {
Wakelock.enable();
_animationController?.repeat(reverse: true);
setState(() {
_toggled = true;
});
// after is toggled
_initTimer();
_updateBPM();
});
}
void _untoggle() {
_disposeController();
Wakelock.disable();
_animationController?.stop();
_animationController?.value = 0.0;
setState(() {
_toggled = false;
});
}
void _disposeController() {
_controller?.dispose();
_controller = null;
}
Future<void> _initController() async {
try {
List _cameras = await availableCameras();
_controller = CameraController(_cameras.first, ResolutionPreset.low);
await _controller.initialize();
Future.delayed(Duration(milliseconds: 100)).then((onValue) {
// _controller.flash(true);
});
_controller.startImageStream((CameraImage image) {
_image = image;
});
} catch (Exception) {
debugPrint(Exception);
}
}
void _initTimer() {
_timer = Timer.periodic(Duration(milliseconds: 1000 ~/ _fs), (timer) {
if (_toggled) {
if (_image != null) _scanImage(_image);
} else {
timer.cancel();
}
});
}
void _scanImage(CameraImage image) {
_now = DateTime.now();
_avg =
image.planes.first.bytes.reduce((value, element) => value + element) /
image.planes.first.bytes.length;
if (_data.length >= _windowLen) {
_data.removeAt(0);
}
setState(() {
_data.add(SensorValue(_now, _avg));
});
}
void _updateBPM() async {
// Bear in mind that the method used to calculate the BPM is very rudimentar
// feel free to improve it :)
// Since this function doesn't need to be so "exact" regarding the time it executes,
// I only used the a Future.delay to repeat it from time to time.
// Ofc you can also use a Timer object to time the callback of this function
List<SensorValue> _values;
double _avg;
int _n;
double _m;
double _threshold;
double _bpm;
int _counter;
int _previous;
while (_toggled) {
_values = List.from(_data); // create a copy of the current data array
_avg = 0;
_n = _values.length;
_m = 0;
_values.forEach((SensorValue value) {
_avg += value.value / _n;
if (value.value > _m) _m = value.value;
});
_threshold = (_m + _avg) / 2;
_bpm = 0;
_counter = 0;
_previous = 0;
for (int i = 1; i < _n; i++) {
if (_values[i - 1].value < _threshold &&
_values[i].value > _threshold) {
if (_previous != 0) {
_counter++;
_bpm += 60 *
1000 /
(_values[i].time.millisecondsSinceEpoch - _previous);
}
_previous = _values[i].time.millisecondsSinceEpoch;
}
}
if (_counter > 0) {
_bpm = _bpm / _counter;
print(_bpm);
setState(() {
this._bpm = ((1 - _alpha) * this._bpm + _alpha * _bpm).toInt();
});
}
await Future.delayed(Duration(
milliseconds:
1000 * _windowLen ~/ _fs)); // wait for a new set of _data values
}
}
}
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import 'package:oktoast/oktoast.dart';
import 'package:tflite/tflite.dart';
import 'camera_page.dart';
class MaskDetectingApp extends StatelessWidget {
const MaskDetectingApp({
@required List<CameraDescription> cameras,
}) : assert(cameras != null),
_cameras = cameras;
final List<CameraDescription> _cameras;
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Face mask detecting',
theme: ThemeData(
brightness: Brightness.dark,
),
builder: (BuildContext context, Widget widget) => OKToast(
child: widget,
),
home: CameraPage(
cameras: _cameras,
),
);
}
}
import 'dart:math';
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'overlay.dart' as ol;
import 'package:tflite/tflite.dart';
class CameraPage extends StatefulWidget {
const CameraPage({
@required List<CameraDescription> cameras,
}) : assert(cameras != null),
_cameras = cameras;
final List<CameraDescription> _cameras;
@override
_CameraPageState createState() => _CameraPageState();
}
class _CameraPageState extends State<CameraPage> with WidgetsBindingObserver {
CameraController _controller;
bool _isDetecting = false;
bool _rear = false;
List<dynamic> _recognitions;
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (_controller == null || !_controller.value.isInitialized) {
return;
}
if (state == AppLifecycleState.inactive) {
_controller?.dispose();
} else if (state == AppLifecycleState.resumed) {
if (_controller != null) {
_setupCamera();
}
}
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
_controller?.dispose();
super.dispose();
}
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
_setupCamera();
}
void _setupCamera() {
if (widget._cameras == null || widget._cameras.isEmpty) {
print('No camera is found');
} else {
_controller = CameraController(
widget._cameras[_rear ? 0 : 1],
ResolutionPreset.max,
);
_controller.initialize().then((_) {
if (_updateCamera()) {
_readFrames();
}
});
}
}
Future<void> _switchCameraLens() async {
_rear = !_rear;
await _controller?.dispose();
_setupCamera();
}
bool _updateCamera() {
if (!mounted) {
return false;
}
setState(() {});
return true;
}
void _updateRecognitions({
List<dynamic> recognitions,
}) {
setState(() {
_recognitions = recognitions;
});
}
void _readFrames() {
_controller.startImageStream(
(CameraImage img) {
if (!_isDetecting) {
_isDetecting = true;
Tflite.runModelOnFrame(
bytesList: img.planes.map((Plane plane) {
return plane.bytes;
}).toList(),
imageWidth: img.width,
imageHeight: img.height,
numResults: 2,
).then((List<dynamic> recognitions) {
_updateRecognitions(
recognitions: recognitions,
);
_isDetecting = false;
});
}
},
);
}
@override
Widget build(BuildContext context) {
if (_controller == null || !_controller.value.isInitialized) {
return Container();
}
final Size screen = MediaQuery.of(context).size;
final double screenH = max(screen.height, screen.width);
final double screenW = min(screen.height, screen.width);
final Size previewSize = _controller.value.previewSize;
final double previewH = max(previewSize.height, previewSize.width);
final double previewW = min(previewSize.height, previewSize.width);
final double screenRatio = screenH / screenW;
final double previewRatio = previewH / previewW;
return Scaffold(
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
floatingActionButton: FloatingActionButton(
onPressed: () async => _switchCameraLens(),
child: Icon(_rear ? Icons.camera_front : Icons.camera_rear),
backgroundColor: Colors.green,
),
body: Stack(
children: <Widget>[
OverflowBox(
maxHeight: screenRatio > previewRatio
? screenH
: screenW / previewW * previewH,
maxWidth: screenRatio > previewRatio
? screenH / previewH * previewW
: screenW,
child: CameraPreview(_controller),
),
ol.Overlay(
results: _recognitions ?? <dynamic>[],
)
],
),
);
}
}
import 'package:camera/camera.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:tflite/tflite.dart';
import 'cameara_service.dart';
class invoker extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Face Mask Detector'),
),
body: Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Image.asset('lib/assets/images/wear.gif'),
),
SizedBox(height: 20),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ElevatedButton(
onPressed: () => invokeCamera(),
child: Text('Detect Mask'),
),
],
),
],
),
);
}
Future<void> invokeCamera() async {
WidgetsFlutterBinding.ensureInitialized();
print(await Tflite.loadModel(
model: 'lib/assets/model.tflite', labels: "lib/assets/labels.txt"));
runApp(MaskDetectingApp(
cameras: await availableCameras(),
));
}
}
import 'dart:async';
import 'package:flutter/material.dart';
import 'toast.dart';
import 'package:oktoast/oktoast.dart';
class Overlay extends StatefulWidget {
const Overlay({
@required List<dynamic> results,
this.threshold = 0.5,
}) : _results = results;
final List<dynamic> _results;
final double threshold;
@override
_OverlayState createState() => _OverlayState();
}
class _OverlayState extends State<Overlay> {
ToastFuture _toastFuture;
String _label;
double _confidence = 0;
set label(String value) => setState(() {
_label = value;
});
set confidence(double value) => setState(() {
_confidence = value;
});
String get label => _label;
double get confidence => _confidence;
Color _updateBorderColor(
BuildContext context,
List<dynamic> bits,
) {
if (bits == null) {
return Colors.transparent;
}
if (bits.length > 1) {
final String firstLabel = bits.first["label"] as String;
final double firstConfidence = bits.first["confidence"] as double;
final String secondLabel = bits.last["label"] as String;
final double secondConfidence = bits.last["confidence"] as double;
if (firstConfidence > secondConfidence) {
label = firstLabel;
confidence = firstConfidence;
} else {
label = secondLabel;
confidence = secondConfidence;
}
}
if (bits.length == 1) {
label = bits.first["label"] as String;
confidence = bits.first["confidence"] as double;
}
if (confidence < widget.threshold) {
scheduleMicrotask(() => _toastFuture ??= Toast.show(
context,
ToastType.error,
"Please keep the camera steady and keep a certain distance to prevent shaking.",
onDismiss: () {
_toastFuture = null;
}));
return Colors.transparent;
}
if (label == "without_mask") {
return Colors.red;
}
if (label == "with_mask") {
return Colors.greenAccent;
}
return Colors.transparent;
}
@override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
Container(
decoration: BoxDecoration(
border: Border.fromBorderSide(BorderSide(
color: _updateBorderColor(
context,
widget._results,
),
width: 10,
)),
),
),
Container(
margin: const EdgeInsets.symmetric(
horizontal: 85,
),
child: Column(
children: <Widget>[
SizedBox(
height: MediaQuery.of(context).padding.top,
),
Align(
alignment: Alignment.center,
child: Text(
label == "with_mask"
? "Wearing mask ${(confidence * 100).toStringAsFixed(0)}%"
: "No mask ${(confidence * 100).toStringAsFixed(0)}%",
style: Theme.of(context).textTheme.caption.copyWith(
color: label == "with_mask"
? Colors.greenAccent
: Colors.red,
),
),
),
Align(
alignment: Alignment.center,
child: LinearProgressIndicator(
value: confidence,
valueColor: AlwaysStoppedAnimation<Color>(
label == "with_mask" ? Colors.greenAccent : Colors.red),
minHeight: 15,
),
),
],
),
),
],
);
}
}
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:oktoast/oktoast.dart';
class SlideFadeInToastAnimation extends BaseAnimationBuilder {
@override
Widget buildWidget(
BuildContext context,
Widget child,
AnimationController controller,
double percent,
) {
final double opacity = min(1.0, percent + 0.2);
final double offset = (1 + percent) * 11;
return Opacity(
opacity: opacity,
child: Transform.translate(
child: child,
offset: Offset(0, offset),
),
);
}
}
import 'package:flutter/material.dart';
import 'slide_fade_in_toast_animation.dart';
import 'package:oktoast/oktoast.dart';
class Toast {
static const Duration kToastDuration = Duration(seconds: 3);
static ToastFuture show(
BuildContext context,
ToastType type,
String text, {
VoidCallback onDismiss,
Duration duration = kToastDuration,
bool dismissEnable = true,
}) {
return showToastWidget(
_buildToast(context, type, text, dismissEnable),
context: context,
position: const ToastPosition(align: Alignment.topCenter),
duration: dismissEnable ? duration : const Duration(days: 1),
handleTouch: true,
onDismiss: onDismiss,
animationBuilder: SlideFadeInToastAnimation(),
);
}
static void dismissAll({bool animated}) {
dismissAllToast(showAnim: animated);
}
static Widget _buildOkButton(BuildContext context) {
return Row(
children: <Widget>[
const SizedBox(
width: 10.0,
),
GestureDetector(
onTap: () => dismissAllToast(showAnim: true),
child: Text(
"OK",
style: Theme.of(context).textTheme.overline.copyWith(
color: Colors.white,
),
),
)
],
);
}
static Widget _buildToast(
BuildContext context,
ToastType type,
String text,
bool dismissEnable,
) {
return SafeArea(
child: Container(
margin: const EdgeInsets.symmetric(horizontal: 10.0),
child: Material(
color: Colors.black,
borderRadius: const BorderRadius.all(Radius.circular(10.0)),
child: Container(
padding:
const EdgeInsets.symmetric(vertical: 12.0, horizontal: 16.0),
child: Row(
children: <Widget>[
if (type == ToastType.success)
const Image(
image: AssetImage('lib/assets/toast_check_mark.png'),
width: 18.0,
height: 18.0,
)
else if (type == ToastType.error)
const Image(
image: AssetImage('lib/assets/toast_error.png'),
width: 18.0,
height: 18.0,
)
else
throw Exception("Wrong toast type!"),
const SizedBox(
width: 16.0,
),
Expanded(
child: Text(
text,
overflow: TextOverflow.clip,
style: Theme.of(context)
.textTheme
.bodyText1
.copyWith(color: Colors.white),
),
),
if (dismissEnable) _buildOkButton(context),
],
),
),
),
),
);
}
}
enum ToastType {
success,
error,
}
...@@ -15,6 +15,22 @@ packages: ...@@ -15,6 +15,22 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.0" version: "2.1.0"
camera:
dependency: "direct main"
description:
path: "packages/camera/camera"
ref: HEAD
resolved-ref: a2ce3dab466125c86e275e70cb04355a8c3daa16
url: "http://github.com/indikaNK/plugins.git"
source: git
version: "0.8.1"
camera_platform_interface:
dependency: transitive
description:
name: camera_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
characters: characters:
dependency: transitive dependency: transitive
description: description:
...@@ -29,6 +45,20 @@ packages: ...@@ -29,6 +45,20 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.0" version: "1.2.0"
charts_common:
dependency: transitive
description:
name: charts_common
url: "https://pub.dartlang.org"
source: hosted
version: "0.9.0"
charts_flutter:
dependency: "direct main"
description:
name: charts_flutter
url: "https://pub.dartlang.org"
source: hosted
version: "0.9.0"
clock: clock:
dependency: transitive dependency: transitive
description: description:
...@@ -36,6 +66,27 @@ packages: ...@@ -36,6 +66,27 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0" version: "1.1.0"
cloud_firestore:
dependency: "direct main"
description:
name: cloud_firestore
url: "https://pub.dartlang.org"
source: hosted
version: "0.14.4"
cloud_firestore_platform_interface:
dependency: transitive
description:
name: cloud_firestore_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.1"
cloud_firestore_web:
dependency: transitive
description:
name: cloud_firestore_web
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.1+2"
collection: collection:
dependency: transitive dependency: transitive
description: description:
...@@ -43,6 +94,13 @@ packages: ...@@ -43,6 +94,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.15.0" version: "1.15.0"
cross_file:
dependency: transitive
description:
name: cross_file
url: "https://pub.dartlang.org"
source: hosted
version: "0.3.1+1"
cupertino_icons: cupertino_icons:
dependency: "direct main" dependency: "direct main"
description: description:
...@@ -57,6 +115,27 @@ packages: ...@@ -57,6 +115,27 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.0" version: "1.2.0"
firebase_core:
dependency: "direct main"
description:
name: firebase_core
url: "https://pub.dartlang.org"
source: hosted
version: "0.5.3"
firebase_core_platform_interface:
dependency: transitive
description:
name: firebase_core_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
firebase_core_web:
dependency: transitive
description:
name: firebase_core_web
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.1+1"
flutter: flutter:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
...@@ -74,6 +153,39 @@ packages: ...@@ -74,6 +153,39 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
flutter_web_plugins:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
http_parser:
dependency: transitive
description:
name: http_parser
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.4"
intl:
dependency: transitive
description:
name: intl
url: "https://pub.dartlang.org"
source: hosted
version: "0.16.1"
js:
dependency: transitive
description:
name: js
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.3"
logging:
dependency: transitive
description:
name: logging
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
matcher: matcher:
dependency: transitive dependency: transitive
description: description:
...@@ -88,6 +200,13 @@ packages: ...@@ -88,6 +200,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.3.0" version: "1.3.0"
oktoast:
dependency: "direct main"
description:
name: oktoast
url: "https://pub.dartlang.org"
source: hosted
version: "2.3.2"
path: path:
dependency: transitive dependency: transitive
description: description:
...@@ -109,6 +228,13 @@ packages: ...@@ -109,6 +228,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.2.0" version: "0.2.0"
pedantic:
dependency: transitive
description:
name: pedantic
url: "https://pub.dartlang.org"
source: hosted
version: "1.11.0"
petitparser: petitparser:
dependency: transitive dependency: transitive
description: description:
...@@ -116,6 +242,20 @@ packages: ...@@ -116,6 +242,20 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "4.1.0" version: "4.1.0"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.3"
quiver:
dependency: "direct main"
description:
name: quiver
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.1"
sky_engine: sky_engine:
dependency: transitive dependency: transitive
description: flutter description: flutter
...@@ -142,6 +282,13 @@ packages: ...@@ -142,6 +282,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.0" version: "2.1.0"
stream_transform:
dependency: transitive
description:
name: stream_transform
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
string_scanner: string_scanner:
dependency: transitive dependency: transitive
description: description:
...@@ -163,6 +310,13 @@ packages: ...@@ -163,6 +310,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.2.19" version: "0.2.19"
tflite:
dependency: "direct main"
description:
name: tflite
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.2"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:
...@@ -177,6 +331,13 @@ packages: ...@@ -177,6 +331,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.0" version: "2.1.0"
wakelock:
dependency: "direct main"
description:
name: wakelock
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.4+2"
xml: xml:
dependency: transitive dependency: transitive
description: description:
......
...@@ -24,6 +24,11 @@ dependencies: ...@@ -24,6 +24,11 @@ dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
flutter_svg: ^0.22.0 flutter_svg: ^0.22.0
tflite: ^1.1.1
oktoast: ^2.3.2
quiver: ^2.0.0
cloud_firestore: ^0.14.3
firebase_core : ^0.5.0
...@@ -31,9 +36,19 @@ dependencies: ...@@ -31,9 +36,19 @@ dependencies:
# Use with the CupertinoIcons class for iOS style icons. # Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2 cupertino_icons: ^1.0.2
#add dependencies for heart rate module
charts_flutter: ^0.9.0
wakelock: ^0.1.4+1
camera:
git:
url: http://github.com/indikaNK/plugins.git
path: packages/camera/camera
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter
dependency_overrides:
quiver: ^3.0.0
# For information on the generic Dart part of this file, see the # For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec # following page: https://dart.dev/tools/pub/pubspec
...@@ -60,8 +75,6 @@ flutter: ...@@ -60,8 +75,6 @@ flutter:
- lib/assets/images/feedback80.png - lib/assets/images/feedback80.png
- lib/assets/images/list80.png - lib/assets/images/list80.png
- lib/assets/images/search80.png - lib/assets/images/search80.png
- lib/assets/ - lib/assets/
- lib/assets/images/awrenessLevel.png - lib/assets/images/awrenessLevel.png
- lib/assets/images/exit.png - lib/assets/images/exit.png
...@@ -85,6 +98,18 @@ flutter: ...@@ -85,6 +98,18 @@ flutter:
- lib/assets/images/5.png - lib/assets/images/5.png
- lib/assets/images/6.png - lib/assets/images/6.png
- lib/assets/images/hero.gif
- lib/assets/images/map80.png
- lib/assets/images/man80.png
- lib/assets/images/bar80.png
- lib/assets/images/coach80.png
- lib/assets/images/time80.png
- lib/assets/images/event80.png
- lib/assets/images/pulse.gif
- lib/assets/model.tflite
- lib/assets/labels.txt
- assets/
- lib/assets/images/wear.gif
# To add assets to your application, add an assets section, like this: # To add assets to your application, add an assets section, like this:
# assets: # assets:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment