目录(?)[-]

  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. Spring Boot下配置MyBatis多数据源

    http://m.blog.csdn.net/article/details?id=51481911

  2. Codeforces 717G Underfail(最小费用最大流 + AC自动机)

    题目 Source http://codeforces.com/problemset/problem/717/G Description You have recently fallen throug ...

  3. Linux学习总结

    1.软链接和硬链接 ln 命令可用来创建硬链接或是符号链接.它的使用方式有两种. ln file link 用来创建硬链接 ln -s item link 用来创建符号链接,这里的item可以是文件也 ...

  4. Ext3文件系统mount选项和文件属性介绍

    mount选项 设置方式 ext3 mount选项可以通过多个方式进行设置:1)内核编译时: 内核menuconfig通过CONFIG_EXT3_DEFAULTS_TO_ORDERED编译控制选项,来 ...

  5. jQuery对数据和对象的操作

    <script type="text/javascript" src="jquery-1.8.2.min.js"></script> & ...

  6. 【转载】Linux 信号列表

    转自:http://blog.csdn.net/muge0913/article/details/7322710 信号及其简介 信号是一种进程通信的方法,他应用于异步事件的处理.信号的实现是一种软中断 ...

  7. React独立组件间通信联动

    React是现在主流的高效的前端框架,其官方文档 http://reactjs.cn/react/docs/getting-started.html 在介绍组件间通信时只给出了父子组件间通信的方法,而 ...

  8. Java WebService 简单实例

    前言:朋友们开始以下教程前,请先看第五大点的注意事项,以避免不必要的重复操作. 一.准备工作(以下为本实例使用工具) 1.MyEclipse10.7.1 2.JDK 1.6.0_22 二.创建服务端 ...

  9. springMVC、https、GET调用别人提供的接口!!!

    import org.apache.http.HttpEntity; import org.apache.http.HttpHost; import org.apache.http.HttpStatu ...

  10. 微博mid和id转换

    mid为62进制编码,id为常见的10进制编码. id从低位到高位,7个数字为一组,转换为62进制,并顺序合并,即转换为mid. mid从地位到高位,4个字母为一组,转换为10进制,并右移7位,计算和 ...