Android下OpenCV的环境搭建

摘要:
OpenCVforAndroid环境已构建。将下载的OpenCVforAndroid解压缩到一个目录。在基于SDK的OpenCV开发中,我们可以直接调用Android来开发封装的OpenCV接口。我们只需要上面的OpenCV for Android环境来开发。然而,android只封装了openCV的一部分,openCV很多功能都没有封装。因此,要实现许多复杂的功能,必须使用C/C++,这是我们将在下面介绍的方法。创建一个新的android项目NdkOpenCV,将图片添加到资源文件中,将其命名为“test.jpg”,然后将OpenCVLibrary添加到项目中,如上所示。

目录(?)[-]

  1. 前言
  2. 系统环境
  3. 相关工具
  4. Android ADT环境搭建
    1. Android SDK环境变量的配置
    2. Android NDK的安装与配置
  5. OpenCV for Android 环境搭建
  6. 基于SDK的OpenCV开发
  7. 基于NDK的OpenCV开发
    1. Android上层程序的编写
      1. 来自CODE的代码片 activity_mainxml
      2. 来自CODE的代码片 MainActivityjava
      3. 来自CODE的代码片 ImageProcjava
    2. 生成C头文件
    3. 底层C程序的编写
      1. 来自CODE的代码片 Androidmk
      2. 来自CODE的代码片 Applicationmk
      3. 来自CODE的代码片 ImageProccpp
    4. 编译和运行程序
  8. 总结

    前言

    最近需要在Android移动设备上进行OpenCV开发,搭建环境是第一步,我在网上看了n个相关的中文和英文的教程,终于成功搭建环境,现在跟大家分享一下成果,希望为大家减少不必要的困惑和麻烦。

    系统环境

    win7/win8(注:我的系统是win8专业版)

    相关工具

    1.Android ADT Bundle for Windows(注: 我下的是adt-bundle-windows-x86_64-20131030)
    下载地址:https://developer.android.com/sdk/index.html?hl=sk
    2.Android NDK(注:我下的是android-ndk-r8e-windows-x86_64)
    下载地址:https://developer.android.com/tools/sdk/ndk/index.html
    3.OpenCV for Android(注:我下的是OpenCV-2.4.8-android-sdk)
    下载地址:http://sourceforge.net/projects/opencvlibrary/files/opencv-android/

    Android ADT环境搭建

    在下面的操作前,保证你的PC机上已经安装了JDK,关于JDK的安装及其环境变量的配置,在此不再介绍,网上资料很多。

    解压下载的Android ADT Bundle for Windows到某一目录下,我解压在D:MySoftware目录下。

    Android SDK环境变量的配置

    打开 计算机->属性->高级系统设置->高级->环境变量,在系统变量栏目下新建“ANDROID_SDK_HOME”变量,变量值为adt-bundle-windows目录下sdk目录的路径,我的是"D:MySoftwareadt-bundle-windows-x86_64-20131030sdk",如图:

    Android下OpenCV的环境搭建第1张

    在Path变量值中添加"%ANDROID_SDK_HOME% ools;%ANDROID_SDK_HOME%platform-tools"

    Android下OpenCV的环境搭建第2张

    进入cmd命令窗口,检查SDK是否安装成功。
    运行 android –h 如果有下面的输出,表明安装成功:

    Android下OpenCV的环境搭建第3张

    打开%ANDROID_SDK_HOME%eclipse下的eclipse.exe,现在进行自己的安卓开发之旅了。

    Android NDK的安装与配置

    将下载下来的Android NDK解压到某一目录,这里我解压到的目录是“D:MySoftware”。

    打开%ANDROID_SDK_HOME%eclipse下的eclipse.exe,在eclipse中,选择windows->Preference->Android->NDK,然后添加刚才解压的NDK目录的路径,如图:

    Android下OpenCV的环境搭建第4张

    点击"ok"按钮,至此NDK环境搭建完成。

    OpenCV for Android 环境搭建

    解压下载的OpenCV for Android到某一目录下。我解压到的目录是“D:MySoftware”。将解压后的目录下的sdk(我的是:D:MySoftwareOpenCV-2.4.8-android-sdksdk)目录拷贝到你的android的workspace目录下,改名为:OpenCV-SDK(也可以改成其它名)。

    在eclipse中,选择File->import,选择Existing project into Workspace:

    Android下OpenCV的环境搭建第5张

    选择“next”,然后如下图,选择OpenCV-SDK目录的路径:

    Android下OpenCV的环境搭建第6张

    点击“Finish”完成。

    基于SDK的OpenCV开发

    这种情形下,我们可以直接调用android为我们封装好的openCV接口进行开发,我们只需要上面的OpenCV for Android环境就可以进行开发。

    在eclipse中,选择File->import,选择Existing project into Workspace,选择...OpenCV-***-android-sdksample(我的是D:MySoftwareOpenCV-2.4.8-android-sdksamples)目录下的“OpenCV Tutorial 1 - Camera Preview”:

    Android下OpenCV的环境搭建第7张

    点击“Finish”完成。此时工程会报错,需进行如下操作:

    选中工程,右击选择Properties,然后在左边选择Android,在Project build target栏中选择一个:

    Android下OpenCV的环境搭建第8张

    在Library栏目中选择"add",增加OpenCV类库:

    Android下OpenCV的环境搭建第9张

    选中OpenCV Library,点击OK

    Android下OpenCV的环境搭建第10张

    点击ok完成操作,此时你会发现项目不再报错。

    如果此时依然出现错误,可能是项目太旧,与新的target不太兼容的缘故,此时按以下操作应该能解决问题:

    选中项目,右键选择build path->configure build path...

    Android下OpenCV的环境搭建第11张

    选中Android Dependencies和 Android Private Libraries,点击“Remove”进行删除。点击“OK”完成。

    此时选中工程,右键选择 Android tools->fix project properties。错误消失。

    你可以使用真机或模拟器运行运行该程序,这是个基于openCV的摄像头调用程序。需要注意的是,在运行前你需要安装OpenCV_***_Manager_**_*.apk,否则opencv应用将会因为无法加载opencv类库而无法运行。OpenCV_***_Manager_**_*.apk存在于...OpenCV-***-android-sdkapk(我的是D:MySoftwareOpenCV-2.4.8-android-sdkapk)目录下。我安装的是“OpenCV_2.4.8_Manager_2.16_armeabi.apk”。

    当然,你也可以自己新建android工程,然后按上述方法进行openCV库的引用,然后调用相关接口,进行自己的项目开发。

    然而android只是对openCV的部分进行了封装,有许多openCV的功能并没有被封装,所以要实现很多复杂的功能还必须用C/C++进行实现,这就是我们下面要介绍的方式。

    基于NDK的OpenCV开发

    下面我将以一个实例向大家展示基于NDK的OpenCV开发。

    新建android工程NdkOpenCV,将一张图片添加到资源文件,并命名为"test.jpg",按上面所示将OpenCV Library添加到工程中。

    Android上层程序的编写

    1. activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent" >
    
    <Button 
        android:id="@+id/btn"android:layout_width="fill_parent"android:layout_height="wrap_content"android:text="@string/app_name"/>
    
    <ImageView
        android:id="@+id/image_view"android:layout_width="wrap_content"android:layout_height="wrap_content"android:contentDescription="@string/app_name"/>


</LinearLayout>

2. MainActivity.java

package my.example.ndkopencv;


import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import android.os.Bundle;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Bitmap.Config;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;


public class MainActivity extends Activity implements OnClickListener{


    private Button btnProc;
    private ImageView imageView;
    private Bitmap bmp;
    
    //OpenCV类库加载并初始化成功后的回调函数,在此我们不进行任何操作
     private BaseLoaderCallback  mLoaderCallback = new BaseLoaderCallback(this) {
        @Override
        public void onManagerConnected(int status) {
            switch (status) {
                case LoaderCallbackInterface.SUCCESS:{
                    System.loadLibrary("image_proc");
                } break;
                default:{
                    super.onManagerConnected(status);
                } break;
            }
        }
    };
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btnProc = (Button) findViewById(R.id.btn);
        imageView = (ImageView) findViewById(R.id.image_view);
        //将测试图片加载程序中并进行显示
         bmp = BitmapFactory.decodeResource(getResources(), R.drawable.test);
        imageView.setImageBitmap(bmp);
        btnProc.setOnClickListener(this);
    }


    @Override
    public void onClick(View v) {
         
        int w = bmp.getWidth();
        int h = bmp.getHeight();
        int[] pixels = new int[w*h];     
        bmp.getPixels(pixels, 0, w, 0, 0, w, h);
        int[] resultInt = ImageProc.grayProc(pixels, w, h);
        Bitmap resultImg = Bitmap.createBitmap(w, h, Config.ARGB_8888);
        resultImg.setPixels(resultInt, 0, w, 0, 0, w, h);
        imageView.setImageBitmap(resultImg);    
    }
    
    @Override
    public void onResume(){
        super.onResume();
        //通过OpenCV引擎服务加载并初始化OpenCV类库
        OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, mLoaderCallback);
    }
}
3. ImageProc.java
package my.example.ndkopencv;


public class ImageProc {
    public static native int[] grayProc(int[] pixels, int w, int h);
}
生成C++头文件

    打开cmd,进入android工程所在的目录下的bin/classes目录下,执行javah ****.ImageProc命令:

    Android下OpenCV的环境搭建第12张

    在F:MyCodeandroidNdkOpenCVinclasses目录下多了个my_example_ndkopencv_ImageProc.h文件,将该文件重命名为ImageProc.h。

    底层C++程序的编写

    在项目中建立jni文件夹,将上面生成的ImageProc.h文件移动到jni文件夹下。然后分别新建Android.mk,Application.mk,ImageProc.cpp文件,这三个文件内容如下:

    1.Android.mk

    LOCAL_PATH := $(call my-dir)
    include $(CLEAR_VARS)
    include ../OpenCV-SDK/native/jni/OpenCV.mk
    LOCAL_SRC_FILES  := ImageProc.cpp
    LOCAL_MODULE     := image_proc
    include $(BUILD_SHARED_LIBRARY)

    代码说明:

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

    第二行:清空变量;

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

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

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

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

    2.Application.mk

    APP_STL := gnustl_static
    APP_CPPFLAGS := -frtti -fexceptions
    APP_ABI := armeabi-v7a
    APP_PLATFORM := android-8

    3.ImageProc.cpp

    #include <ImageProc.h>#include <opencv2/core/core.hpp>#include <string>#include <vector>
    
    using namespace cv;
    using namespace std;
    
    
    JNIEXPORT jintArray JNICALL Java_my_example_ndkopencv_ImageProc_grayProc(JNIEnv* env, jclass obj, jintArray buf, jint w, jint h){
        jint *cbuf;
        cbuf = env->GetIntArrayElements(buf, 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;
    }

    上面操作完成后,选中工程,右键选择Android tools->add native support...

    Android下OpenCV的环境搭建第13张

    点击“Finish”完成。

    然后选中工程,右键选择properties,在左侧选择C/C++ General->Paths and Symbols.

    Android下OpenCV的环境搭建第14张

    在右侧选择"Add",然后选择File System,选择OpenCV-SDK所在目录下的“nativejniinclude”路径,并选择“ok”:

    Android下OpenCV的环境搭建第15张

    点击“ok”,完成。

    编译和运行程序

    现在运行程序,eclipse会先调用ndk-build对C++程序进行编译,如果你使用的是NDK8以上的版本,当前可能会出现如下信息:

    Android NDK: WARNING:jni/Android.mk:detection_based_tracker: non-system libraries in linker flags: -lopencv_java
    Android NDK: This is likely to result in incorrect builds. Try using LOCAL_S

    这是NDK9目前的问题(当前最新版本是android-ndk-r9d-windows-x86_64),希望在今后能够改进,这也正是我为什么要用NDK8的原因。

    点击“NdkOpenCV”按钮,对比两张图:

    Android下OpenCV的环境搭建第16张Android下OpenCV的环境搭建第17张

    至此,Android下OpenCV的环境搭建已经完成。

    总结

    在此需要说明一下,传统的编译底层C++方法是通过在Cygwin中进行的,由于新版ADT和NDK给我们带来的便捷,我们可以不安装Cygwin进行android下的openCV开发。如果你想了解Cygwin下编译上述程序的方法,我会在今后的博客中为大家介绍。

免责声明:文章转载自《Android下OpenCV的环境搭建》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇【Unity3D入门教程】Unity着色器基本使用方法一文入门富文本编辑器下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

pkg-config 用法

在进行使用fuse 2.9写程序的时候,遇到了pkg-config 命令和 .pc 文件。本篇博客就具体说明一下pkg-config 命令是什么? 我们首先看一下: gcc -Wall hello.c `pkg-config fuse3 --cflags --libs` -o hello [root@docker pkgconfig]# cat fuse....

DISPLAY变量和xhost(原创)

DISPLAY 在Linux/Unix类操作系统上, DISPLAY用来设置将图形显示到何处. 直接登陆图形界面或者登陆命令行界面后使用startx启动图形, DISPLAY环境变量将自动设置为:0:0, 此时可以打开终端, 输出图形程序的名称(比如xclock)来启动程序, 图形将显示在本地窗口上, 在终端上输入printenv查看当前环境变量, 输出结...

python环境搭建

目录 python安装 配置python环境变量 pycharm安装 pycharm使用 python安装 打开官网:http://www.python.org,点击Downloads下载,如下图 进入python版本下载页面,选择对应版本以及电脑位数进行下载,如下图(红色为windows64位,蓝色为Windows32位) 下载完成,双...

如何使用 Secret?- 每天5分钟玩转 Docker 容器技术(108)

我们经常要向容器传递敏感信息,最常见的莫过于密码了。比如: docker run -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql 在启动 MySQL 容器时我们通过环境变量 MYSQL_ROOT_PASSWORD 设置了 MySQL 的管理员密码。不过密码是以明文的形式写在 docker run 命令中,有潜在的安...

Python下opencv库的安装过程与一些问题汇总

本文主要内容是python下opencv库的安装过程,涉及我在安装时遇到的问题,并且,将从网上搜集并试用的一些解决方案进行了简单的汇总,记录下来。 由于记录的是我第一次安装opencv库的过程,所以内容涵盖可能不全面,如果有出错的地方请务必指正。下面进入主题。 关于python的下载安装不再赘述,python的版本号是我们在opencv库的安装过程中需要用...

Android开发-Android Studio问题以及解决记录

[Android开发] Android Studio问题以及解决记录 http://blog.csdn.net/niubitianping/article/details/51400721 1、真机运行报错Multi dex requires Build Tools 21.0.0 / Current: 19.1 解决: 在项目 build.gradle 里...