如何在Flutter应用中使用 OpenCV和 CC++库进行图像流处理

本文指导如何在Flutter应用中集成C/C++插件,特别是OpenCV,以解决Flutter相机插件在处理图像流时的性能问题。通过使用Dart的Isolates和FFI,结合OpenCV的C++库,实现在Android和iOS上的高效图像处理,同时保持UI流畅。文章提供了结构建议、处理流程和FFI绑定的详细步骤,以及GitHub仓库链接供参考。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文将帮助你在 Android 和 iOS 中为 Flutter 应用程序集成 C/C++ 插件。

问题1: Flutter camera 插件没有为快速复杂的图像流处理提供完整的指南。

问题2: Flutter camera 插件处理图像流太慢。

问题3:图像处理需要OpenCV包

问题4:你当前的图像流处理实现正在阻塞 UI 并导致你的应用程序滞后和内存泄漏

问题5:缺乏实现接口和使用 Dart FFI 库有效集成 C/C++ 库的知识

本指南将通过使用 OpenCV C++ 构建适用于 Android 和 iOS 的示例应用程序来解决每个问题,以进行图像流处理。

先决条件

在开始之前,需要一个带有 OpenCV C++ 的 Flutter 插件及其适用于 Android 的静态库以及适用于 iOS 的 xcframework。本文不会介绍如何执行此操作,但你可以按照下方链接提供的指南或在我提供的 GitHub 存储库中运行脚本文件。

  • 指南:https://medium.com/@khaifunglim97/how-to-build-a-flutter-app-with-c-c-libraries-via-ffi-on-android-and-ios-including-opencv-1e2124e85019

  • 脚本文件:https://github.com/khaifunglim97/flutter_ffi_examples

对于 Android,确保 CMakeLists.txt 构建所需的库,并将 build.gradle 设置为以下值,防止OpenCV 产生错误。

externalNativeBuild {            
    cmake {                
        cppFlags "-frtti -fexceptions -std=c++17"
        abiFilters 'armeabi-v7a', 'arm64-v8a'            
    }        
}

对于 iOS,确保 podspec 下的 vendored_frameworks 包含 OpenCV 的 xcframework。

此外,本指南假设有一个工作状态小部件,类似于 flutter camera 插件中提供的简单示例,其中包含一个 CameraPreview 小部件及其所需的设置。

示例:https://pub.dev/packages/camera

假设

本指南仅承诺在手机后置摄像头上以纵向模式进行图像处理的工作模型,设置捕获分辨率为720p (1280x720)。但是,它可以作为读者集成其他相机、设备方向模式和捕获分辨率的指南。

注意:本指南仅在适用于 Android 的 Android NDK 版本 25.0.8775105 上进行测试。它可能无法使用其他 NDK 版本成功构建 C/C++ 文件。

建议的结构

b0d00f6e485bdde9db2e44791cbe5409.png

相机图像流处理的建议结构

移动设备上任何流处理的主要挑战是处理帧的速度足够快,以每秒至少处理 60 帧(每帧约 16 毫秒)。传统的图像处理过程几乎总是需要比每帧 16 毫秒多得多的时间。因此,必须使用后台线程来不阻塞 UI 并导致应用程序卡顿。

我们需要利用 Dart Isolates 来实现这一点。包含 CameraPreview 小部件的视图旁边将有一个 CameraProcessor 小部件,这样每个帧都将被传递给处理器进行处理。处理器将依次生成Isolate,以运行 C/C++ OpenCV 代码,并异步等待它们完成。

最后,从处理器中的Isolate接收到的任何结果都将传递给 CameraPainter 以更新 UI 状态并显示结果。尽管具有流畅的 UI,但这种方法的缺点是响应延迟,其中 UI 和Painter将显示不匹配,其中绘制的结果来自先前捕获的帧,具体取决于设备和处理速度

相机视图/相机预览

camera 插件页面中提供的示例足以构建最小的相机视图。我们只需要在小部件内添加帧捕获和相机处理器,如下所示:

// Start frame capture in controller under initState()
...
try {
    await controller?.initialize();
    controller?.startImageStream(_processCameraImage);
    setState(() {});
} catch (e) {
...

// Set what to do with frames inside stateful widget
Future _processCameraImage(CameraImage camImage) async {
   if (!mounted) return;    
   setState(() {
      cameraImage = camImage;
   });
}

// Pass each frame into CameraProcessor under build()
CameraPreview(
    camController,
    child: CameraProcessor(
        image: camImg,
    ),
)

CameraPainter

此处的指南为Painter 展示了一些不错的模板:https://github.com/bharat-biradar/Google-Ml-Kit-plugin/tree/master/packages/google_ml_kit/example/lib/vision_detector_views)

我们需要将要绘制到画布上的对象传递给这个小部件,并使用绘制函数来显示结果。需要注意的最重要的事情是图像的旋转&

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值