Flutter目标检测插件ultralytics_yolo的使用
Flutter目标检测插件ultralytics_yolo的使用
简介
ultralytics_yolo
是一个Flutter插件,用于将Ultralytics YOLO计算机视觉模型集成到移动应用中。该插件支持Android和iOS平台,并提供对象检测和图像分类的API。
特性
功能 | Android | iOS |
---|---|---|
检测 | ✅ | ✅ |
分类 | ✅ | ✅ |
姿态估计 | ❌ | ❌ |
分割 | ❌ | ❌ |
OBB检测 | ❌ | ❌ |
在进一步操作或报告新问题之前,请确保您已彻底阅读本文档。
使用方法
先决条件
导出Ultralytics YOLO模型
在使用Ultralytics YOLO之前,必须导出所需的模型。导出的模型文件格式为.tflite
和.mlmodel
,然后将其包含在您的应用中。使用Ultralytics YOLO CLI导出模型。
Android
yolo export format=tflite model=yolov8n imgsz=320 int8
iOS
yolo export format=mlmodel model=yolov8n imgsz=[320, 192] half nms
安装
导出模型后,您会得到.tflite
和.mlmodel
文件。将这些文件包含在您的应用的assets
文件夹中。
权限
确保您有访问相机和存储的必要权限。
Android
在AndroidManifest.xml
中添加以下权限:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
iOS
在Info.plist
中添加以下权限:
<key>NSCameraUsageDescription</key>
<string>Camera permission is required for object detection.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Storage permission is required for object detection.</string>
在Podfile
中添加以下配置:
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
# Start of the permission_handler configuration
target.build_configurations.each do |config|
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
'$(inherited)',
## dart: PermissionGroup.camera
'PERMISSION_CAMERA=1',
## dart: PermissionGroup.photos
'PERMISSION_PHOTOS=1',
]
end
# End of the permission_handler configuration
end
end
使用示例
创建预测器对象
使用LocalYoloModel
类创建预测器对象。此类需要以下参数:
final model = LocalYoloModel(
id: id,
task: Task.detect /* 或 Task.classify */,
format: Format.tflite /* 或 Format.coreml*/,
modelPath: modelPath,
metadataPath: metadataPath,
);
对象检测器
final objectDetector = ObjectDetector(model: model);
await objectDetector.loadModel();
图像分类器
final imageClassifier = ImageClassifier(model: model);
await imageClassifier.loadModel();
相机预览
使用UltralyticsYoloCameraPreview
小部件显示相机预览和预测结果。
final _controller = UltralyticsYoloCameraController();
UltralyticsYoloCameraPreview(
predictor: predictor, // 您的预测模型数据
controller: _controller, // Ultralytics相机控制器
loadingPlaceholder: Center(
child: Wrap(
direction: Axis.vertical,
crossAxisAlignment: WrapCrossAlignment.center,
children: [
const CircularProgressIndicator(
color: Colors.white,
strokeWidth: 2,
),
const SizedBox(height: 20),
Text(
'Loading model...',
style: theme.typography.base.copyWith(
color: Colors.white,
fontSize: 14,
),
),
],
),
),
)
图像检测与分类
使用detect
或classify
方法获取图像预测结果。
objectDetector.detect(imagePath: imagePath);
// 或
imageClassifier.classify(imagePath: imagePath);
示例代码
以下是完整的示例代码,展示了如何在Flutter应用中使用ultralytics_yolo
插件进行对象检测。
import 'dart:io' as io;
import 'package:flutter/material.dart';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:flutter/services.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:ultralytics_yolo/ultralytics_yolo.dart';
import 'package:ultralytics_yolo/yolo_model.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final controller = UltralyticsYoloCameraController();
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: FutureBuilder<bool>(
future: _checkPermissions(),
builder: (context, snapshot) {
final allPermissionsGranted = snapshot.data ?? false;
return !allPermissionsGranted
? Container()
: FutureBuilder<ObjectDetector>(
future: _initObjectDetectorWithLocalModel(),
builder: (context, snapshot) {
final predictor = snapshot.data;
return predictor == null
? Container()
: Stack(
children: [
UltralyticsYoloCameraPreview(
controller: controller,
predictor: predictor,
onCameraCreated: () {
predictor.loadModel(useGpu: true);
},
),
StreamBuilder<double?>(
stream: predictor.inferenceTime,
builder: (context, snapshot) {
final inferenceTime = snapshot.data;
return StreamBuilder<double?>(
stream: predictor.fpsRate,
builder: (context, snapshot) {
final fpsRate = snapshot.data;
return Times(
inferenceTime: inferenceTime,
fpsRate: fpsRate,
);
},
);
},
),
],
);
},
);
},
),
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.abc),
onPressed: () {
controller.toggleLensDirection();
},
),
),
);
}
Future<ObjectDetector> _initObjectDetectorWithLocalModel() async {
final modelPath = await _copy('assets/yolov8n_int8.tflite');
final metadataPath = await _copy('assets/metadata.yaml');
final model = LocalYoloModel(
id: '',
task: Task.detect,
format: Format.tflite,
modelPath: modelPath,
metadataPath: metadataPath,
);
return ObjectDetector(model: model);
}
Future<ImageClassifier> _initImageClassifierWithLocalModel() async {
final modelPath = await _copy('assets/yolov8n-cls.mlmodel');
final model = LocalYoloModel(
id: '',
task: Task.classify,
format: Format.coreml,
modelPath: modelPath,
);
return ImageClassifier(model: model);
}
Future<String> _copy(String assetPath) async {
final path = '${(await getApplicationSupportDirectory()).path}/$assetPath';
await io.Directory(dirname(path)).create(recursive: true);
final file = io.File(path);
if (!await file.exists()) {
final byteData = await rootBundle.load(assetPath);
await file.writeAsBytes(byteData.buffer
.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes));
}
return file.path;
}
Future<bool> _checkPermissions() async {
List<Permission> permissions = [];
var cameraStatus = await Permission.camera.status;
if (!cameraStatus.isGranted) permissions.add(Permission.camera);
var storageStatus = await Permission.storage.status;
if (!storageStatus.isGranted) permissions.add(Permission.storage);
if (permissions.isEmpty) {
return true;
} else {
try {
Map<Permission, PermissionStatus> statuses =
await permissions.request();
return statuses[Permission.camera] == PermissionStatus.granted &&
statuses[Permission.storage] == PermissionStatus.granted;
} on Exception catch (_) {
return false;
}
}
}
}
class Times extends StatelessWidget {
const Times({
super.key,
required this.inferenceTime,
required this.fpsRate,
});
final double? inferenceTime;
final double? fpsRate;
@override
Widget build(BuildContext context) {
return SafeArea(
child: Align(
alignment: Alignment.bottomCenter,
child: Container(
margin: const EdgeInsets.all(20),
padding: const EdgeInsets.all(20),
decoration: const BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(10)),
color: Colors.black54,
),
child: Text(
'${(inferenceTime ?? 0).toStringAsFixed(1)} ms - ${(fpsRate ?? 0).toStringAsFixed(1)} FPS',
style: const TextStyle(color: Colors.white70),
)),
),
);
}
}
通过上述步骤,您可以成功地在Flutter应用中集成Ultralytics YOLO模型进行对象检测和图像分类。希望这个指南对您有所帮助!
更多关于Flutter目标检测插件ultralytics_yolo的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter目标检测插件ultralytics_yolo的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter项目中使用ultralytics_yolo
插件进行目标检测的示例代码。这个插件允许你使用YOLO(You Only Look Once)模型进行实时目标检测。
1. 添加依赖
首先,在你的pubspec.yaml
文件中添加ultralytics_yolo
依赖:
dependencies:
flutter:
sdk: flutter
ultralytics_yolo: ^最新版本号 # 请替换为实际发布的最新版本号
然后运行flutter pub get
来获取依赖。
2. 配置Android和iOS权限
由于目标检测需要访问设备的摄像头,你需要在AndroidManifest.xml
和Info.plist
中添加相应的权限。
Android
在android/app/src/main/AndroidManifest.xml
中添加:
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
iOS
在ios/Runner/Info.plist
中添加:
<key>NSCameraUsageDescription</key>
<string>需要访问相机以进行目标检测</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>需要访问照片库以保存检测结果</string>
3. 使用ultralytics_yolo
插件
以下是一个简单的Flutter应用示例,展示如何使用ultralytics_yolo
插件进行目标检测:
import 'package:flutter/material.dart';
import 'package:ultralytics_yolo/ultralytics_yolo.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter YOLO 目标检测',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: CameraScreen(),
);
}
}
class CameraScreen extends StatefulWidget {
@override
_CameraScreenState createState() => _CameraScreenState();
}
class _CameraScreenState extends State<CameraScreen> {
late UltralyticsYolo _yolo;
late CameraController _cameraController;
@override
void initState() {
super.initState();
// 初始化YOLO模型
_yolo = UltralyticsYolo(
weights: 'yolov5s.pt', // 你可以指定其他权重文件
source: '0', // 使用设备的后置摄像头
conf: 0.25, // 置信度阈值
);
// 初始化相机控制器
_cameraController = CameraController(
_yolo.camera!,
ResolutionPreset.high,
enableAudio: false,
);
_cameraController.initialize().then((_) {
if (!mounted) return;
setState(() {});
});
}
@override
void dispose() {
_cameraController.dispose();
_yolo.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
if (!_cameraController.value.isInitialized) {
return Container();
}
return Scaffold(
appBar: AppBar(
title: Text('Flutter YOLO 目标检测'),
),
body: Stack(
children: [
CameraPreview(_cameraController),
_buildOverlay(),
],
),
floatingActionButton: FloatingActionButton(
onPressed: () async {
// 捕获图像并进行目标检测
final image = await _cameraController.capture();
final detections = await _yolo.detect(image: image.path);
print(detections); // 打印检测结果
},
tooltip: '检测',
child: Icon(Icons.photo_camera),
),
);
}
Widget _buildOverlay() {
if (!_cameraController.value.isRecordingImage) {
return Container();
}
// 这里你可以添加代码来绘制检测结果,例如使用CustomPaint
return Container();
}
}
注意事项
- 模型权重:你需要下载YOLOv5的权重文件(如
yolov5s.pt
),并将其放置在合适的位置,或者直接使用在线权重(如果插件支持)。 - 性能:目标检测是一个计算密集型的任务,确保在适当的设备上运行,以获得流畅的体验。
- 权限处理:在实际应用中,你需要处理用户权限的请求和拒绝情况。
这个示例代码展示了如何在Flutter应用中使用ultralytics_yolo
插件进行基本的目标检测。根据具体需求,你可能需要进一步优化和扩展代码。