(1)搭建opencv-android环境

前言:

本文目的是指导在windows平台搭建一个opencv for android 的开发环境,作者参考了很多网上的教程,本文所使用的各种软件、插件都是截止到写这篇文章的最新版本,作者在实际搭建环境过程中遇到了很多问题,所以会列出遇到的一些常见问题,但是具体机器可能遇到的问题又不一样,还需要读者自己多去实践和摸索,如果遇到什么问题欢迎和作者交流!

准备工具:

eclipse:        adt-bundle-windows-x86_64-20131030 (绿色西瓜皮,此版本已集成android的sdk,cdt等插件)

ndk:             android-ndk-r9c

opencv-sdk:   OpenCV-2.4.8-android-sdk

, w, , , w, h);
  • int[] resultInt = ImageProc.grayProc(pixels, w, h);
  • Bitmap resultImg = Bitmap.createBitmap(w, h, Config.ARGB_8888);
  • resultImg.setPixels(resultInt, , w, , , w, h);
  • imageView.setImageBitmap(resultImg);
  • }
  • @Override
  • public void onResume(){
  • super.onResume();
  • //通过OpenCV引擎服务加载并初始化OpenCV类库,所谓OpenCV引擎服务即是
  • //OpenCV_2.4.3.2_Manager_2.4_*.apk程序包,存在于OpenCV安装包的apk目录中
  • OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, mLoaderCallback);
  • }
  • }
  • 代码第28行:System.loadLibrary("image_proc")用来当OpenCV类库初始化完成后加载类库image_proc。此类库由我们来生成,用于完成图像灰度处理的操作,此部分将在下面中说明。

    (4) ImageProc.java

    [java] view plaincopy(1)搭建opencv-android环境(1)搭建opencv-android环境
    1. package com.iron.grayprocess2;
    2. public class ImageProc {
    3. public static native int[] grayProc(int[] pixels, int w, int h);
    4. }

    ImageProc.java中只定义了方法grayProc,关键字native表明,此方法的实现由本地代码(C/C++)来完成。

    好,到这里,java部分的代码算是写完了,接下来编写JNI及C相关代码

    如果你的eclipse正常导入了NDK,那么在项目上右键 Android Tools->Add Native Support

    (1)搭建opencv-android环境

    (1)搭建opencv-android环境

    接着,在项目目录下会发现多了一个文件夹jni,里面有cpp、Android.mk文件

    (1)搭建opencv-android环境

    我们最终需要在jni目录中包含Android.mk,Application.mk,ImageProc.h,ImageProc.cpp

    头文件ImageProc.h是要自己动手生成的,其他的没有的自己加进去,有的需要改名字的改一下

    (1) Android.mk

    [plain] view plaincopy(1)搭建opencv-android环境(1)搭建opencv-android环境
    1. LOCAL_PATH := $(call my-dir)
    2. include $(CLEAR_VARS)
    3. include ../OpenCV-SDK/native/jni/OpenCV.mk
    4. LOCAL_SRC_FILES  := ImageProc.cpp
    5. LOCAL_MODULE     := image_proc
    6. include $(BUILD_SHARED_LIBRARY)

    注意:

    include .. /OpenCV-SDK/native/jni/OpenCV.mk

    这一句,“OpenCV-SDK"对应的是你解压后复制的opencv的sdk的文件夹名字,这个例子把这个文件夹命名为OpenCV-SDK了

    代码说明:

    第一行:指明当前编译路径;

    第二行:清空变量;

    第三行:将OpenCV类库中的编译文件包含进来,如此一来在我们的工程中即可使用OpenCV类库;

    第四行:指定需要编译的C++源文件;

    第五行:指定编译生成的类库名称;

    第六行:调用命令将源文件编译为静态库。

    注:第三行指定的路径很关键,当opencv类库与工程路径相关位置发生改变时,此路径也要随之改变。

    (2) Application.mk(配置文件)

    [plain] view plaincopy(1)搭建opencv-android环境(1)搭建opencv-android环境
    1. APP_STL := gnustl_static
    2. APP_CPPFLAGS := -frtti -fexceptions
    3. APP_ABI := armeabi-v7a
    4. APP_PLATFORM := android-8

    (3)ImageProc.cpp

    1. #include <ImageProc.h>
    2. #include <opencv2/core/core.hpp>
    3. #include <string>
    4. #include <vector>
    5. using namespace cv;
    6. using namespace std;
    7. JNIEXPORT jintArray JNICALL Java_com_iron_grayprocess2_ImageProc_grayProc(JNIEnv* env, jclass obj, jintArray buf, jint w, jint h){
    8. jint *cbuf;
    9. cbuf = env->GetIntArrayElements(buf, false);
    10. if(cbuf == NULL){
    11. return 0;
    12. }
    13. Mat imgData(h, w, CV_8UC4, (unsigned char*)cbuf);
    14. uchar* ptr = imgData.ptr(0);
    15. for(int i = 0; i < w*h; i ++){
    16. //计算公式:Y(亮度) = 0.299*R + 0.587*G + 0.114*B
    17. //对于一个int四字节,其彩色值存储方式为:BGRA
    18. int grayScale = (int)(ptr[4*i+2]*0.299 + ptr[4*i+1]*0.587 + ptr[4*i+0]*0.114);
    19. ptr[4*i+1] = grayScale;
    20. ptr[4*i+2] = grayScale;
    21. ptr[4*i+0] = grayScale;
    22. }
    23. int size=w * h;
    24. jintArray result = env->NewIntArray(size);
    25. env->SetIntArrayRegion(result, 0, size, cbuf);
    26. env->ReleaseIntArrayElements(buf, cbuf, 0);
    27. return result;
    28. }

    说明:

    •         ImageProc.h头文件可以通过jdk提供的工具javah来生成,具体生成方法在下面
    •         JNI中的定义的函数遵循一定的命名规则:Java_包名_类名_方法名,具体参考JNI编程相关知识;
    •         ImageProc.cpp中利用彩色值转换为灰度值的计算公式,将lena.jpg图像的每个像素转换为灰度值,并返回给应用层。需要注意的是对于ARGB_8888类型的图像而言,其每一个像素值在int型数据中的存储序列为BGRA。
      还需要注ImageProc.cpp 这个文件 第10行的函数名称Java_包名_类名_方法名 请修改成.h 文件生成的那个函数名 

    生成.h 文件


    进行到这里,进行到这里,记得对项目 Project->Build Project,然后开始生成头文件的步骤

    如何生成头文件?

    生成jni头文件时,一直不成功,找了很多教程,最后终于解决了

    可能是环境变量没设置好:

    ANDROID JNI的头文件生成配置

    (1)我的电脑-属性-高级-环境变量
    增加系统变量:java_home:D:\Program Files\Java\jdk1.7.0_01(java安装好后的路径),
    Path变量中添加 %java_home%/bin,
    增加系统变量:classpath:.;D:\Program Files\Android\android-sdk\platforms\android-8\android (第1点android文件夹路径,特别注意要加".;",否则还是会失败的)

    3. 在eclipse中build工程,当然最好无错误了。在cmd窗口下进入此工程的classes目录下运行:javah -jni 包名.类名


    Jni头文件的生成有两种


    一种是很多教程上教的:

    打开cmd,用cd命令进入项目目录,进入bin->classes,

    然后执行javah com.example.grayprocess2 ImagProc

    然后在classes内会发现一个头文件,修改一下名字复制到jni文件夹内就行了


    另一种方法:

    通过cmd,进入src,然后执行javah com.example.grayprocess2 ImagProc


    这两种方法效果一样,区别在于,第一种方法编译的是.class文件,第二种方法编译的是.java文件,两者异曲同工,作者认为对.java文件进行编译更合理,选择哪种方法读者自己选择吧


    把头文件复制到jni之后,会发现ImageProc.cpp 会报很多错,

    还可能会有Symbol 'cv' could not be resolved 这样的错误


    解决方法如下:

    项目右键 properties -> c/c++ ->Paths and Symbol   在includes 里 点Add ->variables->输入path->在${Path}后面加上opencv的sdk的路径,比如我的 E:\android-eclipse\workspace\OpenCV-SDK\native\jni


    添加include

    C/C++ General -> Paths and Symbols:在Includes下add新的GNU C依赖路径。此工程需要“D:\Java\android-ndk-r8\platforms\android-8\arch-arm\usr\include”即可,以后根据不同项目选择不同的依赖库。

    (1)搭建opencv-android环境

    这里只要是你cpp文件里头文件包含目录

    你可以直接在NDK 和opencv jni那个目录下搜索头文件名 然后看看在那个路径有

    配置好后运行就行了


    读者如果还遇到什么问题欢迎评论留言,我在配置环境的过程中查了很多教程,发现和解决了很多问题,很有意思很有收获,对java,c++很多方面有了更深的认识


    上一篇:MySQL内存表的特性与使用介绍


    下一篇:devexpress设置系统全局字体(含工具栏字体)