Flutter图像标注插件image_annotation的使用

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

Flutter图像标注插件image_annotation的使用

该库为Flutter应用程序提供了添加图像标注功能的简单解决方案。通过此库,用户可以在定义的图片区域中绘制形状、添加文本、高亮特定区域并调整注释大小。

演示

演示

功能

  • 在图像上绘制线条、矩形和椭圆。
  • 在图像上添加自定义文本注释。
  • 高亮图像的特定区域。
  • 调整图像区域内的注释大小。
  • 清除所有或最后一个注释。

安装

要在您的Flutter项目中添加此库,请在pubspec.yaml文件中包含它:

dependencies:
  image_annotation: ^latest_version

然后在终端中运行以下命令:

flutter pub get

使用

导入包:

import 'package:image_annotation/image_annotation.dart';

然后,您可以在应用中使用ImageAnnotation小部件。您可以指定注释类型(‘line’、‘rectangle’、‘oval’、‘text’)和图像路径。

ImageAnnotation(
  imagePath: "assets/images/example.png",
  annotationType: "rectangle",
)

快速示例

import 'package:flutter/material.dart';
import 'package:image_annotation/image_annotation.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: ImageAnnotation(
          imagePath: 'images/my_image.png',
          annotationType: 'line',
        ),
      ),
    );
  }
}

更详细的示例

以下是更详细的示例,展示了如何在应用中实现不同的注释选项。

import 'package:flutter/material.dart';
import 'package:image_annotation/image_annotation.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  [@override](/user/override)
  _MyAppState createState() => _MyAppState();
}

enum AnnotationOption { line, rectangle, oval, text }

class _MyAppState extends State<MyApp> {
  // 定义一个scaffold key以防止意外更改。
  final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();

  AnnotationOption selectedOption = AnnotationOption.line; // 默认选项。

  // 根据选择的选项返回注释类型字符串的帮助函数。
  String chooseAnnotationType(AnnotationOption option) {
    switch (option) {
      case AnnotationOption.line:
        return 'line';
      case AnnotationOption.rectangle:
        return 'rectangle';
      case AnnotationOption.oval:
        return 'oval';
      case AnnotationOption.text:
        return 'text';
    }
  }

  // 处理抽屉选项点击事件并更新所选选项的函数。
  void _handleDrawerOptionTap(AnnotationOption option) {
    setState(() {
      selectedOption = option;
    });
    _scaffoldKey.currentState?.openEndDrawer();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Image Annotation Demo',
      home: Scaffold(
        key: _scaffoldKey,
        appBar: AppBar(
          title: const Text('Image Annotation Demo'),
          centerTitle: true,
        ),
        endDrawer: Drawer(
          child: ListView(
            children: <Widget>[
              const DrawerHeader(
                margin: EdgeInsets.zero,
                padding: EdgeInsets.zero,
                child: UserAccountsDrawerHeader(
                  decoration: BoxDecoration(color: Colors.green),
                  accountName: Text('Image Annotation Types'),
                  accountEmail: Text('choose one option'),
                ),
              ),
              ListTile(
                title: Text('Line'),
                onTap: () => _handleDrawerOptionTap(AnnotationOption.line),
                selected: selectedOption == AnnotationOption.line,
              ),
              ListTile(
                title: Text('Rectangular'),
                onTap: () => _handleDrawerOptionTap(AnnotationOption.rectangle),
                selected: selectedOption == AnnotationOption.rectangle,
              ),
              ListTile(
                title: Text('Oval'),
                onTap: () => _handleDrawerOptionTap(AnnotationOption.oval),
                selected: selectedOption == AnnotationOption.oval,
              ),
              ListTile(
                title: Text('Text'),
                onTap: () => _handleDrawerOptionTap(AnnotationOption.text),
                selected: selectedOption == AnnotationOption.text,
              ),
            ],
          ),
        ),
        body: Center(
          child: ImageAnnotation(
            imagePath: 'assets/images/your_image.jpg',
            annotationType: chooseAnnotationType(selectedOption),
          ),
        ),
      ),
    );
  }
}

更多关于Flutter图像标注插件image_annotation的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter图像标注插件image_annotation的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter中使用image_annotation插件来进行图像标注的示例代码。请注意,image_annotation插件通常与机器学习库(如TensorFlow Lite)结合使用,以便在移动设备上执行图像识别任务。然而,image_annotation插件本身主要用于处理图像数据,并不直接提供标注功能。因此,以下示例将展示如何加载图像并使用TensorFlow Lite模型进行标注(假设你已经有一个训练好的模型)。

首先,确保你的pubspec.yaml文件中已经添加了必要的依赖项:

dependencies:
  flutter:
    sdk: flutter
  image_picker: ^0.8.4+4 # 用于从设备选择图像
  tflite_flutter: ^0.9.0+2 # TensorFlow Lite Flutter 插件
  image: ^3.0.2 # 用于处理图像数据

然后,你可以按照以下步骤编写Flutter代码:

  1. 导入必要的库
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:tflite_flutter/tflite_flutter.dart';
import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:image/image.dart' as img;
  1. 定义全局变量
late Interpreter interpreter;
late Uint8List imageBuffer;
late List<int> output;
final ImagePicker picker = ImagePicker();
  1. 加载模型

在你的initState方法中加载TensorFlow Lite模型:

@override
void initState() {
  super.initState();
  loadModel();
}

Future<void> loadModel() async {
  // 确保你有正确的模型路径
  String modelPath = "assets/model.tflite";
  interpreter = await Interpreter.fromAsset(modelPath);
}
  1. 选择并处理图像

定义一个函数来选择图像,并将其转换为TensorFlow Lite可以接受的格式:

Future<void> pickImage() async {
  final pickedFile = await picker.pickImage(source: ImageSource.camera);

  if (pickedFile != null) {
    final imageFile = File(pickedFile.path);
    final Uint8List imageBytes = await imageFile.readAsBytes();
    final img.Image imgImage = img.decodeImage(imageBytes)!;

    // 将图像调整为模型输入所需的尺寸(例如224x224)
    final resizedImage = img.copyResize(imgImage, 224, 224);
    final ByteData byteData = ByteData(224 * 224 * 3);

    for (int y = 0; y < 224; y++) {
      for (int x = 0; x < 224; x++) {
        img.Color pixel = resizedImage.getPixel(x, y);
        byteData.setUint8(y * 224 * 3 + x * 3, pixel.r);
        byteData.setUint8(y * 224 * 3 + x * 3 + 1, pixel.g);
        byteData.setUint8(y * 224 * 3 + x * 3 + 2, pixel.b);
      }
    }

    imageBuffer = byteData.buffer.asUint8List();
    runModel();
  }
}
  1. 运行模型并获取标注结果
Future<void> runModel() async {
  // 创建输入张量
  final inputTensor = TensorBuffer.createFixedSize(Uint8List, [1, 224, 224, 3]);
  inputTensor.loadFromBuffer(imageBuffer);

  // 运行模型
  List<TensorBuffer> outputBuffers = await interpreter.run(inputTensor.buffer, outputShapes: [intListToList(interpreter.getOutputTensor(0).shape)]);

  // 获取输出
  TensorBuffer outputBuffer = outputBuffers[0];
  Float32List outputData = outputBuffer.getFloat32List();
  output = outputData.map((e) => e.toInt()).toList();

  // 根据输出数据解析标注结果(具体逻辑取决于你的模型)
  // 例如,找到最大值的索引作为预测结果
  int bestLabel = output.indexOf(output.reduce((a, b) => Math.max(a, b)));
  print("Predicted Label: $bestLabel");

  // 更新UI(如果需要)
  // setState(() { /* 更新状态 */ });
}

List<int> intListToList(List<Int32> int32List) {
  List<int> result = [];
  for (int value in int32List) {
    result.add(value);
  }
  return result;
}
  1. 在UI中添加按钮以触发图像选择和标注
@override
Widget build(BuildContext context) {
  return MaterialApp(
    home: Scaffold(
      appBar: AppBar(
        title: Text('Image Annotation'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: pickImage,
          child: Text('Pick Image'),
        ),
      ),
    ),
  );
}

请注意,上述代码示例中的模型路径、输入尺寸、输出解析等细节可能需要根据你实际的TensorFlow Lite模型和标注需求进行调整。此外,image_annotation插件通常用于更高层次的图像处理和标注任务,但直接用于Flutter应用程序中的标注功能可能较少见,更多的是与机器学习库结合使用来处理图像数据。如果你需要更高级的图像标注功能,可能需要考虑使用更专业的图像标注工具或库,并在Flutter应用中通过API调用这些工具。

回到顶部