Flutter人脸检测插件learning_face_detection的使用
Flutter人脸检测插件learning_face_detection的使用
ML Face Detection
使用ML Kit在Flutter中进行人脸检测的一个简单方法。通过ML Kit的人脸检测,我们可以在图像中检测到人脸,识别关键面部特征,并获取检测到的人脸轮廓。请注意:它只是检测人脸,而不是识别人。
由于它可以实时执行人脸检测,因此我们可以将其用于视频聊天、游戏或TikTok等应用程序,这些应用程序可以响应用户的表情。
为了更好地了解人脸检测的过程,包括标志点、轮廓和分类,请先阅读相关概念。
Getting Started
将依赖项添加到您的Flutter项目:
$ flutter pub add learning_face_detection
或者在pubspec.yaml
文件中添加:
dependencies:
learning_face_detection: ^0.0.2
然后运行 flutter pub get
。
Usage
导入包:
import 'package:learning_face_detection/learning_face_detection.dart';
Input Image
输入图像作为InputImage
实例传递,它是learning_input_image
包的一部分。
您可以使用learning_input_image
中的InputCameraView
小部件作为默认实现,以处理来自相机/存储的图像(或图像流)并将其转换为InputImage
格式。
以下是使用InputCameraView
获取InputImage
进行人脸检测的示例:
import 'package:learning_input_image/learning_input_image.dart';
InputCameraView(
title: 'Face Detection',
onImage: (InputImage image) {
// 现在我们可以将输入图像馈送到人脸检测器
},
)
Face Detection
获取InputImage
后,我们可以通过调用FaceDetector
实例的detect
方法开始检测人脸:
FaceDetector detector = FaceDetector();
List<Face> result = await detector.detect(image);
FaceDetector
实例化时带有以下默认参数:
FaceDetector detector = FaceDetector(
mode: FaceDetectorMode.fast, // 检测模式:快速或准确
detectLandmark: true, // 是否检测标志点
detectContour: true, // 是否检测轮廓
enableClassification: false, // 是否启用分类
enableTracking: false, // 是否启用跟踪
minFaceSize: 0.15, // 最小人脸大小
)
但是我们可以通过传递其他值来覆盖这些默认值。
参数 | 值 | 默认值 |
---|---|---|
mode | FaceDetectorMode.fast / FaceDetectorMode.accurate | FaceDetectorMode.fast |
detectLandmark | false / true | false |
detectContour | false / true | false |
enableClassification | false / true | false |
enableTracking | false / true | false |
minFaceSize | 0.0 到 1.0 之间的任何值 | 0.15 |
Output
人脸检测过程的结果是一个Face
对象列表,每个对象包含以下内容:
Rect boundingBox // 显示检测到的人脸的矩形
double headAngleY // 头部向右旋转的角度
double headAngleZ // 头部侧倾的角度
int? trackingId // 跟踪ID
double? smilingProbability // 笑脸的概率
double? leftEyeOpenProbability // 左眼睁开的概率
double? rightEyeOpenProbability // 右眼睁开的概率
Map<FaceLandmarkType, FaceLandmark> landmarks // 标志点列表
Map<FaceContourType, FaceContour> countours // 轮廓列表
FaceLandmark
对象包含两种信息:类型和点。
FaceLandmarkType type
Offset point
以下是FaceLandmarkType
列表:
LEFT_EYE
RIGHT_EYE
LEFT_EAR
RIGHT_EAR
LEFT_CHEEK
RIGHT_CHEEK
NOSE_BASE
MOUTH_LEFT
MOUTH_RIGHT
MOUTH_BOTTOM
每个FaceContour
实例包含两种信息:类型和点。
FaceContourType type
List<Offset> points
以下是FaceContourType
列表:
FACE
LEFT_EYE
RIGHT_EYE
LEFT_EYEBROW_TOP
LEFT_EYEBROW_BOTTOM
RIGHT_EYEBROW_TOP
RIGHT_EYEBROW_BOTTOM
NOSE_BRIDGE
NOSE_BOTTOM
LEFT_CHEEK
RIGHT_CHEEK
UPPER_LIP_TOP
UPPER_LIP_BOTTOM
LOWER_LIP_TOP
LOWER_LIP_BOTTOM
Face Painting
为了方便地从Face
对象绘制到屏幕,我们提供了FaceOverlay
,您可以将其传递给InputCameraView
的overlay
参数。
FaceOverlay(
size: size,
originalSize: originalSize,
rotation: rotation,
faces: faces,
contourColor: Colors.white.withOpacity(0.8),
landmarkColor: Colors.lightBlue.withOpacity(0.8),
)
Dispose
detector.dispose();
Example Project
完整示例项目如下:
import 'package:flutter/material.dart';
import 'package:learning_face_detection/learning_face_detection.dart';
import 'package:learning_input_image/learning_input_image.dart';
import 'package:provider/provider.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.lightBlue,
visualDensity: VisualDensity.adaptivePlatformDensity,
primaryTextTheme: TextTheme(headline6: TextStyle(color: Colors.white)),
),
home: ChangeNotifierProvider(
create: (_) => FaceDetectionState(),
child: FaceDetectionPage(),
),
);
}
}
class FaceDetectionPage extends StatefulWidget {
[@override](/user/override)
_FaceDetectionPageState createState() => _FaceDetectionPageState();
}
class _FaceDetectionPageState extends State<FaceDetectionPage> {
FaceDetectionState get state => Provider.of(context, listen: false);
FaceDetector _detector = FaceDetector(
mode: FaceDetectorMode.accurate, // 准确模式
detectLandmark: true, // 检测标志点
detectContour: true, // 检测轮廓
enableClassification: true, // 启用分类
enableTracking: true, // 启用跟踪
);
[@override](/user/override)
void dispose() {
_detector.dispose(); // 释放资源
super.dispose();
}
Future<void> _detectFaces(InputImage image) async {
if (state.isNotProcessing) {
state.startProcessing(); // 开始处理
state.image = image;
state.data = await _detector.detect(image); // 检测人脸
state.stopProcessing(); // 结束处理
}
}
[@override](/user/override)
Widget build(BuildContext context) {
return InputCameraView(
title: 'Face Detection', // 标题
onImage: _detectFaces, // 图像回调
resolutionPreset: ResolutionPreset.high, // 高分辨率预设
overlay: Consumer<FaceDetectionState>(
builder: (_, state, __) {
if (state.isEmpty) {
return Container();
}
Size originalSize = state.size!;
Size size = MediaQuery.of(context).size;
// 如果图像是从相册获取的
// 图像显示尺寸缩放到360x360并保留纵横比
if (state.notFromLive) {
if (originalSize.aspectRatio > 1) {
size = Size(360.0, 360.0 / originalSize.aspectRatio);
} else {
size = Size(360.0 * originalSize.aspectRatio, 360.0);
}
}
return FaceOverlay(
size: size,
originalSize: originalSize,
rotation: state.rotation,
faces: state.data,
contourColor: Colors.white.withOpacity(0.8), // 轮廓颜色
landmarkColor: Colors.lightBlue.withOpacity(0.8), // 标志点颜色
);
},
),
);
}
}
class FaceDetectionState extends ChangeNotifier {
InputImage? _image;
List<Face> _data = [];
bool _isProcessing = false;
InputImage? get image => _image;
List<Face> get data => _data;
String? get type => _image?.type;
InputImageRotation? get rotation => _image?.metadata?.rotation;
Size? get size => _image?.metadata?.size;
bool get isNotProcessing => !_isProcessing;
bool get isEmpty => data.isEmpty;
bool get isFromLive => type == 'bytes';
bool get notFromLive => !isFromLive;
void startProcessing() {
_isProcessing = true;
notifyListeners();
}
void stopProcessing() {
_isProcessing = false;
notifyListeners();
}
set image(InputImage? image) {
_image = image;
if (notFromLive) {
_data = [];
}
notifyListeners();
}
set data(List<Face> data) {
_data = data;
notifyListeners();
}
}
更多关于Flutter人脸检测插件learning_face_detection的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter人脸检测插件learning_face_detection的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用learning_face_detection
插件进行人脸检测的示例代码。这个插件允许你利用机器学习模型在图像中检测人脸。
首先,确保你的Flutter项目已经设置好,并且在pubspec.yaml
文件中添加了learning_face_detection
依赖:
dependencies:
flutter:
sdk: flutter
learning_face_detection: ^最新版本号 # 请替换为当前最新版本号
然后,运行flutter pub get
来安装依赖。
接下来,编写Flutter代码来使用这个插件。以下是一个简单的示例,展示了如何从图像中检测人脸:
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:learning_face_detection/learning_face_detection.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: FaceDetectionScreen(),
);
}
}
class FaceDetectionScreen extends StatefulWidget {
@override
_FaceDetectionScreenState createState() => _FaceDetectionScreenState();
}
class _FaceDetectionScreenState extends State<FaceDetectionScreen> {
File? _imageFile;
List<FaceDetectionResult>? _faceResults;
final ImagePicker _picker = ImagePicker();
Future<void> _pickImage(ImageSource source) async {
final XFile? image = await _picker.pickImage(source: source);
if (image != null) {
final File imageFile = File(image.path);
setState(() {
_imageFile = imageFile;
_detectFaces(imageFile);
});
}
}
Future<void> _detectFaces(File imageFile) async {
try {
final List<FaceDetectionResult> faceResults = await LearningFaceDetection.detectFaces(imageFile.path);
setState(() {
_faceResults = faceResults;
});
} catch (e) {
print('Error detecting faces: $e');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Face Detection'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
_imageFile != null
? Image.file(
_imageFile!,
width: 300,
height: 300,
fit: BoxFit.cover,
child: _faceResults != null
? CustomPaint(
size: Size(300, 300),
painter: FacePainter(_faceResults!),
)
: null,
)
: Text('No image selected.'),
SizedBox(height: 20),
ElevatedButton(
onPressed: () => _pickImage(ImageSource.gallery),
child: Text('Pick Image from Gallery'),
),
SizedBox(height: 10),
ElevatedButton(
onPressed: () => _pickImage(ImageSource.camera),
child: Text('Take Photo'),
),
],
),
),
);
}
}
class FacePainter extends CustomPainter {
final List<FaceDetectionResult> faceResults;
FacePainter(this.faceResults);
@override
void paint(Canvas canvas, Size size) {
final Paint paint = Paint()
..color = Colors.red
..style = PaintingStyle.stroke
..strokeWidth = 2.0;
for (var face in faceResults) {
final Rect faceRect = Rect.fromLTWH(
face.boundingBox.left,
face.boundingBox.top,
face.boundingBox.width,
face.boundingBox.height,
);
canvas.drawRect(faceRect, paint);
}
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return oldDelegate != this;
}
}
在这个示例中,我们使用了image_picker
插件来选择或拍摄照片。然后,我们使用learning_face_detection
插件来检测选定图像中的人脸,并在检测到的人脸周围绘制红色矩形框。
请确保在你的pubspec.yaml
文件中也添加image_picker
依赖:
dependencies:
image_picker: ^最新版本号 # 请替换为当前最新版本号
这个示例代码提供了一个基本的人脸检测功能,你可以根据需要进一步扩展和自定义。