如何在Android中使用OpenCV

作者&投稿:都荀 (若有异议请与网页底部的电邮联系)
如何在Android中使用OpenCV~

在Android中使用OpenCV方法为:
a、OpenCV安装路径"F:\OpenCV-2.3.1-android-bin"下有两个文件夹。将文件夹"OpenCV-2.3.1"拷贝到Eclipse工作空间所在的目录,也就是在你的项目的上一级目录中,然后导入到工作空间中,在Package Explorer中选择项目,单机右键在弹出菜单中选择Properties,然后在弹出的Properties窗口中左侧选择Android,然后点击右下方的Add按钮,选择OpenCV-2.3.1并点击OK,。
b、此时,展开项目树,可以看到新加了一个OpenCV-2.3.1_src目录,如下图,那么就是正确添加了OpenCV Java API,否则就是放置OpenCV-2.3.1的目录路径不正确。
c、然后就可以在Java源文件中导入OpenCV的API包,并且使用OpenCV API了,OpenCV API的包的形式如下:
Org.opencv.(OpenCV模块名).(OpenCV类名)
例如:
Org.opencv.core.Mat

1、下载
进入官网下载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类库而无法运行(下篇文章会介绍不提前安装openCV Manager,即可运行openCV的方法)。
2、将OpenCV引入Android Studio
在Android Studio中选择File->Import Module,找到OpenCV解压的路径,选择sdk/java文件夹。

3、更新build.gradle信息
在Android Studio中的左上角选择Project视图,在oepnCVLibrary2411文件夹里,打开build.gradle(有很多重名的文件,一定找对openCV库文件下的),修改文件中的1)compileSdkVersion 2)buildToolsVersion 3) minSdkVersion 4)targetSdkVersion,将其内容与app文件夹下的build.gradle中信息相一致。点击上方提示的黄色提示框内的Try Again进行更新。
4、添加Module Dependency
右键app文件夹,选择Open Module Settings,在app module的Dependencies一栏中,点击右上角的绿色加号,将openCVLibrary2411添加进去,点击确定。

5、复制libs文件夹到项目中
在OpenCV的解压包中,将sdk-->native-->libs文件夹复制,粘贴在Project视图下app-->src-->main目录下,并将其重命名为jniLibs。
自此,OpenCV的环境就配置好了。可以将OpenCV-android-sdk-->samples-->tutorial-1-camerapreview中的layout文件,java文件,放入工程中,修改AndroidManifest.xml,添加使用摄像机的权限,即可测试是否成功了。

如何在Android程序中使用OpenCV

有两种方式(重点讲后面一种):

1.使用OpenCV Java API。

OpenCV安装路径"F:\OpenCV-2.3.1-android-bin"下有两个文件夹,


将文件夹"OpenCV-2.3.1"拷贝到你的Eclipse工作空间所在的目录,也就是在你的项目的上一级目录中,然后导入到工作空间中,在Package Explorer中选择你的项目,单机右键在弹出菜单中选择Properties,然后在弹出的Properties窗口中左侧选择Android,然后点击右下方的Add按钮,选择OpenCV-2.3.1并点击OK,


此时,展开你的项目树,你可以看到新加了一个OpenCV-2.3.1_src目录,如下图,那么就是正确添加了OpenCV Java API,否则就是你放置OpenCV-2.3.1的目录路径不正确。


然后就可以在你的Java源文件中导入OpenCV的API包,并且使用OpenCV API了,OpenCV API的包的形式如下:

Org.opencv.(OpenCV模块名).(OpenCV类名)

例如:

Org.opencv.core.Mat

2.利用JNI编写C++ OpenCV代码,通过Android NDK创建动态库(.so)

新建一个工作空间,例如"TestOpenCV",在Window->Preferences中设置好Android SDK的路径。


然后新建一个Android项目,Build Target选择Android2.2,命名为"HaveImgFun",活动名改为HaveImgFun,Package name中填写com.testopencv.haveimgfun,最后点击finish。

如同使用OpenCV Java API那样,将OpenCV-2.3.1文件夹拷贝到与工作空间同一级目录中;另外,将"F:\OpenCV-2.3.1-android-bin\samples"下的includeOpenCV.mk文件拷贝到和项目HaveImgFun同一级目录中:


(上面这个各个文件夹和文件的放置很重要,因为OpenCV-2.3.1下的OpenCV.mk中有很多相对路径的指定,如果不是这样放置,在NDK生成动态库时可能会报文件或文件夹无法找到的错误)

选择Package Explorer中你的项目,右键选择new->folder,新建一个名为jni的文件夹,用来存放你的c/c++代码。

然后把res->layout下的main.xml的内容改为下面所示:


1 <?xml version="1.0" encoding="utf-8"?> 
2     <LinearLayout   xmlns:android="http://schemas.android.com/apk/res/android" 
3      android:orientation="vertical" 
4      android:layout_width="fill_parent"  
5      android:layout_height="fill_parent" 
6     > 
7     <Button android:layout_height="wrap_content"  
8         android:layout_width="fill_parent"  
9         android:id="@+id/btnNDK"  
10         android:text="使用C++ OpenCV进行处理" /> 
11     <Button android:layout_height="wrap_content"  
12         android:layout_width="fill_parent"  
13         android:id="@+id/btnRestore"  
14         android:text="还原" />  
15     <ImageView android:id="@+id/ImageView01"  
16     android:layout_width="fill_parent"  
17     android:layout_height="fill_parent" />       
18 </LinearLayout>


上面的代码就是一个线性布局里面包含2个按钮加上一个显示图像的ImageView

在文件夹src下的com.testopencv.haveimgfun包中新建一个类用于包装使用了opencv c++代码的动态库的导出函数,类名为LibImgFun。

Eclipse会为你创建一个新的文件LibImgFun.java,将里面的内容改为:


1 package com.testopencv.haveimgfun; 
2 public class LibImgFun {  
3 static {   
4         System.loadLibrary("ImgFun");   
5        }   
6       /** 
7             * @param width the current view width 
8             * @param height the current view height 
9 */ 
10     public static native int[] ImgFun(int[] buf, int w, int h);  
11 }


从上面的代码可以得知,我们的动态库名字应该为“libImgFun.so”,注意"public static native int[] ImgFun(int[] buf, int w, int h)"中的native关键字,表明这个函数来自native code。static表示这是一个静态函数,这样就可以直接用类名去调用。

在jni文件夹下建立一个"ImgFun.cpp"的文件,内容改为下面所示:


1 #include <jni.h> 
2 #include <stdio.h> 
3 #include <stdlib.h> 
4 #include <opencv2/opencv.hpp> 
5 using namespace cv;
6  
7 extern "C"
8 { 
9     JNIEXPORT jintArray JNICALL Java_com_testopencv_haveimgfun_LibImgFun_ImgFun(JNIEnv* env, jobject obj, jintArray buf, int w, int h); 
10     JNIEXPORT jintArray JNICALL Java_com_testopencv_haveimgfun_LibImgFun_ImgFun(JNIEnv* env, jobject obj, jintArray buf, int w, int h){ 
11  
12     jint *cbuf; 
13     cbuf = env->GetIntArrayElements(buf, false); 
14     if(cbuf == NULL) 
15     { 
16         return 0; 
17     } 
18  
19     Mat myimg(h, w, CV_8UC4, (unsigned char*)cbuf);  
20     for(int j=0;j<myimg.rows/2;j++) 
21     { 
22         myimg.row(j).setTo(Scalar(0,0,0,0)); 
23     } 
24  
25     int size=w * h; 
26     jintArray result = env->NewIntArray(size); 
27     env->SetIntArrayRegion(result, 0, size, cbuf); 
28     env->ReleaseIntArrayElements(buf, cbuf, 0); 
29     return result; 
30     } 
31 }


上面的代码中#include <jni.h>是必须要包含的头文件,#include <opencv2/opencv.hpp>是opencv要包含的头文件。

动态库要导出的函数如下声明:

JNIEXPORT jintArray JNICALL Java_com_testopencv_haveimgfun_LibImgFun_ImgFun(JNIEnv* env, jobject obj, jintArray buf, int w, int h);

JNIEXPORT 和JNICALL是必须要加的关键字

jintArray就是int[],这里返回类型要么为空,要么为jni中定义的类型,事实上就是C\C++类型前面加上j,如果是数组,则在后面加上Array。

函数名的命名规则如下:

Java_(包路径)_(类名)_(函数名) (JNIEnv *env, jobject obj, 自己定义的参数...)

包路径中的"."用"_"(下划线)代替,类名就是上面包装该动态库函数的类的名字,最后一个才是真正的函数名;JNIEnv *env和jobject obj这两个参数时必须的,用来调用JNI环境下的一些函数;后面就是你自己定义的参数。在这里,jintArray buf代表了传进来的图像的数据,int w是图像的宽,int h是图像的高。

这个函数的功能是将传进来的图像的上半部分涂成黑色。

然后再在jni下新建两个文件"Android.mk"文件和"Application.mk"文件,这两个文件事实上就是简单的Makefile文件。

其中将Android.mk的内容改为如下所示:

LOCAL_PATH := $(call my-dir)  

include $(CLEAR_VARS)  

include ../includeOpenCV.mk  

ifeq ("$(wildcard $(OPENCV_MK_PATH))","")  

#try to load OpenCV.mk from default install location  

include $(TOOLCHAIN_PREBUILT_ROOT)/user/share/OpenCV/OpenCV.mk  

else  

include $(OPENCV_MK_PATH)  

endif  

LOCAL_MODULE    := ImgFun  

LOCAL_SRC_FILES := ImgFun.cpp  

include $(BUILD_SHARED_LIBRARY) 

Application.mk的内容改为如下所示:

APP_STL:=gnustl_static  

APP_CPPFLAGS:=-frtti -fexceptions  

APP_ABI:=armeabi armeabi-v7a 

其中APP_ABI指定的是目标平台的CPU架构。(经过很多测试,android2.2必须指定为armeabi,android2.2以上的使用armeabi-v7a,如果没有设置对,很有可能安装到android虚拟机失败,当然你同时如上面写上也是可以的)

上面的步骤完成后,就可以使用NDK生成动态库了,打开cygwin,cd到项目目录下:


输入$NDK/ndk-build命令,开始创建动态库。


这时候刷新Eclipse的Package Explorer会出现两个新的文件夹obj和libs。

现在,只剩最后一步完成这个测试程序。

将一张图片,例如"lena.jpg"放到项目res->drawable-hdpi目录中并刷新该目录。

然后将HaveImgFun.java的内容改为下面所示:


1 package com.testopencv.haveimgfun; 
2  
3 import android.app.Activity;  
4 import android.graphics.Bitmap;   
5 import android.graphics.Bitmap.Config;   
6 import android.graphics.drawable.BitmapDrawable;   
7 import android.os.Bundle;   
8 import android.widget.Button;  
9 import android.view.View;   
10 import android.widget.ImageView;  
11  
12 public class HaveImgFun extends Activity{ 
13 /** Called when the activity is first created. */  
14 ImageView imgView;  
15 Button btnNDK, btnRestore; 
16  
17 @Override  
18 public void onCreate(Bundle savedInstanceState) {  
19     super.onCreate(savedInstanceState);   
20         setContentView(R.layout.main);  
21  
22     this.setTitle("使用NDK转换灰度图");   
23     btnRestore=(Button)this.findViewById(R.id.btnRestore);   
24     btnRestore.setOnClickListener(new ClickEvent());   
25     btnNDK=(Button)this.findViewById(R.id.btnNDK);   
26     btnNDK.setOnClickListener(new ClickEvent());   
27     imgView=(ImageView)this.findViewById(R.id.ImageView01);  
28         Bitmap img=((BitmapDrawable) getResources().getDrawable(R.drawable.lena)).getBitmap();  
29     imgView.setImageBitmap(img);  
30 } 
31  
32 class ClickEvent implements View.OnClickListener{  
33     public void onClick(View v){ 
34         if(v == btnNDK){
35             long current=System.currentTimeMillis();   
36             Bitmap img1=((BitmapDrawable) getResources().getDrawable(R.drawable.lena)).getBitmap();   
37             int w=img1.getWidth(),h=img1.getHeight();   
38             int[] pix = new int[w * h];   
39             img1.getPixels(pix, 0, w, 0, 0, w, h);   
40             int[] resultInt=LibImgFun.ImgFun(pix, w, h);   
41             Bitmap resultImg=Bitmap.createBitmap(w, h, Config.RGB_565);   
42             resultImg.setPixels(resultInt, 0, w, 0, 0,w, h);   
43             long performance=System.currentTimeMillis()-current;   
44             imgView.setImageBitmap(resultImg);   
45             HaveImgFun.this.setTitle("w:"+String.valueOf(img1.getWidth())+",h:"+String.valueOf(img1.getHeight())+"NDK耗时"+String.valueOf(performance)+" 毫秒"); 
46         } else if(v == btnRestore){  
47                 Bitmap img2=((BitmapDrawable) getResources().getDrawable(R.drawable.lena)).getBitmap();  
48                imgView.setImageBitmap(img2);  
49                 HaveImgFun.this.setTitle("使用OpenCV进行图像处理");
50         } 
51      }
52    } 
53 }


点击全部保存,OK,现在可以选择一个Android虚拟机运行看一下效果,配置好Run Configuration然后点击Run,得到下面的结果:

点击使用C++ OpenCV进行处理,得到下面的结果:



看了网上的很多教程和官方http://opencv.willowgarage.com/wiki/Android提供的如何在Android上使用OpenCV的教程,照着一步一步的做最后总有些问题,不是APK安装失败就是运行时突然报错退出。和同学一起摸索了一段时间后,终于弄成功,在这里做一个总结。最关键的问题是项目中各个文件夹和文件的位置要放置正确,而且目标机器的CPU架构要设置正确,下面是配置的详细过程。

一、Android开发环境
1.Sun JDK 6
访问http://www.oracle.com/technetwork/java/javase/downloads/index.html这里并且安装好JDK
注意:不要使用OpenJDK,Android SDK支持Sun JDK
2.Android SDK
访问http://developer.android.com/sdk/index.html获取android sdk,如果选择的是Windows安装文件,则你还需要安装32bit JRE。
3.Android SDK组件
l Android SDK Tools, revision 12或者更新
l SDK平台Android 2.2, API 8, revision 2(also known as Java API)
这是OpenCV Java API支持的最低平台,OpenCV发布默认为Android 2.2
4. Eclipse IDE和ADT plugin for Eclipse
访问http://www.eclipse.org/downloads/下载Eclipse并解压即可。
打开Eclipse,选择Help->Install New Software菜单,但后点击Add按钮,在Add Repository对话框中的Name一栏输入"ADT Plugin",Location一栏输入https://dl-ssl.google.com/android/eclipse/,但后点击OK。在Available Software对话框中选中所有单选框,然后一路next直到finish为止,当安装ADT完毕后重启Eclipse即可。
5. Android NDK
访问http://developer.android.com/sdk/ndk/index.html 下载最新的Android NDK,是一个ZIP解压包,只需解压到某个路径即可,例如"F:\android-ndk-r6b-windows\android-ndk-r6b",再把这个路径添加到系统的环境变量PATH中。
6. Cygwin
访问http://cygwin.com/index.html下载最新的Cygwin,最好安装全部的Cygwin组件。假设安装在"C:\cygwin"下,将"C:\cygwin\bin"添加到系统环境变量PATH中,为了方便的在命令行下调用Android NDK,找到"C:\cygwin\home\(你的用户名)"这个目录,打开文件".bash_profile",在文件的最下面加上下面两行内容:
NDK=/cygdrive/f/android-ndk-r6b-windows/android-ndk-r6b
export NDK
这样便可以在命令行中以 "$NDK/ndk-build" 这种形式调用NDK了。
二、OpenCV
1.首先下载在http://sourceforge.net/projects/opencvlibrary/files/opencv-android/2.3.1/ 已经预编译好的opencv包。
2.把下载好的包解压到某个路径上(最好不要带空格),例如"F:\OpenCV-2.3.1-android-bin"
三、如何在Android程序中使用OpenCV
有两种方式(重点讲后面一种):
1.使用OpenCV Java API。
OpenCV安装路径"F:\OpenCV-2.3.1-android-bin"下有两个文件夹,如下图

将文件夹"OpenCV-2.3.1"拷贝到你的Eclipse工作空间所在的目录,也就是在你的项目的上一级目录中,然后导入到工作空间中,在Package Explorer中选择你的项目,单机右键在弹出菜单中选择Properties,然后在弹出的Properties窗口中左侧选择Android,然后点击右下方的Add按钮,选择OpenCV-2.3.1并点击OK,如下图:

此时,展开你的项目树,你可以看到新加了一个OpenCV-2.3.1_src目录,如下图,那么就是正确添加了OpenCV Java API,否则就是你放置OpenCV-2.3.1的目录路径不正确。

然后就可以在你的Java源文件中导入OpenCV的API包,并且使用OpenCV API了,OpenCV API的包的形式如下:
Org.opencv.(OpenCV模块名).(OpenCV类名)
例如:
Org.opencv.core.Mat
2.利用JNI编写C++ OpenCV代码,通过Android NDK创建动态库(.so)
新建一个工作空间,例如"TestOpenCV",在Window->Preferences中设置好Android SDK的路径,如下图所示。

然后新建一个Android项目,Build Target选择Android2.2,命名为"HaveImgFun",活动名改为HaveImgFun,Package name中填写com.testopencv.haveimgfun,最后点击finish。
如同使用OpenCV Java API那样,将OpenCV-2.3.1文件夹拷贝到与工作空间同一级目录中;另外,将"F:\OpenCV-2.3.1-android-bin\samples"下的includeOpenCV.mk文件拷贝到和项目HaveImgFun同一级目录中,如下图所示:

(上面这个各个文件夹和文件的放置很重要,因为OpenCV-2.3.1下的OpenCV.mk中有很多相对路径的指定,如果不是这样放置,在NDK生成动态库时可能会报文件或文件夹无法找到的错误)
选择Package Explorer中你的项目,右键选择new->folder,新建一个名为jni的文件夹,用来存放你的c/c++代码。
然后把res->layout下的main.xml的内容改为下面所示:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <Button android:layout_height="wrap_content" android:layout_width="fill_parent" android:id="@+id/btnNDK" android:text="使用C++ OpenCV进行处理" /> <Button android:layout_height="wrap_content" android:layout_width="fill_parent" android:id="@+id/btnRestore" android:text="还原" /> <ImageView android:id="@+id/ImageView01" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </LinearLayout>

上面的代码就是一个线性布局里面包含2个按钮加上一个显示图像的ImageView
在文件夹src下的com.testopencv.haveimgfun包中新建一个类用于包装使用了opencv c++代码的动态库的导出函数,类名为LibImgFun。
Eclipse会为你创建一个新的文件LibImgFun.java,将里面的内容改为:
package com.testopencv.haveimgfun; public class LibImgFun { static { System.loadLibrary("ImgFun"); } /** * @param width the current view width * @param height the current view height */ public static native int[] ImgFun(int[] buf, int w, int h); }

从上面的代码可以得知,我们的动态库名字应该为“libImgFun.so”,注意"public static native int[] ImgFun(int[] buf, int w, int h)"中的native关键字,表明这个函数来自native code。static表示这是一个静态函数,这样就可以直接用类名去调用。
在jni文件夹下建立一个"ImgFun.cpp"的文件,内容改为下面所示:
#include <jni.h> #include <stdio.h> #include <stdlib.h> #include <opencv2/opencv.hpp> using namespace cv; extern "C" { JNIEXPORT jintArray JNICALL Java_com_testopencv_haveimgfun_LibImgFun_ImgFun( JNIEnv* env, jobject obj, jintArray buf, int w, int h); JNIEXPORT jintArray JNICALL Java_com_testopencv_haveimgfun_LibImgFun_ImgFun( JNIEnv* env, jobject obj, jintArray buf, int w, int h){ jint *cbuf; cbuf = env->GetIntArrayElements(buf, false); if(cbuf == NULL) { return 0; } Mat myimg(h, w, CV_8UC4, (unsigned char*)cbuf); for(int j=0;j<myimg.rows/2;j++) { myimg.row(j).setTo(Scalar(0,0,0,0)); } int size=w * h; jintArray result = env->NewIntArray(size); env->SetIntArrayRegion(result, 0, size, cbuf); env->ReleaseIntArrayElements(buf, cbuf, 0); return result; } }

上面的代码中#include <jni.h>是必须要包含的头文件,#include <opencv2/opencv.hpp>是opencv要包含的头文件。
动态库要导出的函数如下声明:
JNIEXPORT jintArray JNICALL Java_com_testopencv_haveimgfun_LibImgFun_ImgFun(
JNIEnv* env, jobject obj, jintArray buf, int w, int h);
JNIEXPORT 和JNICALL是必须要加的关键字
jintArray就是int[],这里返回类型要么为空,要么为jni中定义的类型,事实上就是C\C++类型前面加上j,如果是数组,则在后面加上Array。
函数名的命名规则如下:
Java_(包路径)_(类名)_(函数名) (JNIEnv *env, jobject obj, 自己定义的参数...)
包路径中的"."用"_"(下划线)代替,类名就是上面包装该动态库函数的类的名字,最后一个才是真正的函数名;JNIEnv *env和jobject obj这两个参数时必须的,用来调用JNI环境下的一些函数;后面就是你自己定义的参数。在这里,jintArray buf代表了传进来的图像的数据,int w是图像的宽,int h是图像的高。
这个函数的功能是将传进来的图像的上半部分涂成黑色。
然后再在jni下新建两个文件"Android.mk"文件和"Application.mk"文件,这两个文件事实上就是简单的Makefile文件。
其中将Android.mk的内容改为如下所示:
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) include ../includeOpenCV.mk ifeq ("$(wildcard $(OPENCV_MK_PATH))","") #try to load OpenCV.mk from default install location include $(TOOLCHAIN_PREBUILT_ROOT)/user/share/OpenCV/OpenCV.mk else include $(OPENCV_MK_PATH) endif LOCAL_MODULE := ImgFun LOCAL_SRC_FILES := ImgFun.cpp include $(BUILD_SHARED_LIBRARY)

Application.mk的内容改为如下所示:
APP_STL:=gnustl_static APP_CPPFLAGS:=-frtti -fexceptions APP_ABI:=armeabi armeabi-v7a

其中APP_ABI指定的是目标平台的CPU架构。(经过很多测试,android2.2必须指定为armeabi,android2.2以上的使用armeabi-v7a,如果没有设置对,很有可能安装到android虚拟机失败,当然你同时如上面写上也是可以的)
上面的步骤完成后,就可以使用NDK生成动态库了,打开cygwin,cd到项目目录下,如下图所示:

输入$NDK/ndk-build命令,开始创建动态库。成功的话如下图所示。

这时候刷新Eclipse的Package Explorer会出现两个新的文件夹obj和libs。
现在,只剩最后一步完成这个测试程序。
将一张图片,例如"lena.jpg"放到项目res->drawable-hdpi目录中并刷新该目录。
然后将HaveImgFun.java的内容改为下面所示:

package com.testopencv.haveimgfun;

import android.app.Activity;

import android.graphics.Bitmap;

import android.graphics.Bitmap.Config;

import android.graphics.drawable.BitmapDrawable;

import android.os.Bundle;

import android.widget.Button;

import android.view.View;

import android.widget.ImageView;

public class HaveImgFun extends Activity {

/** Called when the activity is first created. */

ImageView imgView;

Button btnNDK, btnRestore;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

this.setTitle("使用NDK转换灰度图");

btnRestore=(Button)this.findViewById(R.id.btnRestore);

btnRestore.setOnClickListener(new ClickEvent());

btnNDK=(Button)this.findViewById(R.id.btnNDK);

btnNDK.setOnClickListener(new ClickEvent());

imgView=(ImageView)this.findViewById(R.id.ImageView01);

Bitmap img=((BitmapDrawable) getResources().getDrawable(R.drawable.lena)).getBitmap();

imgView.setImageBitmap(img);

}

class ClickEvent implements View.OnClickListener{

public void onClick(View v){

if(v == btnNDK)

{

long current=System.currentTimeMillis();

Bitmap img1=((BitmapDrawable) getResources().getDrawable(R.drawable.lena)).getBitmap();

int w=img1.getWidth(),h=img1.getHeight();

int[] pix = new int[w * h];

img1.getPixels(pix, 0, w, 0, 0, w, h);

int[] resultInt=LibImgFun.ImgFun(pix, w, h);

Bitmap resultImg=Bitmap.createBitmap(w, h, Config.RGB_565);

resultImg.setPixels(resultInt, 0, w, 0, 0,w, h);

long performance=System.currentTimeMillis()-current;

imgView.setImageBitmap(resultImg);

HaveImgFun.this.setTitle("w:"+String.valueOf(img1.getWidth())+",h:"+String.valueOf(img1.getHeight())

+" NDK耗时 "+String.valueOf(performance)+" 毫秒");

}

else if(v == btnRestore)

{

Bitmap img2=((BitmapDrawable) getResources().getDrawable(R.drawable.lena)).getBitmap();

imgView.setImageBitmap(img2);

HaveImgFun.this.setTitle("使用OpenCV进行图像处理");

}

}

}

}
点击全部保存,OK,现在可以选择一个Android虚拟机运行看一下效果,配置好Run Configuration然后点击Run,得到下面的结果:

点击使用C++ OpenCV进行处理,得到下面的结果:

本文出自 “UnderTheHood” 博客,请务必保留此出处http://underthehood.blog.51cto.com/2531780/670169


中国地区Android智能手机市场份额超越iOS达78.8%,Android用户增长...
报告指出,iPhone的需求疲软趋势在这份数据中有所体现,但同时也揭示了两个关键动态。首先,中国等市场的大量新智能手机用户,即从传统功能型手机转向智能手机的用户,倾向于选择Android设备。其次,即使在成熟市场如美国,Android的用户忠诚度也显著,新购买Android手机的用户中有91.4%是此前的Android用户。K...

谷歌Android Wear中国版合作背后:应用商店入华图谋何在?
谷歌中国布局:补贴厂商推动自家商店回归 9月8日,摩托罗拉Moto 360二代智能手表的发布,标志着谷歌以一种前所未有的方式重回中国。这款手表支持中文语音唤醒“出门问问”的搜索引擎,而非Google Now,搭载的是联想应用商店和搜狗地图,而非Google Play和谷歌地图,显示出谷歌接受其安卓生态系统与原生服务分离...

未来安卓手机如何摆脱价格和硬件比拼?
未来之路何在硬件发展瓶颈已经显现,单纯依靠增加核心数量已无可能。消费者可能会从盲目追求硬件转向注重使用体验,关键在于如何协调硬件与软件的发展,避免资源浪费。当价格战和硬件竞争不再吸引人时,手机厂商将面临新的挑战。低价策略还能持续多久?当硬件发展停滞,价格竞争失去动力时,未来的安卓手机将如何在...

android系统为什么越来越不稳定了?速度提上去可稳定性差了,原因何在...
若是较老型号的,原身系统是1.5或1.6,那么您刷2.1或2.2或2.3,那么系统不稳定是经常有的事,(就像P4 CPU带Windows 7,那速度是很慢的)若您的机本身就是很高性能,原生系统即2.2或2.3,那么您可以刷官方的Rom.不要刷别人的定制Rom.那样系统是很稳定的,速度其实是没影响的.Android 2.1\/2\/...

Android8.0新特性【转】
Android O 自适应图标的意义何在?Google 设计师给你答案 | 科普设计自适应图标实现自适应图标Android O 新特性介绍:自适应图标(Adaptive Icons) Android 8.0 还从多个角度增强了原生 Android 平台对蓝牙的支持,具体包括: 支持AVRCP 1.4 标准:支持远程浏览和控制 TV、HiFi 等设备的媒体库。支持蓝牙低功耗 (BLE) 5.0...

关于android2.2模拟器,运行程序时总是报错,不知问题何在
请检查指定的AVD Target是否已经设置了相应的特性。通常,缺省设置的AVD不包括键盘、轨迹球、加速度感应、GPS、相机、SD卡、电池等功能的支持。你必须在AVD管理器中手工添加相应功能,并且在调试运行应用程序时,指定该AVD Target。

中国产安卓病毒Kemoge如何肆虐全球并逃避安全检测?
中国又一款安卓病毒席卷全球,安全防线何在?近期,全球范围内爆发了一款由FireEye Labs发现的中国产Android恶意软件——Kemoge,其传播速度之快,影响范围之广,令人震惊。这个恶意软件家族已经入侵了20多个国家和地区的政府部门及大型机构,显示出其在全球范围内的威胁性。Kemoge的攻击手段隐蔽且狡猾,它通过...

中国产安卓病毒Kemoge如何肆虐全球并获取设备权限?
中国产安卓病毒再次引发全球关注:安全防线何在?FireEye Labs的最新报告显示,一个源自中国的Android恶意软件家族已经迅速在全球20多个国家和地区传播,包括政府部门和大型机构在内的众多目标受到影响,这个被称为Kemoge的威胁不容小觑。Kemoge的攻击手段狡猾,它通过篡改正常应用,伪装成第三方应用在商店发布,...

市场变化因由何在,苹果在平板市场的问题出在哪里?
平板市场风云变幻:苹果面对多方挑战 苹果在平板电脑市场的霸主地位正在遭受挑战。尽管新发布的iPad Air和iPad mini 2展示了苹果的技术实力,但竞争对手如诺基亚的Windows RT平板Lumia 2520和微软的Surface系列也蓄势待发。Android阵营的活跃,如谷歌Nexus 7和亚马逊Kindle Fire的更新,使得选择日益丰富,价格...

新的Android12安装动画是借鉴了iOS的设计吗?
这个新功能,被命名为Android 12安装图标符号,尽管在功能上与iOS略有差异,但操作方式上却如出一辙,仿佛是谷歌从苹果那里汲取了一丝灵感。安装完成后,该图标将安静地出现在主屏幕的一隅,等待着你的关注。据PhoneArena的Mishaal Rahman报道,这个新动画似乎与谷歌去年夏季推出的“下载时播放”功能有所...

韶关市18287965368: 如何在Android中使用OpenCV -
赤轻醋酸: 在Android中使用OpenCV方法为:a、OpenCV安装路径"F:\OpenCV-2.3.1-android-bin"下有两个文件 夹.将文件夹"OpenCV-2.3.1"拷贝到Eclipse工作空间所在的目录,也就是在你的项目的上一级目录中,然后导入到工作空间中,在 ...

韶关市18287965368: 想在Android上使用openoffice来解析office文档,可以么 -
赤轻醋酸: openoffice优点: 1、所有的包有类似的外观,易于使用,如“样式”等“一次学会到处使用”的工具.OpenOffice org保持与电脑类似的外观——一旦改变您的桌面,OpenOffice org也会相应改变. 2、组件间的相同工具用法相同——例如, ...

韶关市18287965368: 怎么在android 4.0中使用openmax al - Android开发 -
赤轻醋酸: 1,native-media app不支持模拟器,只支持设备!2,android 4.0不支持openmax al中的XADataLocator_Address!

韶关市18287965368: 想在Android上使用openoffice来解析office文档,可以么 -
赤轻醋酸: 应该不能 OpenOffice是需要安装的 且安装包134MB大小 你要封装到Android几乎不可能,国内也只有WPS

韶关市18287965368: android 怎么使用自己编译的openssl -
赤轻醋酸: 自己结一下帖.是ndk api 8以下不支持libdl中某些特性的原因,添加 Application.mk APP_PLATFORM := android-8 再次编译成功

韶关市18287965368: android studio怎么打开一个已存在的工程 -
赤轻醋酸: 1、下载了GitHub上面的一个路由分发的项目… 2、然后我在AndroidStudio里面新建了一个可运行的项目:Test 3、app/build.gradle配置如下(新建自动生成的,没做任何改动): 4、project/build.gradle配置如下(自动生成,未做任何改...

韶关市18287965368: android 上能否使用openoffice来进行开发? -
赤轻醋酸: 应该可以吧 貌似openoffice可以在Android上用的

韶关市18287965368: 怎样设置android studio -
赤轻醋酸: 相信很多使用Eclipse的朋友,开始用Android Studio都是觉得不是特别方便,a:比如如何使鼠标放到方法上面,就有提示使用方法; b:如何设置字体大小,和背景色; c:还有怎么查看Outline; d:还有一些Eclipse没有的功能; 下面是我总结...

韶关市18287965368: android 怎么调用opentld -
赤轻醋酸: 1、定义其他类 public class Other{//定义一个普通类 public void show(){//定义一个普通方法 } public static void cal(){//定义类的静态方法 } }2、实例化其他类或者调用其他类的静态方法 在android中调用:Other ot = new Other();//实例化Other类 ot.show();//调用Other类的普通方法 Other.cal();//类名.方法的方法调用静态方法

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网