Files
fcs/lib/face/face_detection_camera.dart
2020-05-29 07:45:27 +06:30

178 lines
4.7 KiB
Dart

import 'smile_painter.dart';
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';
import 'package:firebase_ml_vision/firebase_ml_vision.dart';
import 'package:flutter/foundation.dart';
import 'dart:ui' as ui show Image;
import 'utils.dart';
class FaceDetectionFromLiveCamera extends StatefulWidget {
FaceDetectionFromLiveCamera({Key key}) : super(key: key);
@override
_FaceDetectionFromLiveCameraState createState() =>
_FaceDetectionFromLiveCameraState();
}
class _FaceDetectionFromLiveCameraState
extends State<FaceDetectionFromLiveCamera> {
final FaceDetector faceDetector = FirebaseVision.instance.faceDetector();
List<Face> faces;
CameraController _camera;
bool _isDetecting = false;
CameraLensDirection _direction = CameraLensDirection.back;
@override
void initState() {
super.initState();
_initializeCamera();
}
void _initializeCamera() async {
CameraDescription description = await getCamera(_direction);
ImageRotation rotation = rotationIntToImageRotation(
description.sensorOrientation,
);
_camera = CameraController(
description,
defaultTargetPlatform == TargetPlatform.iOS
? ResolutionPreset.low
: ResolutionPreset.medium,
);
await _camera.initialize();
_camera.startImageStream((CameraImage image) {
if (_isDetecting) return;
_isDetecting = true;
detect(
image,
FirebaseVision.instance
.faceDetector(FaceDetectorOptions(
mode: FaceDetectorMode.accurate,
enableClassification: true))
.processImage,
rotation)
.then(
(dynamic result) {
setState(() {
faces = result;
});
_isDetecting = false;
},
).catchError(
(_) {
_isDetecting = false;
},
);
});
}
Widget _buildResults() {
const Text noResultsText = const Text('No results!');
const Text multipleFaceText = const Text('Multiple faces!');
const Text pleaseSmileText = const Text('Please smile!');
if (faces == null || _camera == null || !_camera.value.isInitialized) {
return noResultsText;
}
CustomPainter painter;
final Size imageSize = Size(
_camera.value.previewSize.height,
_camera.value.previewSize.width,
);
if (faces is! List<Face> ||
faces.isEmpty ||
faces == null ||
faces.length == 0) return noResultsText;
if (faces.length > 1) return multipleFaceText;
var face = faces[0];
if (face.smilingProbability == null || face.smilingProbability < 0.8) {
return pleaseSmileText;
}
painter = SmilePainterLiveCamera(imageSize, faces);
return CustomPaint(
painter: painter,
);
}
Widget _buildImage() {
return Container(
constraints: const BoxConstraints.expand(),
child: _camera == null
? const Center(
child: Text(
'Initializing Camera...',
style: TextStyle(
color: Colors.green,
fontSize: 30.0,
),
),
)
: Stack(
fit: StackFit.expand,
children: <Widget>[
CameraPreview(_camera),
_buildResults(),
Positioned(
bottom: 0.0,
left: 0.0,
right: 0.0,
child: Container(
color: Colors.white,
height: 50.0,
child: ListView(
children: faces
.map((face) => Text(
"${face.boundingBox.center.toString()}, Smile:${face.smilingProbability}"))
.toList(),
),
),
),
],
),
);
}
void _toggleCameraDirection() async {
if (_direction == CameraLensDirection.back) {
_direction = CameraLensDirection.front;
} else {
_direction = CameraLensDirection.back;
}
await _camera.stopImageStream();
await _camera.dispose();
setState(() {
_camera = null;
});
_initializeCamera();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Face Detection with Smile"),
),
body: _buildImage(),
floatingActionButton: FloatingActionButton(
onPressed: _toggleCameraDirection,
child: _direction == CameraLensDirection.back
? const Icon(Icons.camera_front)
: const Icon(Icons.camera_rear),
),
);
}
}