Android环境搭建之三 Eclipse下搭建Android + C/C++ + OpenCV 开发坏境

来源:互联网 发布:电脑照相机软件下载 编辑:程序博客网 时间:2024/05/01 14:07

接上一篇博客,“Android环境搭建之二  Eclipse下搭建Android+OpenCV开发坏境”,其中提到Android平台下使用OpenCV有两种方式,一种是直接利用OpenCV的java API进行开发;另一种是在Android平台下调用C代码,在C代码中调用OpenCV。上一篇博客介绍了第一种方法,这篇博客来介绍第二种方法。

相比于第一种方法,在Android中调用C代码的坏境配置以及调用过程要复杂的多,但是带来的好处是效率大大提高,在手机这种资源有限的平台上,效率显得尤为重要。需要强调的一点是NDK r8版本之后,并不需要在Windows上安装Cygwin来模拟Linux坏境了,如此可以简化很多操作、减少出错的几率,而很多人在环境配置上都倒在了Cygwin上,导致后续过程难以进行。

本文默认你的计算机上装有Eclipse的基本Android开发坏境,即只要可以开发最基本的“HelloWorld”工程即可。首先例举下Android + C所需要软件,已上传至百度网盘,大家可去分享下载。

 http://pan.baidu.com/s/1mgr7nF6 密码:bv7y

         AndroidNDK:android-ndk-r10 (r8版本之后都可)

         NDK路径设置插件:com.android.ide.eclipse.ndk_23.0.2.1259578.jar


本文在配置过程中参考了很多优秀的技术博客,感谢他们的分享,推荐其中几篇和大家共同学习。

http://jingyan.baidu.com/article/3ea51489e7a9bd52e61bbac7.html

         http://blog.csdn.net/shulianghan/article/details/18964835


一、Android + C环境搭建

(1)在Eclipse根目录同一文件夹下。如下图


(2)下载NDK路径设置插件(com.android.ide.eclipse.ndk_23.0.2.1259578.jar),将其放在Eclipse下的plugins文件夹下,如图


(3)打开Eclipse,依次打开 windows à preference àAndroid à NDK,在NDK location下设置NDK的路径,如图


以上基本步骤完成表明基本坏境已经搭建完成,相比于网络上普遍博客介绍的需要安装Cygwin坏境,所需步骤大大减少。接下来用个实例来验证下所配置坏境是否正确


4)Eclipse中导入“hello-jni”程序,以此打开Fileàimport,如下图

                  


(5)右键“HelloJni”工程àAndroid ToolsàAdd Native Support



(6) “Ctrl + B”编译过程,然后运行,运行结果如下,则Android + C基本坏境成功




二、编写自己的Android+C程序

(1)新建工程“DemoJni”,并建立一个基本布局,一个Button加上一个TextView

(2)右键 “DemoJni”工程àAndroidToolsàAdd Native Support,添加完之后可以发现包资源管理器多了一个 jni 文件夹,文件夹下会有Android.mk 和.cpp文件

(3)在Activity中声明Native函数,如下:

public native int myAdd(int a, int b);

pulibc native int muMinus(int a, int b);


static {
        System.loadLibrary("hello-jni");
    }

4)右键“DemoJni”工程à属性àBuilder(构建器)à新建。新建的构建器具体设置如下:location(位置)为javah.exe的路径,通过浏览文件系统来选择;工作目录为“DemoJni”工程目录,通过浏览工作空间来选择;自变量的路径设置为 “-classpath src -djni/platform com.example.demojni.MainActivity”,最后的一段路径为声明Native函数的Activity路径。如图


(5)”Ctrl + B”编译工程,完成之后可以看到platform文件夹下多了 .h 头文件,然后从其他工程中拷贝一份 Application.mk 文件至 jni 文件夹下如图

(6)在 .cpp 文件夹中编写本地C/C++代码;在Android.mk和Application.mk文件中编写相应内容,然后进行编译。这部分内容的详细说明在一些技术博客中可以找到,以下为推荐的博客地址:http://blog.csdn.net/shulianghan/article/details/18964835

(7)在手机或者模拟器上运行调试。

三、编写自己的Android+ C + OpenCV程序

基于以上Android + C坏境,下面来说明如何更进一步在C代码中调用OpenCV从而在涉及多媒体信息处理的程序时,可以大大提高程序性能。在基于以上“DemoJni”工程的基础上,进行调用OpenCV的说明。

(1)首先右键“DemoJni”工程à属性àAndroidà添加OpenCV4Android的依赖库。

(2)添加完依赖库之后,需要修改工程的一些环境设置。具体如下,右键“DemoJni”工程à属性àC/C++ Buildà更改Build Command如下图


(3)右键“DemoJni”工程à属性àC/C++GeneralàPath and Symbols,添加以下路径

         ${NDKROOT}/platforms/android-9/arch-arm/usr/include

${NDKROOT}/sources/cxx-stl/gnu-libstdc++/4.6/include

${NDKROOT}/sources/cxx-stl/gnu-libstdc++/4.6/libs/armeabi-v7a/include

${ProjDirPath}/../../sdk/native/jni/include

         其中最后一个路径指定到计算机中OpenCV4Android的路径,例如在我的电脑中具体路径为” D:\Java\work\OpenCV_SDK\native\jni\include”。


(4)在Activity中声明Native函数,新建布局,完成一个基本的Blur功能。然后编译工程,要想在C代码中使用OpenCV,需要在Android.mk和Application.mk中添加一些代码,具体如下。

         在Android.mk文件中,额外添加一行”include ../OpenCV_SDK/native/jni/OpenCV.mk”,其中路径是OpenCV4Android中OpenCV.mk文件的路径。

         在Application.mk中,额外添加代码

         APP_STL:= gnustl_static 

APP_CPPFLAGS :=-frtti -fexceptions

         这部分的详细说明可以在 OpenCV的官方手册中找到,具体地址如下;http://docs.opencv.org/doc/tutorials/introduction/android_binary_package/android_dev_intro.html#android-dev-intro

(5)在.cpp文件中编写本地C++代码,调用OpenCV API,然后编译运行。

MainActivity中代码为:

package com.example.demojni;import org.opencv.android.BaseLoaderCallback;import org.opencv.android.LoaderCallbackInterface;import org.opencv.android.OpenCVLoader;import android.graphics.Bitmap;import android.graphics.Bitmap.Config;import android.graphics.BitmapFactory;import android.os.Bundle;import android.support.v7.app.ActionBarActivity;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.ImageView;import android.widget.TextView;public class MainActivity extends ActionBarActivity {private Button button;private ImageView imageView;private Bitmap bmp;public native int[] JniBlur(int[] pixels, int w, int h);private BaseLoaderCallback  mLoaderCallback = new BaseLoaderCallback(this) {      @Override          public void onManagerConnected(int status) {              switch (status) {                  case LoaderCallbackInterface.SUCCESS:{                      System.loadLibrary("DemoJni");                  } break;                  default:{                      super.onManagerConnected(status);                  } break;              }          }     };     @Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.blur_layout);button = (Button)findViewById(R.id.blur_button);imageView = (ImageView)findViewById(R.id.blur_imageview);bmp = BitmapFactory.decodeResource(getResources(), R.drawable.lena);button.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// TODO 自动生成的方法存根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 = JniBlur(pixels, w, h);          Bitmap resultImg = Bitmap.createBitmap(w, h, Config.ARGB_8888);          resultImg.setPixels(resultInt, 0, w, 0, 0, w, h);          imageView.setImageBitmap(resultImg);}});} 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_9, this, mLoaderCallback);      }}

.cpp文件中代码为:

#include <jni.h>#include <opencv2/opencv.hpp>#include <opencv2/imgproc/imgproc.hpp>#include <opencv2/core/core.hpp>using namespace cv;using namespace std;extern "C" JNIEXPORT jintArray JNICALL Java_com_example_demojni_MainActivity_JniBlur  (JNIEnv * env, jobject obj, jintArray pixels, jint w,  jint h){jint *cbuf;    cbuf = env->GetIntArrayElements(pixels, NULL);    if(cbuf == NULL){        return 0;    }    Mat imgData(h, w, CV_8UC4, (unsigned char*)cbuf);    blur(imgData, imgData,Size(25,25),Point(-1, -1));    int size=w * h;    jintArray result = env->NewIntArray(size);    env->SetIntArrayRegion(result, 0, size, cbuf);    env->ReleaseIntArrayElements(pixels, cbuf, 0);    return result;}
(6)最后运行结果如下,表明在C代码中调用OpenCV API进行图像的模糊处理,即Android + C + OpenCV 搭建成功。



中国科学技术大学多媒体计算与通信教育部-微软重点实验室MultiMedia Computing Group


0 0
原创粉丝点击