如何在没有 OpenCv Manager 的情况下 运行 OpenCV 代码

How to run OpenCV code without OpenCv Manager

我使用的是 OpenCV4Android 版本 2.4.10,我在 Samsung Galayx GT-I9300 上测试我的代码。我遇到的问题是,我必须从 Play 商店下载 Opencv Manager,以便我的 opencv 代码 运行s,否则应用程序将无法启动。 我参考了一些帖子 "as shown here How to integrate OpenCV Manager in Android App" 以了解如何 运行 android 上的 opncv 代码而不需要下载 OpenCV 管理器 但不幸的是,只要未安装 OpenCV 管理器,应用程序就不会启动。

我尝试了以下方法

static {
    if (!OpenCVLoader.initDebug()) {
        // Handle initialization error
    }
}

private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
    @Override
    public void onManagerConnected(int status) {
        switch (status) {
            case LoaderCallbackInterface.SUCCESS:
            {
                Log.i(TAG, "OpenCV loaded successfully");
                mOpenCvCameraView.enableView();
            } break;
            default:
            {
                super.onManagerConnected(status);
            } break;
        }
    }
};
...
...
...

@Override
public void onResume() {
    super.onResume();
    Log.w(TAG, "onResume");

    if (!OpenCVLoader.initDebug()) {
        Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager for initialization");
        OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_10, getActivity(), mLoaderCallback);
    } else {
        Log.d(TAG, "OpenCV library found inside package. Using it!");
        mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
    }
}

但这并没有解决问题。 请让我知道如何在 android 上 运行 打开 cv 代码而不下载 Opencv 管理器?

更新:

使用 initAsync:

您能否举例说明如何在应用程序的生产版本中使用 "initAsync()"?因为我尝试这样做,但当然我不能在静态块中使用它,因为 "intiAsync" 的签名如下 "OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_10, this, mLoaderCallback);" 并且我不能使用 "this" 关键字或对回调的引用"mLoaderCallback" 静态块内

public class MainActivity extends AppCompatActivity {

static {
    //OpenCVLoader.initDebug();
    OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_10, this, mLoaderCallback); //this keyword and "mLoaderCallback" are not defined in this scope
}

private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
    @Override
    public void onManagerConnected(int status) {
        switch (status) {
            case LoaderCallbackInterface.SUCCESS: {
                Log.i("MainActivity", "OpenCV loaded successfully");
            }
            break;
            default: {
                super.onManagerConnected(status);
            }
            break;
        }
    }
};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Mat m = new Mat(100, 100, CvType.CV_8UC4);
    Log.d("MainActivity", "m.width()" + m.width());
    Log.d("MainActivity", "m.height()" + m.height());
}
}

因为你想要一步一步的过程,所以我会从头开始创建一个 SampleOpenCV 项目,并且还建议在一个新项目中执行以下步骤,一旦它开始工作你可以尝试将更改迁移到您的主项目。

  1. Opencv.org [ Direct Download Link V3.1 下载 android 的 OpenCV 包]
  2. 将 zip 解压到您选择的位置,在 Android Studio 中打开 SampleOpenCV 项目,然后 File -> New -> Import Module ,这将打开一个新的弹出窗口以输入模块路径,select {unzipped_opencv}/sdk/java,这将在 SampleOpenCV.
  3. 下创建一个 OpenCVLibrary310 目录
  4. 现在打开 SampleOpenCV/OpenCVLibrary310/build.gradle 并从 SampleOpenCV/app/build.gradle 复制以下字段:
    • compileSdkVersion
    • 构建工具版本
    • minSdkVersion
    • targetSdkVersion
  5. 现在右键单击您的 SampleOpenCV 项目并单击 打开模块设置 ,查找 Modules >> app 和 select 依赖关系

  1. 点击右上角的+标志,在弹出window和select3模块依赖性。现在选择 OpencvLibrary310。关闭弹出窗口并让 gradle 同步。

  2. 复制 libs 文件夹 {unzipped_opencv}/sdk/native/libs 到 app/src/main 下的 Android Studio 并重命名为 jniLibs (Mind这里的情况)。

  3. 大功告成。

public class MainActivity extends AppCompatActivity {
    static {
        OpenCVLoader.initDebug();
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Mat m = new Mat(100, 100, CvType.CV_8UC4);
    }
}

注意OpenCVLoader.initDebug() 必须仅用于调试目的,就像您在机器上进行本地开发一样。但出于生产目的,您需要在 Play 商店等发布应用程序,您必须使用 OpenCVLoader.initAsync()。实际初始化 OpenCVLoader 需要一些时间,具体取决于 phone。所以如果你加载它 uisng initDebug(),那么它会在主线程中执行,这可能会阻塞 UI 一段时间。所以建议在后台加载 OpenCV,这可以使用 initAsync()

来实现

更新的答案

如果您完成所有步骤并获得 java.lang.UnsatisfiedLinkError,可能您遗漏了 jniLibs 或者您没有正确执行第 6 步。

将此代码添加到您的应用级别 gradle:

 andriod{
        sourceSets.main {
                    jniLibs.srcDirs = ['libs'] 
        }
  }

gradle sync 后 jniLibs 会像这样显示

把我的方法分享给你

  1. https://opencv.org/releases.html
  2. 下载 android 的 opencv sdk
  3. 解压opencv sdk
  4. 在您的项目(例如 ADVisionProject)中,打开 settings.gradle 文件并在下面添加配置

--

def opencvsdk = '<path_to_opencv_android_sdk_rootdir>'
include ':opencv'
project(':opencv').projectDir = new File(opencvsdk + '/sdk')

以我的 settings.gradle 文件为例

include ':app'

def opencvsdk = '/Volumes/Data/Projects/machine-learning/OpenCV-android-sdk'
include ':opencv'
project(':opencv').projectDir = new File(opencvsdk + '/sdk')
  1. 在app/build.gradle中,添加opencv模块到dependencies

--

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
   ....
    implementation project(':opencv')

}
  1. 写一些测试用的代码。关于下面的代码,它将可绘制图像读取到 Mat 并将颜色转换为灰色模式,将 Mat 转换为 Bitmap 并将 Bitmap 显示到 ImageView。

--

import android.graphics.Bitmap;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ImageView;

import org.opencv.android.OpenCVLoader;
import org.opencv.android.Utils;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;

import java.io.IOException;

public class MainActivity extends AppCompatActivity {

    static {
        OpenCVLoader.initDebug();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ImageView imageView = findViewById(R.id.activity_main_iv_result);
        try {
            Mat img = Utils.loadResource(this, R.drawable.eye);
            Mat gryimg =  new Mat(img.size(),CvType.CV_8U);
            Imgproc.cvtColor(img, gryimg, Imgproc.COLOR_RGB2GRAY);
            Bitmap bm = Bitmap.createBitmap(gryimg.cols(), gryimg.rows(), Bitmap.Config.ARGB_8888);
            Utils.matToBitmap(gryimg, bm);
            imageView.setImageBitmap(bm);
        } catch (IOException e) {
            e.printStackTrace();
        }


    }
}
  1. 尝试构建 apk 并安装到 android 设备。它不需要 OpenCV 管理器。但我发现 apk 的大小很大,初始大小约为 80MB

已使用 opencv-3.4.1-android-sdk 和 Android Studio 3.1.3

进行测试

我们有一些方法可以将 sdk 集成到您的项目中。您应该阅读 /sdk/build.gradle 以获得更多选项

正确加载原生库的方式是:

System.loadLibrary("opencv_java3");