Flutter图像标注插件learning_image_labeling的使用

发布于 1周前 作者 yibo5220 来自 Flutter

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_imageInputCameraView小部件作为处理来自相机/存储的图像(或图像流)到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

1 回复

更多关于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}';
  }
}

说明:

  1. 依赖项:确保 learning_image_labeling 插件已添加到你的 pubspec.yaml 文件中。
  2. 图像路径:将 imagePath 替换为你的实际图像路径。如果图像在 assets 文件夹中,请确保在 pubspec.yaml 中声明它。
  3. 控制器:使用 LearningImageLabelingController 来管理图像标注的状态。
  4. UI:在 LearningImageLabeling 小部件中显示图像,并允许用户进行标注。
  5. 保存和删除:通过 _handleSave_handleDelete 方法处理用户标注的保存和删除操作。

请注意,这只是一个基本的示例,你可能需要根据实际需求进一步自定义和扩展代码。

回到顶部