目录(?)[-]

  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. Jquery和其他库($的好处)

    ---很多时候我们的页面 会使用很多的 javascript库 ---而这个时候  jQuery这款重点在满足社区用户的需求的工具  做好了让jQuery在页面上与其他库和平共处的准备 凭借名副其实的 ...

  2. Python笔记-第一天

    1.Python的输出print函数要把输出的字符串用单引号或者双引号括起来,但是不能混用. 比如print('hello,world')和print("hello,world") ...

  3. .net core 关键概念

    startup       startup asp.net core 的入口,在构造函数中完成环境参数的配置. 其中Configure 方法是用来控制如何respond一个http请求的, 例如配置l ...

  4. c#内部类的使用

    using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...

  5. JavaBean对象与Map对象互相转化

    /** * 使用org.apache.commons.beanutils进行转换 */ class A { public static Object mapToObject(Map<String ...

  6. 阿里云SLB双机IIS多站点负载均衡部署笔记

    首先SLB是通过局域网与ECS链接 ECS1服务器 test文件夹增加index.html test1文件夹增加index.html 设置ECS1服务器(130)IIS test站点 设置test主机 ...

  7. iOS文档注释

    Eclipse和IntelliJ IDEA系的IDE都有自动生成文档注释的功能,Xcode虽然安装了VVDocument,但是仍然感觉注释的功能不是很完善,于是今天整理了一下书写文档注释的一些用法. ...

  8. R爬虫知识点

    >>如何用 R 模仿浏览器的行为? GET / POST URLencode / URLdecode (破解中文網址的祕密) header & cookie 如何突破使用 cook ...

  9. *HDU1142 最短路+记忆化dfs

    A Walk Through the Forest Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Jav ...

  10. 【emWin】例程五:显示数值

    实验指导书及代码包下载: 链接:http://pan.baidu.com/s/1pLexsAf密码:p0jf 实验现象: