花了一个星期时间研究NDK编译OpenCV今天终于搞定了。。。。。看了网上无数的文章,感觉都写的不详细,现在我要整理一下整个NDK编辑过程

先给出一个连接参考 http://underthehood.blog.51cto.com/2531780/670169 虽然没成功,但是给我了很大的提示

好了首先要准备的工具

Cygwin   自行下载最近的

NDK 我用的是 r8版本的(之前用r7但是一直错,后来查了才知道r7有点BUG)

然后下载opencv-android2.3.1  http://sourceforge.net/projects/opencvlibrary/files/opencv-android/2.3/    选择OpenCV-2.3.1-beta1-android-bin.tar.bz2   进行下载

这个是已经编辑好的


然后解压后~你应该可以看到这个目录


opencv透明背景图像_image

将其解压到你的文件下

然后穿件一个Android的工程  比如:我创建了一个OpenCVJNI

在你的工程目录下 新建一个jni目录  ,这个目录是存放你的 C/C++原分件和Android.mk (还有Application.mk,这个是可选的)

如何写C源代码这里我就不详细介绍了   我讲我参考的C的代码贴上

#include <string.h>
 #include <jni.h>
 #include <opencv2/core/core.hpp>
 #include <opencv2/imgproc/imgproc.hpp>
 #include <opencv2/features2d/features2d.hpp>
 #include <cv.h>
 #include <cxcore.h>
 #include <android/log.h> 

 #define LOG_TAG "opencv_smooth"
 #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
 #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) 
 using namespace std;
 using namespace cv;

 extern "C" {
     
 JNIEXPORT void JNICALL Java_XJ_Work_JNI_OpenCV_Util_JNI_1OpenCV_JSmooth(
   JNIEnv* env,jobject thiz, jintArray javaIntArray0, 
     jintArray dstArray, jint width, jint height, jint smoothpara) {
      LOGI("load image 1"); 
     jint* src = env->GetIntArrayElements(javaIntArray0, 0);
      LOGI("load image 2"); 
      jint* dst = env->GetIntArrayElements(dstArray, 0);
       LOGI("load image 3"); 
   Mat srcMat = Mat(Size(width, height), CV_8UC4, (unsigned char*) src);
    LOGI("load image 4"); 
   Mat dstMat = Mat(Size(width, height), CV_8UC4, (unsigned char*) dst);
    LOGI("load image 5"); 
   CvMat cvsrcMat = srcMat;
    LOGI("load image 6"); 
   CvMat cvdstMat = dstMat;
   LOGI("load image successfully"); 
     cvSmooth(&cvsrcMat, &cvdstMat,CV_GAUSSIAN,smoothpara,0,0,0);//高斯模糊
     LOGI("smooth image successfully"); 
     env->ReleaseIntArrayElements(javaIntArray0, src, 0);
   env->ReleaseIntArrayElements(dstArray, dst, 0);
 }

 }


这是一个处理图像使之模糊的函数

现在开始写mk文件


LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
include F:/workspace/OpenCV-2.3.1/share/OpenCV/OpenCV.mk   // 这个是opencv下的opencv.mk文件的路径

LOCAL_MODULE    := opencv_xj

LOCAL_SRC_FILES := opencv_xj.cpp

LOCAL_LDLIBS += -ldl -llog //这个如果你需要用到  android的Log功能  需要导入 -llog  ,-ldl 是导入动态库的意思
include $(BUILD_SHARED_LIBRARY)


然后是开始写你的Application.mk(我现在也不知道什么情况下才需要用到这个文件)


APP_STL:=gnustl_static
APP_CPPFLAGS:=-frtti -fexceptions
APP_ABI := armeabi armeabi-v7a //如果是2.2以上的版本需要  写armeabi-v7a
APP_PLATFORM := android-8
STLPORT_FORCE_REBUILD := true


然后很关键的一步:你需要将samples中的includeOpenCV.mk文件放到 你自己的工程目录下!!!

opencv透明背景图像_opencv透明背景图像_02

opencv透明背景图像_dst_03

(当然这个是我已经编辑完成的所有目录,如果你还没用NDK编辑的话  obj和libs目录是不存在的)

现在可以进入Cygwin到$(你的工程目录)/jni下

用NDK命令编辑 (关于NDK的配置参考其他资料   )


好了,现在你觉得OK了吧。。。no!!!

因为接下来你可能会碰到这个问题

opencv透明背景图像_dst_04

解决方法 在提示的目录下 找到这个文件 用UE打开 将64行改成  $(LOCAL_BUILT_MODULE): $(LOCAL_OBJECTS=%)

(这个是之前用NDK R7时做的出现的错误)


然后你继续编辑  可能还会碰到

opencv透明背景图像_image_05

然后你需要在你的NDK的 \sources\cxx-stl\gnu-libstdc++\libs\armeabi中找到这个静态文件 (如果你的Application.mk 中写了 armeabi-v7a,等会还会有需要这个文件的提示

目录也是一样的NDK的\sources\cxx-stl\gnu-libstdc++\libs\armeabi-v7a中找到它就行了),将它放入到F:\workspace\OpenCVJNI\obj\local\armeabi下面(这时你的工程目录会生成一个obj的目录)然后继续编译

opencv透明背景图像_android_06

很好,现在你需要在(你的OpenCV-2.3.1目录)\libs\armeabi下所有的静态库都复制到 之前的(你工程目录)\obj\local\armeabi下

继续编译

opencv透明背景图像_image_07

你需要将(你的OpenCV-2.3.1目录)\share\OpenCV\3rdparty\libs\armeabi下的文件复制到 (你工程目录)\obj\local\armeabi下

opencv透明背景图像_jni_08

这个情况是你的Application.mk中写了armeabi-v7a的原因   ,然后就是一样的继续复制 只不过是放到(你工程目录)\obj\local\armeabi-7va下


OK,如果你的C源代码没有写错误的话  那么你应该可以看到  这个

opencv透明背景图像_opencv透明背景图像_09

编辑成功  得到我们需要的库文件了!(靠,就是这些问题我搞了差不多一个星期)

然后就是在java中使用了

比如我的代码

public class JNI_OpenCV {
     static{
         System.loadLibrary("opencv_xj");
     }
     public native void JSmooth(int[] src, int[] dst, int width, int height, int smoothpara);
 }

 public class OpenCVJNIActivity extends Activity {
     /** Called when the activity is first created. */
     private Button mohu;
     private ImageView img;
     private JNI_OpenCV jni;
     String file = null;
     Bitmap bm = null;
     Bitmap map = null;
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.main);
         mohu = (Button) findViewById(R.id.mohu);
         img = (ImageView) findViewById(R.id.img);
         jni = new JNI_OpenCV();
         BitmapFactory.Options option = new BitmapFactory.Options();
         option.inPreferredConfig = Config.ARGB_8888;
     
         bm = BitmapFactory.decodeResource(this.getResources(),R.drawable.text);
         img.setImageBitmap(bm);
         
         mohu.setOnClickListener(new Button.OnClickListener() {
             
             @Override
             public void onClick(View v) {
                 // TODO Auto-generated method stub
                 //String outfile = file+File.separator+"end.jpg";
                 int width = bm.getWidth();
                 int height = bm.getHeight();
                 int[] src=new int[width*height]; 
                 int[] dst=new int[width*height];
                 bm.getPixels(src,0, width, 0, 0, width, height);
                 
                 /* 如果要对图像进行编辑 必须要使用Bitmap.createBitmap,
                  * 不然使用BitmapFactory.decodeResource(this.getResources(),R.drawable.text);
                  * 是不能对图像进行编辑,会报一个异常
                  *     AndrodRuntime Caused by:java.lang.IllegalStateException
                     AndrodRuntime at android.graphics.Bitmap.setPixels(Bitmap.java:853)
                  */
                 map = Bitmap.createBitmap(width,height,Bitmap.Config.ARGB_8888);
                 
                 jni.JSmooth(src,dst,width,height,11);
                 map.setPixels(dst,0, width,0, 0, width,height);
                 img.setImageBitmap(map);
             }
         });
     }

 }


最后运行

opencv透明背景图像_opencv透明背景图像_10

opencv透明背景图像_jni_11

完成!