Flutter图像分割渲染插件segmentation_renderer的使用

Flutter图像分割渲染插件segmentation_renderer的使用

segmentation_renderer 包提供了一组用于可视化分割数据的 Flutter 小部件和自定义画笔。它特别适用于处理图像处理的应用程序,其中分割数据用于描绘不同区域或轮廓。该包允许根据分割数据直接在图像上绘制轮廓,或者将它们作为几何形状单独渲染。

特性

  • 自定义轮廓画笔:基于分割数据,在任何图像上绘制详细的轮廓。
  • 形状渲染器:可选地,在轮廓周围绘制矩形、圆形或其他椭圆形状。
  • 灵活的渲染选项:根据可视化需求选择仅渲染轮廓、边界形状或两者都渲染。
  • 平滑路径渲染:通过可选的路径平滑增强轮廓的视觉质量。

包中的小部件

  • ImageWithContours:一个将图像与基于提供的分割数据的轮廓或边界形状叠加的小部件。注意:此小部件还会根据图像渲染大小自动缩放点。
  • ContoursPainter:一个自定义画笔,直接在画布上绘制轮廓,可以平滑绘制或以锐利线条绘制。
  • ShapeAroundContoursPainter:一个自定义画笔,围绕轮廓绘制指定的形状。

图片

以下是一些 segmentation_renderer 可以实现的效果示例:

轮廓示例 图像上的轮廓示例

边界框示例 围绕轮廓绘制的边界框示例

使用方法

安装

在您的 Flutter 项目中添加 segmentation_renderer 包,将其包含在 pubspec.yaml 文件中:

dependencies:
  segmentation_renderer: ^1.0.0

基本示例

以下是如何在您的 Flutter 应用程序中使用 ImageWithContours 小部件:

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

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

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: ImageWithContours(
            image: Image.asset('path/to/your/image.png'), // 替换为实际的图像路径
            contours: [
              Contour(points: [Point(x: 10, y: 10), Point(x: 50, y: 50)]),
              // 更多轮廓
            ],
            renderType: RenderType.both, // 渲染类型,可选值有 RenderType.contour, RenderType.boundingBox, RenderType.both
          ),
        ),
      ),
    );
  }
}

自定义

您可以自定义轮廓和边界形状的外观:

ImageWithContours(
  image: Image.asset('path/to/image.png'), // 替换为实际的图像路径
  contours: yourContoursData, // 您的轮廓数据
  renderType: RenderType.both, // 渲染类型
  // 其他配置
)

轮廓数据

准备您的轮廓数据,这些数据可以动态加载或静态定义:

List<Contour> yourContoursData = [
  Contour(points: [Point(x: 10, y: 10), Point(x: 20, y: 20), ...]),
  // 更多轮廓
];

示例代码

以下是 segmentation_renderer 的完整示例代码:

import 'package:flutter/material.dart';
import 'package:segmentation_renderer/lib.dart';

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

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Segmentation Renderer Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Segmentation Renderer Demo'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: const Center(
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ImageWithContoursWithLoading(
              imagePath: "assets/test_image.jpeg",
              contoursPath: "assets/test_image_contours.txt",
            ),
            SizedBox(width: 20),
            ImageWithContoursWithLoading(
              imagePath: "assets/test_image2.jpeg",
              contoursPath: "assets/test_image2_contours.txt",
            ),
          ],
        ),
      ),
    );
  }
}

class ImageWithContoursWithLoading extends StatefulWidget {
  final String imagePath;
  final String contoursPath;
  const ImageWithContoursWithLoading({
    super.key,
    required this.imagePath,
    required this.contoursPath,
  });

  [@override](/user/override)
  State<ImageWithContoursWithLoading> createState() => _ImageWithContoursWithLoadingState();
}

class _ImageWithContoursWithLoadingState extends State<ImageWithContoursWithLoading> {
  List<Contour> contours = [];
  ValueNotifier<bool> isLoading = ValueNotifier(false);

  [@override](/user/override)
  void initState() {
    Future.microtask(() async {
      isLoading.value = true;
      try {
        contours = await ContoursReader.readContoursFromAssetFile(widget.contoursPath);
      } catch (e) {
        print(e);
      }
      isLoading.value = false;
    });
    super.initState();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return ValueListenableBuilder<bool>(
      valueListenable: isLoading,
      builder: (context, value, child) {
        if (value) {
          return const CircularProgressIndicator();
        } else {
          return ImageWithContours(
            image: Image.asset(widget.imagePath),
            contours: contours,
            renderType: RenderType.boundingBox,
          );
        }
      },
    );
  }
}

更多关于Flutter图像分割渲染插件segmentation_renderer的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

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


当然,以下是如何在Flutter项目中使用segmentation_renderer插件来进行图像分割渲染的一个示例。segmentation_renderer插件通常用于显示图像分割结果,比如用于图像中的物体检测或区域划分。

首先,确保你的Flutter项目中已经添加了segmentation_renderer依赖。你可以通过修改pubspec.yaml文件来添加依赖:

dependencies:
  flutter:
    sdk: flutter
  segmentation_renderer: ^最新版本号

然后运行flutter pub get来安装依赖。

接下来是一个简单的示例代码,展示如何使用segmentation_renderer插件来加载图像并显示其分割结果。

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Segmentation Renderer Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: SegmentationDemo(),
    );
  }
}

class SegmentationDemo extends StatefulWidget {
  @override
  _SegmentationDemoState createState() => _SegmentationDemoState();
}

class _SegmentationDemoState extends State<SegmentationDemo> {
  final imageProvider = Image.network(
    'https://example.com/path/to/your/image.jpg', // 替换为你的图像URL
  ).image;

  // 假设你有一个分割结果,这里用随机生成的数组作为示例
  final segmentationMask = Uint8List.fromList(List.generate(256 * 256, (index) => index % 256 < 128 ? 255 : 0)); // 256x256的灰度图,一半白一半黑

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Segmentation Renderer Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            AspectRatio(
              aspectRatio: imageProvider.width.toDouble() / imageProvider.height.toDouble(),
              child: SegmentationRenderer(
                imageProvider: imageProvider,
                segmentationMask: segmentationMask,
                maskWidth: 256,
                maskHeight: 256,
                // 可选参数,设置颜色映射
                colorMap: [
                  Color(0xFF0000FF).value, // 蓝色
                  Color(0xFFFF0000).value, // 红色
                ],
                // 可选参数,设置透明度
                maskOpacity: 0.5,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

代码解释

  1. 依赖添加:在pubspec.yaml中添加segmentation_renderer依赖。
  2. 主应用:创建了一个简单的Flutter应用,包含一个主屏幕SegmentationDemo
  3. 图像和分割结果
    • imageProvider:通过网络加载图像。
    • segmentationMask:假设的分割结果,这里用一个256x256的灰度图作为示例,其中一半为白色(255),一半为黑色(0)。
  4. 渲染分割结果
    • 使用AspectRatio来保持图像的宽高比。
    • 使用SegmentationRenderer来渲染图像和分割结果。
    • colorMap用于定义分割结果的颜色映射。
    • maskOpacity用于设置分割结果的透明度。

请确保替换示例中的图像URL和分割结果数组以匹配你的实际数据。如果你从本地文件加载图像,可以使用AssetImageFileImage

这个示例只是一个基础示例,你可以根据需要进行扩展和修改。

回到顶部