Flutter 对象检测应用 + YOLOV5 模型。
Flutter 是一款流行的开源移动应用开发框架,它允许开发者创建高性能的跨平台应用,支持 Android 和 iOS 设备。凭借其易用性和灵活性,Flutter 已成为开发者构建移动应用的热门选择。
移动应用最常见的应用场景之一是目标检测,即应用能够识别和分类图像或视频中的物体。YOLOv5 是一种先进的目标检测算法,近年来因其高精度和高速度而广受欢迎。
在本文中,我们将探讨如何将 YOLOv5 与 Flutter 集成,以创建一个目标检测应用程序。
1. 环境搭建:
首先,你需要搭建开发环境。你的电脑上需要安装 Flutter 和 Python。之后,打开 VS Code 并创建一个新的 Flutter 项目。
flutter create object_detection
等待项目创建完成。
现在,打开https://pub.dev/packages/flutter_pytorch并导航至“安装”选项卡,您可以在那里找到最新的软件包版本,目前该软件包版本为 1.0.1。
运行以下命令:
使用 Flutter:$ flutter pub add flutter_pytorch
这会在你的包的 pubspec.yaml 文件中添加类似这样的行(并隐式运行 flutter pub get):
dependencies:
flutter_pytorch: ^1.0.1
或者,您的编辑器可能支持 flutter pub get。请查阅编辑器的文档了解更多信息。
导入
后,您可以在 Dart 代码中使用:
import 'package:flutter_pytorch/flutter_pytorch.dart';
2. 准备模型。
在 Flutter 应用中使用 YOLOv5 之前,您需要先在特定的数据集上训练模型。您可以使用现有数据集,也可以创建自己的数据集来训练模型。
本文使用的是https://github.com/ultralytics/yolov5上提供的 YOLOv5 预训练模型。由于我们需要进行目标检测,因此需要将预训练模型的权重转换为 TorchScript 格式。
分类
import torch
from torch.utils.mobile_optimizer import optimize_for_mobile
model = torch.load('model_scripted.pt',map_location="cpu")
model.eval()
example = torch.rand(1, 3, 224, 224)
traced_script_module = torch.jit.trace(model, example)
optimized_traced_model = optimize_for_mobile(traced_script_module)
optimized_traced_model._save_for_lite_interpreter("model.pt")
目标检测(YOLOv5)
!python export.py --weights "the weights of your model" --include torchscript --img 640 --optimize
例子
!python export.py --weights yolov5s.pt --include torchscript --img 640 --optimize
3. 为应用程序创建基本用户界面。
打开应用程序的 lib 文件夹,你会看到 main.dart 文件,这是 Dart 的主编译文件。
在连接的模拟器或手机上以调试模式运行该文件。
emulator -avd "Your emulator name"
现在通过 VS Code 的调试模式运行您的应用程序,因为它提供快速重新加载和热重启功能。
创建用户界面设计
为了设计应用程序,我们将遵循工作分解结构 (WBS) 来进行应用程序设计和机器学习模型集成。
请打开 main.dart 文件,并将所有代码替换为以下内容:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'OBJECT DETECTOR',
debugShowCheckedModeBanner: false,
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.blue,
),
);
}
}
以上代码只是一个基本的应用程序类结构,其中移除了所有不必要的代码。重新加载后,你会看到类似如下的黑屏:
在 lib 文件夹内创建一个名为 HomeScreen.dart 的新 Dart 文件。
现在,如果您输入 stf 并按回车键,它将自动创建相关的代码结构,这里我们使用的是有状态组件。
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
@override
Widget build(BuildContext context) {
return Container();
}
}
现在在 Scaffold 类中创建一个文本,如下所示:
return Scaffold(
backgroundColor: Colors.white,
body: Text("Home Screen"),
);
并将此主屏幕状态作为应用程序状态调用,如下所示:
home: HomeScreen(),
现在您可以看到应用程序已更改为:
现在在 HomeScreen.dart 中添加以下代码,以设计应用程序的基本用户界面。
import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/container.dart';
import 'package:flutter/src/widgets/framework.dart';
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("OBJECT DETECTOR APP")),
backgroundColor: Colors.white,
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
//Image with Detections....
//Button to click pic
ElevatedButton(
onPressed: () {},
child: const Icon(Icons.camera),
)
],
)),
);
}
}
4. 将模型与 Flutter 集成
模型训练完成后,即可将其集成到 Flutter 应用中。首先,创建一个名为 assets 的文件夹,并在其中创建 model 和 labels 子文件夹,同时在 pubspec.yaml 文件中声明这些子文件夹。如下图所示:
添加 assets 路径后的 pubspec.yaml 文件:

现在将转换后的模型放入 models 文件夹,并创建 labels.txt 文件,将标签放入其中。

或者您可以从以下链接下载模型和标签:
https://github.com/AneeqMalik/flutter_pytorch/tree/main/example/assets
请给这个仓库点个星标😊。
将标签和模型放入各自的文件夹后,就可以等待将模型集成到我们的应用中了。
整合YOLOv5模型
- 创建以下变量:
File? _imageFile;
late ModelObjectDetection _objectModel;
String? _imagePrediction;
List? _prediction;
File? _image;
ImagePicker _picker = ImagePicker();
bool objectDetection = false;
List<ResultObjectDetection?> objDetect = [];
- 创建一个函数,用于将模型加载到应用程序中:
Future loadModel() async {
String pathObjectDetectionModel = "assets/models/yolov5s.torchscript";
try {
_objectModel = await FlutterPytorch.loadObjectDetectionModel(
//Remeber here 80 value represents number of classes for custom model it will be different don't forget to change this.
pathObjectDetectionModel, 80, 640, 640,
labelPath: "assets/labels/labels.txt");
} catch (e) {
if (e is PlatformException) {
print("only supported for android, Error is $e");
} else {
print("Error is $e");
}
}
}
- 在 initState() 函数内部调用 load 函数,以便在应用启动时加载模型:
@override
void initState() {
// TODO: implement initState
super.initState();
loadModel();
}
- 在列中添加以下组件:
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
//Image with Detections....
Expanded(
child: Container(
height: 150,
width: 300,
child: objDetect.isNotEmpty
? _image == null
? Text('No image selected.')
: _objectModel!.renderBoxesOnImage(_image!, objDetect)
: _image == null
? Text('No image selected.')
: Image.file(_image!),
),
),
Center(
child: Visibility(
visible: _imagePrediction != null,
child: Text("$_imagePrediction"),
),
),
//Button to click pic
ElevatedButton(
onPressed: () {
runObjectDetection();
},
child: const Icon(Icons.camera),
)
],
)),
- 最后,创建一个目标检测函数,以获取检测到的图像的推断结果:
Future runObjectDetection() async {
//pick an image
final XFile? image = await _picker.pickImage(
source: ImageSource.gallery, maxWidth: 200, maxHeight: 200);
objDetect = await _objectModel.getImagePrediction(
await File(image!.path).readAsBytes(),
minimumScore: 0.1,
IOUThershold: 0.3);
objDetect.forEach((element) {
print({
"score": element?.score,
"className": element?.className,
"class": element?.classIndex,
"rect": {
"left": element?.rect.left,
"top": element?.rect.top,
"width": element?.rect.width,
"height": element?.rect.height,
"right": element?.rect.right,
"bottom": element?.rect.bottom,
},
});
});
setState(() {
_image = File(image!.path);
});
}
更改默认 SDK 版本
后,在进行上述更改后运行应用程序,应用程序将无法编译,并会出现类似于以下的问题:

您需要修改以下文件中的默认 SDK 版本:
ProjectName\object_detection\android\app\build.gradle:

保存更改并重新运行应用构建。
等待构建完成,期间可能会出现一些警告,但暂时忽略它们。
5. 测试应用程序
为了测试您的应用程序,您可以向应用程序提供图像或视频,并查看模型如何检测媒体中的对象。
屏幕截图
🥳🥳🥳🥳应用程序运行正常,并能进行检测。
源代码链接
https://github.com/AneeqMalik/Flutter-Object-Detector-App-YOLOv5-
其他资源/信息
https://pub.dev/packages/flutter_pytorch
文章来源:https://dev.to/aneeqmalik/flutter-object-detection-app-yolov5-model-3h4l









