Flutter物体检测插件learning_object_detection的使用
Flutter物体检测插件 learning_object_detection
的使用
概述
learning_object_detection
是一个用于在Flutter应用中进行物体检测和跟踪的插件。它基于ML Kit,可以轻松实现从图像或实时摄像头流中检测和跟踪物体,并可选择对检测到的物体进行分类。
开始使用
添加依赖
首先,在你的Flutter项目的pubspec.yaml
文件中添加以下依赖:
dependencies:
learning_object_detection: ^0.0.1
然后运行以下命令来获取依赖:
flutter pub get
导入包
在你的Dart文件中导入必要的包:
import 'package:learning_object_detection/learning_object_detection.dart';
import 'package:learning_input_image/learning_input_image.dart';
使用方法
输入图像
输入图像需要转换为InputImage
格式,这可以通过learning_input_image
包中的InputCameraView
小部件来实现。该小部件可以从相机或存储中处理图像并将其转换为InputImage
格式。
以下是一个使用InputCameraView
获取InputImage
的例子:
InputCameraView(
title: 'Object Detection & Tracking',
onImage: (InputImage image) {
// 现在我们可以将输入图像送入对象检测器
},
)
物体检测
一旦有了InputImage
,我们就可以通过调用ObjectDetector
实例的detect
方法开始检测物体。
ObjectDetector detector = ObjectDetector();
List<DetectedObject> result = await detector.detect(image);
你可以根据需要自定义ObjectDetector
的参数:
ObjectDetector detector = ObjectDetector(
isStream: false, // 是否处理图像流
enableClassification: true, // 是否启用分类
enableMultipleObjects: true, // 是否检测多个物体
);
参数 | 可选值 | 默认值 |
---|---|---|
isStream | false / true | false |
enableClassification | false / true | true |
enableMultipleObjects | false / true | true |
输出结果
检测结果是一个DetectedObject
列表,每个对象包含以下信息:
int? trackingId // 跟踪ID(当isStream为false时为null)
Rect boundingBox // 包围检测到的物体的矩形框
List<DetectedLabel> labels // 可能的标签列表
每个DetectedLabel
包含以下数据:
int index // 标签索引
String label // 物体的标签
double confidence // 表示标签正确的概率
绘制检测结果
为了方便地将DetectedObject
绘制到屏幕上,插件提供了ObjectOverlay
类,你可以将其传递给InputCameraView
的小部件overlay
参数。
ObjectOverlay(
size: size,
originalSize: originalSize,
rotation: rotation,
objects: objects,
)
清理资源
确保在不需要时释放资源:
detector.dispose();
示例项目
完整的示例代码可以在这里找到。
示例代码
下面是一个完整的示例项目代码:
import 'package:flutter/material.dart';
import 'package:learning_input_image/learning_input_image.dart';
import 'package:learning_object_detection/learning_object_detection.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: (_) => ObjectDetectionState(),
child: ObjectDetectionPage(),
),
);
}
}
class ObjectDetectionPage extends StatefulWidget {
[@override](/user/override)
_ObjectDetectionPageState createState() => _ObjectDetectionPageState();
}
class _ObjectDetectionPageState extends State<ObjectDetectionPage> {
ObjectDetectionState get state => Provider.of(context, listen: false);
ObjectDetector _detector = ObjectDetector(
isStream: false,
enableClassification: true,
enableMultipleObjects: true,
);
[@override](/user/override)
void dispose() {
_detector.dispose();
super.dispose();
}
Future<void> _detectObjects(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(
cameraDefault: InputCameraType.rear,
title: 'Object Detection & Tracking',
onImage: _detectObjects,
overlay: Consumer<ObjectDetectionState>(
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 ObjectOverlay(
size: size,
originalSize: originalSize,
rotation: state.rotation,
objects: state.data,
);
},
),
);
}
}
class ObjectDetectionState extends ChangeNotifier {
InputImage? _image;
List<DetectedObject> _data = [];
bool _isProcessing = false;
InputImage? get image => _image;
List<DetectedObject> 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<DetectedObject> data) {
_data = data;
notifyListeners();
}
}
更多关于Flutter物体检测插件learning_object_detection的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter物体检测插件learning_object_detection的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter项目中使用learning_object_detection
插件进行物体检测的示例代码。这个插件允许你使用TensorFlow Lite模型在移动设备上执行实时物体检测。
前提条件
- 确保你已经安装了Flutter SDK。
- 确保你的Android或iOS设备已经连接并可以被Flutter识别。
- 在你的
pubspec.yaml
文件中添加learning_object_detection
依赖。
dependencies:
flutter:
sdk: flutter
learning_object_detection: ^0.6.0 # 请检查最新版本号
步骤
- 创建Flutter项目(如果还没有项目的话):
flutter create object_detection_app
cd object_detection_app
-
添加依赖并获取TensorFlow Lite模型:
确保在
pubspec.yaml
中添加了learning_object_detection
依赖,然后运行flutter pub get
。你需要一个TensorFlow Lite模型文件(通常是
.tflite
格式)和一个与之对应的标签文件(通常是.txt
格式)。这些文件可以从TensorFlow Model Zoo或你自己训练的模型中获取。 -
配置Android和iOS项目:
将你的
.tflite
模型和.txt
标签文件添加到项目的assets
文件夹中,并在pubspec.yaml
中声明它们:
flutter:
assets:
- assets/model.tflite
- assets/labels.txt
-
编写Flutter代码:
下面是一个简单的示例,展示如何使用
learning_object_detection
插件进行物体检测:
import 'package:flutter/material.dart';
import 'package:learning_object_detection/learning_object_detection.dart';
import 'dart:typed_data';
import 'dart:ui' as ui;
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Object Detection App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: ObjectDetectionScreen(),
);
}
}
class ObjectDetectionScreen extends StatefulWidget {
@override
_ObjectDetectionScreenState createState() => _ObjectDetectionScreenState();
}
class _ObjectDetectionScreenState extends State<ObjectDetectionScreen> {
late ObjectDetector _objectDetector;
late CameraController _cameraController;
@override
void initState() {
super.initState();
_initCamera();
_initObjectDetector();
}
Future<void> _initCamera() async {
// 初始化相机控制器(这里省略具体实现,可以使用camera插件)
// _cameraController = ...
}
Future<void> _initObjectDetector() async {
_objectDetector = await ObjectDetector.loadModel(
model: 'assets/model.tflite',
labels: 'assets/labels.txt',
numThreads: 1,
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Object Detection'),
),
body: Center(
child: _cameraController.value.isInitialized
? AspectRatio(
aspectRatio: _cameraController.value.aspectRatio,
child: CameraPreview(_cameraController),
)
: Container(),
),
floatingActionButton: FloatingActionButton(
onPressed: () async {
if (_cameraController.value.isRecordingImage) return;
final Uint8List imageBytes = await _cameraController.capture();
final ui.Image image = await loadImage(imageBytes);
final List<Detection> detections = await _objectDetector.detectObjectsOnImage(image);
// 处理检测结果(这里可以绘制检测框等)
},
tooltip: 'Capture Image and Detect Objects',
child: Icon(Icons.camera_alt),
),
);
}
Future<ui.Image> loadImage(Uint8List imageBytes) async {
final Completer<ui.Image> completer = Completer<ui.Image>();
ui.decodeImageFromList(imageBytes, (ui.Image img) {
completer.complete(img);
});
return completer.future;
}
@override
void dispose() {
_cameraController?.dispose();
_objectDetector?.close();
super.dispose();
}
}
注意:
- 上面的代码示例中省略了相机初始化的具体实现,你可以使用
camera
插件来管理相机预览和捕获图像。 loadImage
函数用于将图像字节数据解码为ui.Image
对象,这是learning_object_detection
插件所需要的格式。- 检测结果
detections
是一个Detection
对象的列表,每个对象包含检测到的物体的边界框、标签和置信度等信息。
运行项目
确保所有依赖都已正确安装,并且你的设备和开发环境已经配置好,然后运行:
flutter run
这将启动你的Flutter应用,并允许你捕获图像并检测其中的物体。