OpenCV4 Android 搭建入门 demo

下载并集成 OpenCV

下载

首先到 OpenCV 官网,下载 Android 版本
在这里插入图片描述
下载后的目录结构如下
在这里插入图片描述

导入项目并做修改

打开 Android Studio,新建项目
然后 File ——> New ——> Import Module,选择 D:\Downloads\opencv-4.2.0-android-sdk\OpenCV-android-sdk\sdk (该目录根据你自己下载的位置而定),引入的时候会让你输入模块名,我是填 opencv,你们可以随意用自己喜欢的名字

对 opencv 的 build.gradle 做 2 处修改

  1. compileSdkVersion 和 targetSdkVersion 都改为最新版
    在这里插入图片描述2. 编译的 Java 版本改为最新的
    在这里插入图片描述

国内被墙,gradle 同步失败问题

修改项目根目录的 build.gradle 文件,通用模板如下(包括flutter同步失败,证数错误等问题,都可以使用该模板解决)


// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        //使用阿里云国内镜像
        maven{ url 'https://maven.aliyun.com/nexus/content/groups/public/'}
        maven{url 'https://maven.aliyun.com/repository/google'}
        maven{url 'https://maven.aliyun.com/repository/jcenter'}
        mavenCentral()
        mavenLocal()
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.6.3'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
        //https://github.com/JakeWharton/butterknife
        classpath 'com.jakewharton:butterknife-gradle-plugin:10.2.1'
        //https://github.com/greenrobot/greenDAO
        classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2'
        //AOP方案一
//        classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.4'
        //AOP方案二:
//        classpath 'org.aspectj:aspectjtools:1.8.13'
//        classpath 'org.aspectj:aspectjweaver:1.8.13'
    }
}

allprojects {
    repositories {
        maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
        maven { url 'https://maven.aliyun.com/nexus/content/repositories/jcenter' }
        maven { url 'https://maven.aliyun.com/nexus/content/repositories/google' }
        maven { url 'https://maven.aliyun.com/nexus/content/repositories/gradle-plugin' }
        mavenCentral()
        // 用来引入 rxpermission, GreenDaoUpgradeHelper 等第三方库
        maven { url 'https://jitpack.io' }
        mavenLocal()
        // bmob后台数据库,用来更新apk
        maven { url "https://raw.github.com/bmob/bmob-android-sdk/master" }
        google()
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

在这里插入图片描述

testOnly 问题

Android Studio 3.0会在debug apk的manifest文件application标签里自动添加 android:testOnly="true"属性,导致IDE中run跑出的apk在大部分手机上只能用 adb install -t <apk> 来安装

在项目根目录的 gradle.properties 中添加 android.injected.testOnly=false

在这里插入图片描述同步一下,至此,编译成功

原理讲解

修改 MainActivity.java

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //初始化
        if (OpenCVLoader.initDebug()) {
            Toast.makeText(this, "OpenCVLoader初始化成功", Toast.LENGTH_SHORT).show();
        }
	}
}

OpenCVLoader 会尝试加载OpenCV 要用到的所有 so 库,如果全部加载成功并返回true,则说明集成正确。

在 OpenCV 3.0 之前,要使用 OpenCV 的功能,都必须额外安装一个 OpenCV Manager 的 apk,但 3.0 版本之后就不用了, OpenCV 的所有功能都已经被集成进 so 了,只需要调用OpenCVLoader.initAsync 然后 OpenCV 会在初始化完毕之后回调 LoaderCallbackInterface 接口的 onManagerConnected 来通知我们初始化完毕。

initDebug 代码如下

public class OpenCVLoader
{
	public static boolean initDebug()
    {
        return StaticHelper.initOpenCV(false);
    }
	(略去后面代码)
}

initOpenCV 代码如下

class StaticHelper {

    public static boolean initOpenCV(boolean InitCuda)
    {
        boolean result;
        String libs = "";

        if(InitCuda)
        {
            loadLibrary("cudart");
            loadLibrary("nppc");
            loadLibrary("nppi");
            loadLibrary("npps");
            loadLibrary("cufft");
            loadLibrary("cublas");
        }

        Log.d(TAG, "Trying to get library list");

        try
        {
            System.loadLibrary("opencv_info");
            libs = getLibraryList();
        }
        catch(UnsatisfiedLinkError e)
        {
            Log.e(TAG, "OpenCV error: Cannot load info library for OpenCV");
        }

        Log.d(TAG, "Library list: \"" + libs + "\"");
        Log.d(TAG, "First attempt to load libs");
        if (initOpenCVLibs(libs))
        {
            Log.d(TAG, "First attempt to load libs is OK");
            String eol = System.getProperty("line.separator");
            for (String str : Core.getBuildInformation().split(eol))
                Log.i(TAG, str);

            result = true;
        }
        else
        {
            Log.d(TAG, "First attempt to load libs fails");
            result = false;
        }

        return result;
    }
	
	(略去后面代码) 
}

加载成功后,日志会打印如下两段内容
在这里插入图片描述
在这里插入图片描述

加载和初始化库的两类函数

在 OpenCVLoader.java 中,有两类函数用来加载 OpenCV 库

  • 同步函数 initDebug(boolean InitCuda)
  • 异步函数 initAsync(String Version, Context AppContext, LoaderCallbackInterface Callback)

源码如下,从注释可以看出,两类函数的功能都是一样的 —— 从应用程序包中,加载并初始化 OpenCV 库,它差不多类似 system.loadLibrary(“opencv_java”)

public class OpenCVLoader {
	/**
     * Current OpenCV Library version
     */
    public static final String OPENCV_VERSION = "4.2.0";


    /**
     * Loads and initializes OpenCV library from current application package. Roughly, it's an analog of system.loadLibrary("opencv_java").
     * @return Returns true is initialization of OpenCV was successful.
     */
    public static boolean initDebug()
    {
        return StaticHelper.initOpenCV(false);
    }

    /**
     * Loads and initializes OpenCV library from current application package. Roughly, it's an analog of system.loadLibrary("opencv_java").
     * @param InitCuda load and initialize CUDA runtime libraries.
     * @return Returns true is initialization of OpenCV was successful.
     */
    public static boolean initDebug(boolean InitCuda)
    {
        return StaticHelper.initOpenCV(InitCuda);
    }

    /**
     * Loads and initializes OpenCV library using OpenCV Engine service.
     * @param Version OpenCV library version.
     * @param AppContext application context for connecting to the service.
     * @param Callback object, that implements LoaderCallbackInterface for handling the connection status.
     * @return Returns true if initialization of OpenCV is successful.
     */
    public static boolean initAsync(String Version, Context AppContext,
            LoaderCallbackInterface Callback)
    {
        return AsyncServiceHelper.initOpenCV(Version, AppContext, Callback);
    }
}

实际使用上,我们一般会先调用其同步方法判断是否已加载成功,如果未成功再调用异步加载函数,比如

if(OpenCVLoader.initDebug()) {
	//执行你需要的opencv函数
} else {
	OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION, this, baseLoaderCallback);
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值