目录(?)[-]

  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:\MySoftware\adt-bundle-windows-x86_64-20131030\sdk",如图:

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

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

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

    Android NDK的安装与配置

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

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

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

    OpenCV for Android 环境搭建

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

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

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

    点击“Finish”完成。

    基于SDK的OpenCV开发

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

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

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

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

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

    选中OpenCV Library,点击OK

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

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

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

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

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

    你可以使用真机或模拟器运行运行该程序,这是个基于openCV的摄像头调用程序。需要注意的是,在运行前你需要安装OpenCV_***_Manager_**_*.apk,否则opencv应用将会因为无法加载opencv类库而无法运行。OpenCV_***_Manager_**_*.apk存在于...\OpenCV-***-android-sdk\apk(我的是D:\MySoftware\OpenCV-2.4.8-android-sdk\apk)目录下。我安装的是“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命令:

    在F:\MyCode\android\NdkOpenCV\bin\classes目录下多了个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...

    点击“Finish”完成。

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

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

    点击“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的环境搭建已经完成。

    总结

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

Android下OpenCV的环境搭建的更多相关文章

  1. Android下NDK开发环境搭建

    Android下NDK开发环境搭建 1.     AndroidNDK安装与配置 1.1  NDK简介 Android NDK是一套允许开发人员使用本地代码(如C/C++)进行Android APP部 ...

  2. OpenCV学习系列(零) Mac下OpenCV + xcode环境搭建

    # OpenCV学习系列(零) Mac下OpenCV + xcode环境搭建 [-= 博客目录 =-] 1-学习目标 1.1-本章介绍 1.2-实践内容 1.3-相关说明 2-学习过程 2.1-hom ...

  3. Android For OpenCV的环境搭建

    OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,可以运行在Linux.Windows.Android和Mac OS操作系统上.它轻量级而且高效--由一系列 C 函数和少量 C++ 类 ...

  4. Linux下OpenCV的环境搭建

    OpenCV is the most popular and advanced code library for Computer Vision related applications today, ...

  5. Linux下OpenCV的环境搭建(转)

    OpenCV is the most popular and advanced code library for Computer Vision related applications today, ...

  6. Android NDK r8 windows环境搭建

    Android NDK r8 windows环境搭建 一.默认基础环境为已经完成Android开发环境的搭建 需要的软件及插件 1. JDK-7u25 2. Eclipse 3. Android SD ...

  7. android 5.0开发环境搭建

    Android 5.0 是 Google 于 2014 年 10 月 15 日发布的全新 Android 操作系统.本文将就最新的Android 5.0 开发环境搭建做详细介绍. 工具/原料 jdk- ...

  8. Mac系统下STF的环境搭建和运行

    本文参考以下文章整理:MAC 下 STF 的环境搭建和运行 一. 前言 STF,全称是Smartphone Test Farm,WEB 端批量移动设备管理控制工具,就是可以用浏览器来批量控制你的移动设 ...

  9. NDK在windows下的开发环境搭建及开发过程

    在Android应用的开发工程中,不管是游戏还是普通应用,都时常会用到.so即动态链接库,关于.so是什么玩意儿,有什么好处,这个大家可以在网上查一下,本人不做过多解释..so本是linux下的文件类 ...

随机推荐

  1. Android入门(七):Spinner下拉式菜单组件

    对于手机和平板电脑的应用程序来说,打字是非常不方便的操作方式,比较好的方式就是列出一组选项让用户挑选,这样就可以避免打字的麻烦.使用Spinner下拉菜单组件需要完成以下几个步骤: 1.建立选项列表, ...

  2. python集合

    集合的创建:set()和frozenset() 区别:frozenset()创建不可变的集合,一旦创建其元素不可改变:而set()创建的集合中的元素可以通过一定的方法进行改变. >>> ...

  3. Xcode的清除缓存

    1.在“前往文件夹”中输入“   /Users/用户名/Library/Developer/Xcode/DerivedData  ”,然后删除里面的东西

  4. JS开发HTML5游戏《神奇的六边形》(一)

    近期出现一款魔性的消除类HTML5游戏<神奇的六边形>,今天我们一起来看看如何通过开源免费的青瓷引擎(www.zuoyouxi.com)来实现这款游戏. (点击图片可进入游戏体验) 因内容 ...

  5. 2016huasacm暑假集训训练四 数论_A

    题目链接:http://acm.hust.edu.cn/vjudge/contest/125308#problem/F 题意:狼捉兔子,兔子躲在n个洞中一个,这n个洞围成一个圈,狼会从第0号洞开始,搜 ...

  6. iOS CADisplayLink 定时器的使用

    CADisplayLink 是一个能让我们以和屏幕刷新频率相同的频率将内容刻画到屏幕上的定时器,在应用中创建一个新的CADisplayLink对象,把他添加到一个runloop中,并且给他提供一个ta ...

  7. # 20145205 《Java程序设计》第1周学习总结

    教材学习内容总结 第一章中 JAVA的三大体系:JAVA SE .JAVA EE.JAVA ME.而在其中书中主要介绍我们入门学习者所要学习的JVAA SE,其又可分为四个主要组成部分同Java SE ...

  8. C语言中static的作用

    (1)在函数体内,局部的static变量.生存周期为程序的整个生命周期:作用域却在定义了的函数体内.一个被声明为静态的变量在这个函数被调用过程中维持其值不变.因为它分配在静态存储区域,函数调用结束以后 ...

  9. 2016.10.14,英语,《American Accent Training》

    这本书是讲述美语发音训练的.已经看了一段时间了,决定向周叶学习,记录读书笔记.计划每天花半个小时,学习3节左右的音频(按照CD TRACK),并完成训练. CD1 Track1 What is Acc ...

  10. 关于type erasure

    哇,好久没有写blog了,再不写的话,blog的秘密都要忘记了,嘿嘿. 最近在试着参与一个开源项目,名字叫avim(A Vibrate IM),别想多了哟.地址是:https://github.com ...