Flutter图像标注插件learning_image_labeling的使用
Flutter图像标注插件learning_image_labeling的使用
通过Flutter使用ML Kit进行图像标注是一种简单的方法。
使用ML Kit的图像标注功能,我们可以检测并提取图像中广泛类别中的实体信息。默认的图像标注模型可以识别一般对象、地点、活动、动物种类、产品等。
请注意,这适用于描述整张图像的图像分类模型。如果要对图像中的一个或多个对象(如鞋子或家具)进行分类,插件learning_object_detection
可能更适合。
开始使用
在您的Flutter项目中添加依赖:
$ flutter pub add learning_image_labeling
或者在pubspec.yaml
文件中添加:
dependencies:
learning_image_labeling: ^0.0.1
然后运行:
$ flutter pub get
使用方法
首先导入库:
import 'package:learning_image_labeling/learning_image_labeling.dart';
输入图像
与其他ML视觉插件一样,输入图像以InputImage
实例的形式提供,该实例属于包learning_input_image
。
您可以使用来自learning_input_image
的InputCameraView
小部件作为处理来自相机/存储的图像(或图像流)到InputImage
格式的默认实现。但是,如果您想创建自己的自定义实现,也可以学习InputCameraView
的内部代码。
以下是如何使用InputCameraView
获取用于图像标注的InputImage
的示例:
import 'package:learning_input_image/learning_input_image.dart';
InputCameraView(
title: 'Image Labeling',
onImage: (InputImage image) {
// 现在我们可以将输入图像送入图像标注过程中
},
)
图像标注
在获取InputImage
后,我们可以通过调用ImageLabeling
实例的process
方法来开始图像标注。
ImageLabeling imageLabeling = ImageLabeling();
List<Label> labels = await imageLabeling.process(image);
ImageLabeling
对象使用默认参数confidenceThreshold
初始化如下:
ImageLabeling imageLabeling = ImageLabeling(confidenceThreshold: 0.8)
但是,您可以根据需要设置自己的confidenceThreshold
值。
输出
图像标注过程的结果是一个包含以下数据的Label
对象列表:
int index // 该标签的索引
String label // 图像的标签
double confidence // 表示标签正确的概率的值
销毁
销毁ImageLabeling
对象:
imageLabeling.dispose();
示例项目
您可以在这里查看完整的示例项目。
import 'package:flutter/material.dart';
import 'package:learning_image_labeling/learning_image_labeling.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: (_) => ImageLabelingState(),
child: ImageLabelingPage(),
),
);
}
}
class ImageLabelingPage extends StatefulWidget {
[@override](/user/override)
_ImageLabelingPageState createState() => _ImageLabelingPageState();
}
class _ImageLabelingPageState extends State<ImageLabelingPage> {
ImageLabelingState get state => Provider.of(context, listen: false);
ImageLabeling _imageLabeling = ImageLabeling();
[@override](/user/override)
void dispose() {
_imageLabeling.dispose();
super.dispose();
}
Future<void> _processLabeling(InputImage image) async {
if (state.isNotProcessing) {
state.startProcessing();
state.image = image;
state.labels = await _imageLabeling.process(image);
state.stopProcessing();
}
}
[@override](/user/override)
Widget build(BuildContext context) {
return InputCameraView(
cameraDefault: InputCameraType.rear,
title: 'Image Labeling',
onImage: _processLabeling,
overlay: Consumer<ImageLabelingState>(
builder: (_, state, __) {
if (state.isEmpty) {
return Container();
}
if (state.isProcessing && state.notFromLive) {
return Center(
child: Container(
width: 32,
height: 32,
child: CircularProgressIndicator(strokeWidth: 2),
),
);
}
return Center(
child: Container(
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 16),
child: Text(state.toString(),
style: TextStyle(fontWeight: FontWeight.w500)),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.8),
borderRadius: BorderRadius.all(Radius.circular(4.0)),
),
),
);
},
),
);
}
}
class ImageLabelingState extends ChangeNotifier {
InputImage? _image;
List<Label> _labels = [];
bool _isProcessing = false;
InputImage? get image => _image;
List<Label> get labels => _labels;
String? get type => _image?.type;
InputImageRotation? get rotation => _image?.metadata?.rotation;
Size? get size => _image?.metadata?.size;
bool get isProcessing => _isProcessing;
bool get isNotProcessing => !_isProcessing;
bool get isEmpty => _labels.isEmpty;
bool get notFromLive => type != 'bytes';
void startProcessing() {
_isProcessing = true;
notifyListeners();
}
void stopProcessing() {
_isProcessing = false;
notifyListeners();
}
set isProcessing(bool isProcessing) {
_isProcessing = isProcessing;
notifyListeners();
}
set image(InputImage? image) {
_image = image;
notifyListeners();
}
set labels(List<Label> labels) {
_labels = labels;
notifyListeners();
}
[@override](/user/override)
String toString() {
List<String> result = labels.map((label) => label.label).toList();
return result.join(', ');
}
}
更多关于Flutter图像标注插件learning_image_labeling的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter图像标注插件learning_image_labeling的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何使用 learning_image_labeling
插件在 Flutter 中进行图像标注的示例代码。learning_image_labeling
插件允许用户在图像上进行标注,这在机器学习数据标注任务中非常有用。
首先,确保在你的 pubspec.yaml
文件中添加 learning_image_labeling
依赖项:
dependencies:
flutter:
sdk: flutter
learning_image_labeling: ^latest_version # 请替换为实际最新版本号
然后运行 flutter pub get
来安装依赖。
接下来是一个完整的 Flutter 应用示例,展示了如何使用 learning_image_labeling
插件:
import 'package:flutter/material.dart';
import 'package:learning_image_labeling/learning_image_labeling.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Image Labeling Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: ImageLabelingScreen(),
);
}
}
class ImageLabelingScreen extends StatefulWidget {
@override
_ImageLabelingScreenState createState() => _ImageLabelingScreenState();
}
class _ImageLabelingScreenState extends State<ImageLabelingScreen> {
final List<Label> initialLabels = [];
final String imagePath = "assets/sample_image.jpg"; // 替换为你的图像路径
late LearningImageLabelingController controller;
@override
void initState() {
super.initState();
controller = LearningImageLabelingController(
imagePath: imagePath,
initialLabels: initialLabels,
);
controller.addListener(() {
setState(() {});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Image Labeling Demo'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
Expanded(
child: LearningImageLabeling(
controller: controller,
onSave: _handleSave,
onDelete: _handleDelete,
),
),
ElevatedButton(
onPressed: () => controller.clearLabels(),
child: Text('Clear Labels'),
),
ElevatedButton(
onPressed: () => Navigator.pop(context),
child: Text('Back'),
),
],
),
),
);
}
void _handleSave() {
final List<Label> labels = controller.labels;
// 在这里处理保存的标签,比如保存到数据库或文件
print('Saved labels: $labels');
}
void _handleDelete() {
// 可以在这里添加删除标签后的处理逻辑
print('Deleted all labels');
}
}
// Label 类是一个简单的示例,你可以根据需求进行扩展
class Label {
final String id;
final Offset position;
final String text;
Label({required this.id, required this.position, required this.text});
@override
String toString() {
return 'Label{id: $id, position: $position, text: $text}';
}
}
说明:
- 依赖项:确保
learning_image_labeling
插件已添加到你的pubspec.yaml
文件中。 - 图像路径:将
imagePath
替换为你的实际图像路径。如果图像在assets
文件夹中,请确保在pubspec.yaml
中声明它。 - 控制器:使用
LearningImageLabelingController
来管理图像标注的状态。 - UI:在
LearningImageLabeling
小部件中显示图像,并允许用户进行标注。 - 保存和删除:通过
_handleSave
和_handleDelete
方法处理用户标注的保存和删除操作。
请注意,这只是一个基本的示例,你可能需要根据实际需求进一步自定义和扩展代码。