如何在Flutter插件中添加OpenCV

时间:2018-11-01 10:46:52

标签: android opencv gradle flutter flutter-dependencies

我正在进行一个抖动项目,在该项目中我必须检测对象的边缘。我已经搜索了现有的插件,但找不到任何插件。我打算使用OpenCV进行边缘检测。

我从Android Studio创建了一个flutter插件。这是插件结构。

enter image description here

我已经从此处opencv-3.4.3-android-sdk下载了适用于Android的OpenCV,并进行了提取。

enter image description here

我已将OpenCV SDK中的java文件夹作为模块导入到flutter插件的Android项目中。

这是我的android项目(flutter插件) build.gradle 的样子

group 'com.xxxx.xxxxx'
version '1.0-SNAPSHOT'

buildscript {
    ext.kotlin_version = '1.2.30'
    repositories {
        google()
        jcenter()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:3.1.2'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

rootProject.allprojects {
    repositories {
        google()
        jcenter()
    }
}

apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'

android {
    compileSdkVersion 27

    sourceSets {
        main.java.srcDirs += 'src/main/kotlin'
    }
    defaultConfig {
        minSdkVersion 16
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    lintOptions {
        disable 'InvalidPackage'
    }
}

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'

    implementation project(':openCVLibrary343')
    compileOnly files('templibs/flutter.jar')
}

这就是我的opencv build.gradle 的样子

apply plugin: 'com.android.library'

android {
    compileSdkVersion 27
    buildToolsVersion "28.0.3"

    defaultConfig {
        minSdkVersion 8
        targetSdkVersion 21
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }
}

这是Android项目(flutter插件)的 settings.gradle 的外观

rootProject.name = 'flutter_plugin'
include ':openCVLibrary343'

当我尝试运行由flutter插件模板创建的示例应用程序时,出现以下错误。

以调试模式在Nexus 6P上启动lib \ main.dart ... 正在初始化gradle ... 解决依赖性... *运行Gradle时出错: 从以下位置退出代码1:C:\ Users \ xxxxx \ Documents \ flutter_plugin \ example \ android \ gradlew.bat app:properties:

失败:构建失败,并出现异常。

  • 其中: 构建文件“ C:\ Users \ xxxx \ Documents \ flutter_plugin \ android \ build.gradle”行:48

  • 出了什么问题: 评估项目':flutter_plugin'时发生问题。

      

    在项目':flutter_plugin'中找不到路径为':openCVLibrary343'的项目。

  • 尝试: 使用--stacktrace选项运行以获取堆栈跟踪。使用--info或--debug选项运行以获取更多日志输出。使用--scan运行以获取完整的见解。

  • https://help.gradle.org

  • 获得更多帮助

1秒内失败

完成错误:请在android /文件夹中查看您的Gradle项目设置。

1 个答案:

答案 0 :(得分:1)

对于我正在从事的项目,我设法创建了一个依赖于OpenCV的flutter插件,以便处理来自相机的图像。请注意,当我说“ 来自摄像机”时,我不是指视频捕获的实时帧,而是先前保存在设备内存中的图片。

首先,我关注了Flutter文档中有关创建plugins here

的信息

当flutter创建了plugin文件夹和文件时,我得到的结构与此类似(第一层的“ opencv”文件夹是plugin的根): Folder structure

请注意,我添加的opencv-341.jar文件包含用于控制本机库的Java方法,OpenCVPlugin.javaopencv.dart是从Flutter访问Java方法的入口点,并且是从Flutter创建的。

.java和.dart文件的文件名可能不同,并且反映了您在上面的插件创建阶段作为参数传递的名称。

.jar文件可以在Java的OpenCV软件包中找到,作为预编译的库。在同一软件包中,您会在此小文章的结尾找到所需的本机库。

[plugin_root] / android中的build.gradle文件应引用该jar文件

dependencies {
    implementation files('opencv/opencv-341.jar')
}

OpencvPlugin.java应该托管从dart调用的方法。就我而言,为了更好地管理不同的方法,我创建了如下代码:

if (call.method.equals("processReceiptImage")) {
    if (!call.hasArgument("input")) {
        result.error("NOTFOUND", "File not found", null);
        return;
    }
    try {
        String input = call.argument("input");
        int maxWidth = (int) call.argument("maxWidth");
        int quality = (int) call.argument("quality");
        String output = call.argument("output");
        result.success(ProcessReceiptImage.run(input, maxWidth, quality, output));
        return;
    } catch (Exception e) {
        e.printStackTrace();
        result.error("UNKNOWN", e.getMessage(), null);
        return;
    }
}

静态方法ProcessReceiptImage包含在相对文件ProcessReceiptImage.java中:

package com.yourplugin.opencv;

import org.opencv.core.Mat;
import org.opencv.core.MatOfInt;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import java.util.ArrayList;


public class ProcessReceiptImage {
    static String run(String input, int maxWidth, int quality, String output) throws Exception {
        Mat src = Imgcodecs.imread(input, Imgcodecs.CV_LOAD_IMAGE_GRAYSCALE);
        Size size = src.size();

        int height = (int) (maxWidth * size.height / size.width);
        Imgproc.resize(src, src, new Size(maxWidth, height));

        ArrayList<Integer> parameters;
        parameters = new ArrayList();

        parameters.add(Imgcodecs.CV_IMWRITE_JPEG_QUALITY);
        parameters.add(quality);

        MatOfInt par = new MatOfInt();
        par.fromList(parameters);
        Imgcodecs.imwrite(output, src, par);
        return output;
    }
}

从这时开始,如果您运行应用程序,则可能由于缺少库opencv_java3而失败。 为了解决这一部分,我现在建立的唯一方法是将本机库复制到最终项目中,如下所示(这是应用程序的根目录,而不是插件):

enter image description here

我已经为要定位的每个平台提供了最终的.so本机库,因此,无论用户使用哪个平台,代码始终可以选择相应的.so并正确加载OpenCV。

提示:由于包含所有.so文件可能会导致较大的APK,建议您配置build.gradle以便将软件包拆分为abis,这样您将拥有一个较小的APK,该APK将自动通过Play商店。