Android 接入 OpenCV库的老三种植方法

     
 OpenCV是一个因BSD许可(开源)发行的跨平台计算机视觉库,可以运作在Linux、Windows、Android和Mac
OS操作系统及。它轻量级而且迅速——由同名目繁多 C 函数和少量 C++
类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理以及计算机视觉方面的群通用算法。

 

     
 我们使用它来举行有图纸的处理,能大大的优化内存的拍卖。下面我的话说过渡下OpenCV
的老三种植艺术:

 

一致、接抱OpenCV 的Java SDK
包,这样您可直接以Java调用OpenCV
的大部方。第一种植方式适用于对Opencv c++
不熟悉的童鞋,不需一直调用C++方案, 因为SDK 已经用JNI
全部包好了。假设你已设置好JDK、AndroidStudio与NDK环境。

         先到官网http://opencv.org/releases.html ,下载Android
包,如:opencv-3.2.0-android-sdk.zip。

C++ 1 

sdk 目录提供了Android的API与Java 库

sdk/java 目录包含了一个 Eclipse 项目,该项目提供 OpenCV 的Java
API,且可以导入到开环境里。

sdk/native 目录包含了OpenCV C++ 头文件(用于JNI),与Android的 .so动态库
.a静态库。

sdk/etc 目录包含了Haar 与 LBP cascades 级联。

apk  目录包含了用户安装在指定的Android设备的安装文件,该公文要opencv
库可以管理opencv API

 

首先: File > New > New Module

C++ 2

 

然后:选择Import Eclipse ADT Project

C++ 3

 

拿sdk/java 下的门类导入到项目里,然后将这modules 添加到 app
modules里,

直以 app 目录下build.gradle 文件里dependencies 大括如泣如诉下上加:

compile project(‘:openCVLibrary’)

 

继以 app/src/main 目录下 创建一个jniLibs 目录,然后把sdk/native/libs
下所有文件 拷贝到jniLibs下,编译,运行。

 

比方导入后,出现一些android
自带的类识别不了,那即便是因编译的SDK版本出错了。

开辟 刚导入 的模块下 build.gradle 文件,把 compileSdkVersion 与
targetSdkVersion修改成你最新的SDK版本,如:

 

apply plugin: 'com.android.library'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.0"

    defaultConfig {
        minSdkVersion 15
        targetSdkVersion 25
    }

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

运行,则成功了,我意识如未需再安装额外的 opencv 的apk 了。

下面链接是本身加加成的例证: 

https://github.com/xiaoxiaoqingyi/NDKDemos     OpenCV_java 项目

 

老二、使用opencv sdk 提供的 C++ 头文件和
.so动态库 与 .a静态库,自己封装jni,这样以的效率会较第一栽艺术高有,
且可以100%下opencv 的接口。下面看一下安的不二法门:

 

      用AndroidStudio 创建一个种类,然后在 Java 类里创建一个native
方法,

重新在app/src/main 下创造 jni,然后创建 cpp 文件对 native 方法。

如上是一个简单易行的jni 方法,你可查阅自己以前的 文章:
http://www.cnblogs.com/xiaoxiaoqingyi/p/6524165.html

当核心的jni 跑通产,我们管 opencv 库加入项目里,首先:

 

1、把 sdk/native 目录 拷贝到 项目的 jni 目录下,

C++ 4

 

接下来就安排 Android.mk文件:

LOCAL_PATH:=$(call my-dir)

include $(CLEAR_VARS)
OpenCV_INSTALL_MODULES := on
OpenCV_CAMERA_MODULES := off
OPENCV_LIB_TYPE :=STATIC

ifeq ("$(wildcard $(OPENCV_MK_PATH))","")
include $(LOCAL_PATH)/native/jni/OpenCV.mk
else
include $(OPENCV_MK_PATH)
endif
LOCAL_MODULE := OpenCV
LOCAL_SRC_FILES := com_magicing_eigenndk_NDKUtils.cpp
LOCAL_LDLIBS +=  -lm -llog
include $(BUILD_SHARED_LIBRARY)

 

继安排 Application.mk 文件:

APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_PLATFORM := android-9

 

说到底在 cpp 文件调用 opencv 的不二法门, 首先导入 #include
<opencv2/opencv.hpp> 如:

#include <jni.h>
#include <string>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <opencv2/opencv.hpp>

using namespace cv;

extern "C"

  JNIEXPORT jintArray JNICALL Java_com_magicing_eigenndk_NDKUtils_gray(
          JNIEnv *env, jclass obj, jintArray buf, int w, int h) {

      jint *cbuf;
      cbuf = env->GetIntArrayElements(buf, JNI_FALSE );
      if (cbuf == NULL) {
          return 0;
      }

      Mat imgData(h, w, CV_8UC4, (unsigned char *) cbuf);

      uchar* ptr = imgData.ptr(0);
      for(int i = 0; i < w*h; i ++){
          //计算公式:Y(亮度) = 0.299*R + 0.587*G + 0.114*B
          //对于一个int四字节,其彩色值存储方式为:BGRA
          int grayScale = (int)(ptr[4*i+2]*0.299 + ptr[4*i+1]*0.587 + ptr[4*i+0]*0.114);
          ptr[4*i+1] = grayScale;
          ptr[4*i+2] = grayScale;
          ptr[4*i+0] = grayScale;
      }

      int size = w * h;
      jintArray result = env->NewIntArray(size);
      env->SetIntArrayRegion(result, 0, size, cbuf);
      env->ReleaseIntArrayElements(buf, cbuf, 0);
      return result;
  }

 

然后以 activity 页面里亮处理了之图,如下:

public class MainActivity extends AppCompatActivity {

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

        Bitmap bitmap = ((BitmapDrawable) getResources().getDrawable(
                R.mipmap.pic_test)).getBitmap();
        int w = bitmap.getWidth(), h = bitmap.getHeight();
        int[] pix = new int[w * h];
        bitmap.getPixels(pix, 0, w, 0, 0, w, h);
        int [] resultPixes=ndk.gray(pix,w,h);
        Bitmap result = Bitmap.createBitmap(w,h, Bitmap.Config.RGB_565);
        result.setPixels(resultPixes, 0, w, 0, 0,w, h);

        ImageView img = (ImageView)findViewById(R.id.img2);
        img.setImageBitmap(result);

    }

}

运行成功后:

C++ 5

 

本身编译成功之种链接:

https://github.com/xiaoxiaoqingyi/NDKDemos   (OpenCV_native项目)

官网参考资料:

http://docs.opencv.org/2.4/doc/tutorials/introduction/android_binary_package/dev_with_OCV_on_Android.html#native-c

 

老三、通过opencv 的源码,重新编译成
Android sdk
库,这样的益处是力所能及获取到新型的效果,缺点是编译有点紧(对于非懂C++/C
的童鞋),且新的代码或许会存在无兼容与错误。

 

http://code.opencv.org/projects/opencv/wiki/Building_OpenCV4Android_from_trunk

     以上的链接是官网推荐的编译过程,我也尝尝过编译成功,如果在windows
下安装Cygwin,然后来编译是经过非了底,需要重新安装cmake、shell
以及另外的软件,编译的历程真的复杂很多。

     我是当MAC下编译的,只待安装
cmake软件,当然也要发NDK的环境。大概的步调:

https://github.com/opencv/opencv 下载opencv 源码包

 

1、在maC++c 下安装好 cmake 软件,

2、配置NDK环境变量,
参考百度:http://jingyan.baidu.com/article/d2b1d1029c1ea65c7e37d4c9.html

3、build_android_arm/install 目录下 得到编译好之jni 目录。

 

     如果你想编译 opencv_contrib 也尽管是 opencv
extra库的话,你要拿https://github.com/Itseez/opencv_contrib
额外库包吗下载下来。我都把opencv_contrib包的tracking模块 加入到opencv
核心库,编译到PC的CodeBlocks开发条件就成了,但是编译成Android的条件就生出错了,这个题目本身直接从未解决,最后我换用了别的方法,我管相应的有些材料供于大家:

 

https://github.com/alexkarargyris/Caffe_OpenCV_Android_App

Building OpenCV & OpenCV Extra Modules For Android From Source

      我参考了上述的材料,在加载opencv
额外库的下,编译了几坏啊并未能够得逞,会报cmake 编译出错。我吗于C++
的同事尝试用cmake 帮自己编译,也绝非能打响,也许我们本着cmake
了解未敷好,据说opencv extra
库是要收费的,所以Android端不可知一直编译进来,但是PC端是马到成功编译了的。如产生编译成功之大神,请多多指教!