〔两行哥〕OpenCV4Android教程之API系列(一)

OpenCV是一个基于C与C++的跨平台计算机视觉处理库,高效且轻便,支持多平台,参考:OpenCV支持平台及相关介绍。目前国内网络上充斥着各种OpenCV“教程”,但大多基于C++语言,或者Python语言,使用的OpenCV版本也非常老旧,而且国外的OpenCV官网上关于Android平台的介绍也寥寥无几,大部分讲解了OpenCV内部的算法原理而非API,对于我们Android开发者(使用Kotlin或Java)来说,想入门OpenCV似乎相当困难。

在这里两行哥给大家带来OpenCV4Android的入门教程,主要分为API系列和算法系列。API系列主要聚焦常用API及用法(略小白),帮助Android开发者快速完成企业开发需求。算法系列主要聚焦OpenCV内部数学算法,供有一定数学基础的开发者一窥究竟。

一、开发环境

(一)基于OpenCV 3最新版(V3.4.10):OpenCV SDK下载地址

OpenCV SDK有多个分支,4.X、3.X及2.X。各个分支除了集成方式不同外,4.X和3.X在某些场景下的效率也比2.X有所提升。具体区别各位读者可以自己查阅相关资料。本教程基于V3.4.10(两行哥发现4.X版本部分API虽然执行速度提升,但是某些场景处理效果较3.X版本有出入,请读者自行查验)。

(二)基于AndroidStudio

请不要再看任何用着Eclipse开发Android的教程,实在太古老了。本文使用的是AS 3.6.3。

(三)基于Java

本来想用Kotlin,想想受众,还是用Java吧,用Kotlin开发Android的基本上都会Java,反过来,用Java开发Android的不一定都会Kotlin。

二、OpenCV SDK集成

相信我,真没有其他人写的那么复杂,不需要那么多种集成方式,那是基于2.X版本的。对于3.X版本的集成,很简单,大家不要有畏难心理。

(一)下载SDK

建立一个Demo工程,然后根据上文提供的下载地址,下载OpenCV4AndroidSDK,如图1。


图1 下载SDK

下载完成后解压,看一下解压后的内容,如图2。


图2 SDK文件夹

这里一共有3个文件夹:

1.samples:这里都是例子工程,包括了编译好的apk文件和项目源码。

2.apk:里面是针对各个架构编译好OpenCVManager.apk文件,这是干什么用的呢?因为OpenCV中的jni库体积比较大,需要集成到App中,如果用户手机中有很多个使用到OpenCV库的App,那么这些App就可以不集成OpenCV的jni库,直接安装对应架构的OpenCVManager,OpenCVManager内就含有OpenCV需要的jni库,所有的App通过OpenCVManager共享一份jni库就好了,而且OpenCVManager可以很方便地管理和升级jni库。那么这些App是如何和OpenCVManager通讯的呢?看一下OpenCVLibrary源码就知道了,嗯,aidl。
说了这么多,到底有什么用呢?假如我们要运行第2个文件夹samples中OpenCV的Demo,你会发现这些Demo体积都非常小,因为它们都没集成OpenCV的jni库。我们装上这十来个Demo后,再装上对应架构的OpenCVManager,它们就能愉快地共用一份jni库了......实际开发中不会这么做,一定是把OpenCV的jni库集成到项目内部的,直接使用。我们总不能要求用户装好我们的App,然后引导用户到OpenCV的官网或者其他地方去下载OpenCVManager吧?大概是脑抽,觉得自己的App活腻了,用户也觉得你的App实在是欠删。好了,说了这么多,其实就是扯蛋,在实际开发中,第一个文件夹里的东西......其实没什么卵用。

3.sdk:就是我们要的sdk了。

(二)引入SDK

首先,我们将文件夹sdk中的java文件夹作为module导入到我们建立好的Demo工程中,如图3、图4所示,这里自定义Module name为OpenCVLib。

图3 导入Module
图4 Module路径

导入完成后,配置项目依赖,如图5所示。

图5 配置项目依赖关系

然后进入OpenCVLib包中的build.gradle,修改编译版本,与app包中的build.gradle一致,如图6所示。

图6 配置Android SDK Version
(三)配置jniLibs

接着开始配置jniLibs,sdk中包含的jniLibs如图7所示:


图7 包含的jniLibs

有两个选择:
选择1:将这些jniLibs文件原封不动地保留在OpenCVLib module的native/libs目录下,原封不动地保留build.gradle(OpenCVLib)中对jniLibs路径的定义:

    sourceSets {
        main {
            jniLibs.srcDirs = ['native/libs']
            java.srcDirs = ['java/src']
            aidl.srcDirs = ['java/src']
            res.srcDirs = ['java/res']
            manifest.srcFile 'java/AndroidManifest.xml'
        }
    }

选择2:复制图7所示目录下所有的文件夹到你定义的jniLibs路径下,我们习惯把jniLibs路径定义在图8所示的app/src/main/jniLibs包下,如果jniLibs包不存在则新建一个。


图8 app 默认 jniLibs

然后在build.gradle(app)中定义jniLibs路径,代码如下:

    sourceSets {
        main {
            jniLibs.srcDirs = ['src/main/jniLibs']
        }
    }

最终完成在app module中定义jniLibs,如图9所示:


图9 app中定义jniLibs

如果之前你自定义了其他的jniLibs包的路径,请复制到你自定义的包路径下,不要生搬硬套。

这里提醒一下,如果你的项目之前就引入过其他jniLibs,则之前引入过多少种架构,这里也选择性地粘贴同样的架构文件夹,多一个不行,少一个也不行。如:之前有armeabi和armeabi-v7a,那么这次你也要选择这两个架构文件夹粘贴就好了,否则在运行时会发生崩溃,提示找不到对应架构的jniLibs。

顺便插一嘴,通常情况下我们选择armeabi、armeabi-v7a和arm64-v8a就够了,如果为了App体积考虑,只引入armeabi也够了。具体各种架构有什么区别,对应什么CPU,两行哥这里就不详细解释了,请读者自行查阅相关资料。

强烈建议配置支持的ndk类型,如图10所示,引入了多少架构包,就写多少种类型。
图10 设置ndk支持的架构
如果项目引入了某个使用了jniLibs的第三方库,这个第三方库支持的架构比你现有项目中架构多,运行时一样会发生上文所说的崩溃现象,就需要进行图10的配置。

例如:项目通过implementation "com.github.pqpo:SmartCropper:v1.1.3" 方式引入了SmartCropper这个第三方库,SmartCropper库支持多种架构,而你的项目仅仅引入了armeabi jniLibs,那么就可能在运行时发生崩溃。此时你需要在图9的位置配置 abiFilters "armeabi",不写其他架构,表示项目仅仅支持armeabi架构,而不支持其他架构。

(四)初始化OpenCV

至此,SDK配置已经完成,在Application或者MainActivity中初始化OpenCV:

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";

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

    public void initOpenCV() {
         OpenCVLoader.initDebug()
    }
}

其实OpenCVLib module中还有很多普通开发者用不到的文件,大家可以尝试精简掉,具体可以参照下文的Demo,保留我们需要的文件即可。

(二)实例Demo

参见:OpenCV4Android入门教程之安卓答题卡识别

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容