您的位置:首页 > 移动开发 > Android开发

opencv for android 教程(环境搭建篇)

2016-04-18 15:45 671 查看

前言:

转载出处:http://blog.csdn.net/pwh0996/article/details/8957764

最近android开发异常火热,随着手机性能越来越高,图像处程序也越来越重要,

由于opencv for android 网上教程大多为英文文档,中文教程都为零星篇章,

很少有完整的opencv for android 教程

博主最近正在学习opencv for android 其中走了很多弯路

所以将一些经验写下 帮助大家少走弯路!

只适合初学者 请大神指正,或者绕道吧,走好不送!

注意本文只负责环境的搭建 不负责讲解

按照文章来确保能搭建一个完美的opencv for android 的开发环境

但是具体的理解 需要读者自己尝试和摸索!

准备工具:

win7/win8 环境我是win8环境
java SDK 6 / 7 我是用的6
eclipse for java EE IED我是32位版
ADT插件
CDT插件
Android SDK
Android NDK我的是r8版
cygwin
Sequoyah
opencv for android我用的是2.4.5



android环境搭建:

参考1:点击打开链接

java SDK安装:

如果你还没有JDK的话,可以去这里下载,接下来的工作就是安装提示一步一步走。设置环境变量步骤如下:

我的电脑->属性->高级->环境变量->系统变量中添加以下环境变量:
JAVA_HOME值为: D:\Program Files\Java\jdk1.6.0_18(你安装JDK的目录
CLASSPATH值为:.;%JAVA_HOME%\lib\tools.jar;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\bin;
Path: 在开始追加 %JAVA_HOME%\bin;
NOTE:前面四步设置环境变量对搭建Android开发环境不是必须的,可以跳过。

安装完成之后,可以在检查JDK是否安装成功。打开cmd窗口,输入java –version 查看JDK的版本信息。出现类似下面的画面表示安装成功了:



eclipse 安装:

1.下载

2.解压到任意目录

3.去目录启动

4.设置工作路径

5.安装完成

Android SDK安装:

在Android Developers下载android-sdk_r05-windows.zip,下载完成后解压到任意路径。

运行SDK Setup.exe,点击Available Packages。如果没有出现可安装的包,请点击Settings,选中Misc中的"Force https://..."这项,再点击Available Packages 。
选择希望安装的SDK及其文档或者其它包,点击Installation Selected、Accept All、Install Accepted,开始下载安装所选包
在用户变量中新建PATH值为:Android SDK中的tools绝对路径(本机为D:\AndroidDevelop\android-sdk-windows\tools)。



进入cmd命令窗口,检查SDK是不是安装成功。

运行 android –h 如果有类似以下的输出,表明安装成功:



ADT插件安装:

ADT是专门给eclipse开发android的插件

打开 Eclipse IDE,进入菜单中的 "Help" -> "Install New Software"
点击Add...按钮,弹出对话框要求输入Name和Location:Name自己随便取,Location输入http://dl-ssl.google.com/android/eclipse。如下图所示:



确定返回后,在work
with后的下拉列表中选择我们刚才添加的ADT,我们会看到下面出有Developer Tools,展开它会有Android DDMS和Android Development Tool,勾选他们。 如下图所示:



然后就是按提示一步一步next。

完成之后:

选择Window > Preferences...
在左边的面板选择Android,然后在右侧点击Browse...并选中SDK路径,本机为:

D:\AndroidDevelop\android-sdk-windows
点击Apply、OK。配置完成。

创建android AVD模拟器:

android AVD模拟器是一个android的虚拟机用来在pc机上调试android程序用的!
至于如何创建 这里就不说了 因为我使用真机调试所以没有用这个

以上 android 的开发环境就搭建完毕了 如果有任何问题请自行google,这个资料太多了!
总会有一个适合你

NDK + Cygwin 环境搭建:

参考1:点击打开链接
参考2:点击打开链接

安装Android NDK:

1.下载Android NDK 我下载的是 r10版本 地址就不给除了 自己google吧,现在ndk安装很简单,不需要很复杂,自行百度!
使用ndk开发参考链接:http://www.2cto.com/kf/201504/388149.html

opecnv for android 开发环境搭建:

参考1:点击打开链接
参考2:点击打开链接

opencv for android SDK 安装:

进入官网(http://opencv.org/)下载OpenCV4Android并解压,其目录结构如下:





其中,sdk目录即是我们开发opencv所需要的类库;samples目录中存放着若干opencv应用示例(包括人脸检测等),可为我们进行android下的opencv开发提供参考;doc目录为opencv类库的使用说明及api文档等;而apk目录则存放着对应于各内核版本的OpenCV_2.4.3.2_Manager_2.4应用安装包。此应用用来管理手机设备中的opencv类库,在运行opencv应用之前,必须确保手机中已经安装了OpenCV_2.4.3.2_Manager_2.4_*.apk,否则opencv应用将会因为无法加载opencv类库而无法运行。

2.2 将SDK引入工作空间

(1) 选择一个路径,新建文件夹做为工作空间(我在E盘根目录下新建workspace目录来做为工作空间);

(2) 将OpenCV-2.4.3.2-android-sdk中的sdk目录copy至工作空间,并将其更名为OpenCV-SDK(是否更改名称无所谓,这是我个人习惯而已);

(3) 以新建的目录为工作空间,打开eclipse;

(4) 将OpenCV-SDK引入到工作空间中,如下图所示:









使用java API开发android:



创建工程

(1) 打开eclipse,创建android应用工程GrayProcess;

(2) 将测试图像lena.jpg添加到资源目录res/drawable-hdpi中;

(3) 在Package Explorer中选择项目GrayProcess,单击右键在弹出菜单中选择Properties,然后在弹出的Properties窗口中左侧选择Android,然后点击右下方的Add按钮,选择OpenCV Library 2.4.3并点击OK,操作完成后,会将OpenCV类库添加到GrayProcess的Android Dependencies中,如下图所示:









工程代码:

(1) 字符串资源文件:strings.xml

[html] view
plain copy







<resources>

<string name="app_name">GrayProcess</string>

<string name="hello_world">Hello world!</string>

<string name="menu_settings">Settings</string>

<string name="title_activity_main">MainActivity</string>

<string name="str_proc">gray process</string>

<string name="str_desc">image description</string>

</resources>

(2) 布局文件:main.xml

[html] view
plain copy







<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_gray_process"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="@string/str_proc"/>

<ImageView

android:id="@+id/image_view"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:contentDescription="@string/str_proc"/>

</LinearLayout>

(3) MainActivity.java

[java] view
plain copy







package com.iron.grayprocess;

import org.opencv.android.BaseLoaderCallback;

import org.opencv.android.LoaderCallbackInterface;

import org.opencv.android.OpenCVLoader;

import org.opencv.android.Utils;

import org.opencv.core.Mat;

import org.opencv.imgproc.Imgproc;

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:{

} break;

default:{

super.onManagerConnected(status);

} break;

}

}

};

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

btnProc = (Button) findViewById(R.id.btn_gray_process);

imageView = (ImageView) findViewById(R.id.image_view);

//将lena图像加载程序中并进行显示

bmp = BitmapFactory.decodeResource(getResources(), R.drawable.lena);

imageView.setImageBitmap(bmp);

btnProc.setOnClickListener(this);

}

@Override

public void onClick(View v) {

Mat rgbMat = new Mat();

Mat grayMat = new Mat();

//获取lena彩色图像所对应的像素数据

Utils.bitmapToMat(bmp, rgbMat);

//将彩色图像数据转换为灰度图像数据并存储到grayMat中

Imgproc.cvtColor(rgbMat, grayMat, Imgproc.COLOR_RGB2GRAY);

//创建一个灰度图像

Bitmap grayBmp = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), Config.RGB_565);

//将矩阵grayMat转换为灰度图像

Utils.matToBitmap(grayMat, grayBmp);

imageView.setImageBitmap(grayBmp);

}

@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);

}

}

3.1.3 运行结果







使用 c++ API开发android:

创建工程

步骤如工程一,创建新工程GrayProcess2,将lena.jpg添加到资源文件,并按上面所示将opencv类库添加到工程中。

编写上层代码(java)

(1)Stings.xml

[html] view
plain copy







<resources>

<string name="app_name">GrayProcess2</string>

<string name="hello_world">Hello world!</string>

<string name="menu_settings">Settings</string>

<string name="title_activity_main">GrayProcess2</string>

<string name="str_proc">gray process</string>

<string name="str_desc">image description</string>

</resources>

(2)main.xml

[html] view
plain copy







<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_gray_process"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="@string/str_proc"/>

<ImageView

android:id="@+id/image_view"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:contentDescription="@string/str_proc"/>

</LinearLayout>

(3)MainActivity.java

[java] view
plain copy







package com.iron.grayprocess2;

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.main);

btnProc = (Button) findViewById(R.id.btn_gray_process);

imageView = (ImageView) findViewById(R.id.image_view);

//将lena图像加载程序中并进行显示

bmp = BitmapFactory.decodeResource(getResources(), R.drawable.lena);

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类库,所谓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
plain copy







package com.iron.grayprocess2;

public class ImageProc {

public static native int[] grayProc(int[] pixels, int w, int h);

}

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

编写JNI及C相关代码

在项目中新建目录jni,在jni目录中分别添加文件Android.mk,Application.mk,ImageProc.h,ImageProc.cpp,这四个文件的内容分别如下所示。

(1) Android.mk

[plain] view
plain copy







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++源文件;

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

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

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

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

[plain] view
plain copy







APP_STL := gnustl_static

APP_CPPFLAGS := -frtti -fexceptions

APP_ABI := armeabi-v7a

APP_PLATFORM := android-8

(3)ImageProc.cpp

[cpp] view
plain copy







#include <ImageProc.h>

#include <opencv2/core/core.hpp>

#include <string>

#include <vector>

using namespace cv;

using namespace std;

JNIEXPORT jintArray JNICALL Java_com_iron_grayprocess2_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;

}

说明:

[align=left] ImageProc.h头文件可以通过jdk提供的工具javah来生成,具体生成方法在下面[/align]

[align=left] JNI中的定义的函数遵循一定的命名规则:Java_包名_类名_方法名,具体参考JNI编程相关知识;[/align]

[align=left] ImageProc.cpp中利用彩色值转换为灰度值的计算公式,将lena.jpg图像的每个像素转换为灰度值,并返回给应用层。需要注意的是对于ARGB_8888类型的图像而言,其每一个像素值在int型数据中的存储序列为BGRA。[/align]
[align=left]还需要注ImageProc.cpp 这个文件 第10行的函数名称Java_包名_类名_方法名 请修改成.h 文件生成的那个函数名 [/align]

生成.h 文件

1.首先当年写完ImageProc.java 这个保存 以后 eclipse会自动帮你生成 java 的class文件

你可以再工程目录--》 bin --》classes -》com -------。。。。。 的文件里找到

比如我的 在E:\work\op\OpenCV-2.4.5-android-sdk\samples\Test2\bin\classes\com\test2\test2 这个路径下

如图


2.将classes文件拷贝到e盘根目录下

然后打开 cmd

e:

cd classes

javah com.test2.test2.ImageProc

然后就会在classes文件里找到一个 xxx.的头文件 如图



你可以将这个头文件改成任意名字 比如我们上面的ImageProc.h 然后放入工程目录的jni中

编译运行方法有两种

1 配置eclipse自动运行

第一步:转换工程。点击“文件 -> 新建 -> 其他”(快捷键:Ctrl+N)。选择“C/C++”下的“Convert to a C/C++ Project(Adds C/C++ Nature)”。进 入“下一步”。



第二步:选中你刚才建的“HelloJni”工程,下面左边选“Makefile project”右边选“Cygwin GCC”。确定后提示的“透视图”不清楚是什么,点击“是”即可。



第三步:在“HelloJni”工程上右键,选择“属性”。配置“C/C++ Build”和“C/C++ General -> Paths and Symbols”。

C/C++ Build:点击“C/C++ Build”,在右边的“Builder Settings”中去掉默认勾选的“Use default build command”复选框。设置Build command为“

${NDKROOT}/ndk-build.cmd "



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



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

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

配置好后运行就行了

2.手动使用Cygwin 生成os 然后运行
由于程序中涉及到了JNI编程,因此需要用cygwin对其中的C/C++代码进行编译。打开cygwin,进入到工程的根目录中执行命令:$NDKROOT/ndk-build完成相关编译;之后在eclipse中刷新工程GrayProcess2,运行即可。编译及运行结果分别如下所示。







到这里两种方法都结束了!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: