http://hujiaweibujidao.github.io/blog/2013/11/18/android-ndk-and-opencv-development-3/
Android Ndk and Opencv Development 3
NOV 18TH, 2013
Android NDK 和 OpenCV 整合开发总结(3)
终于写到第三节啦,虽然很累,但是还是要坚持,坚持写完这3篇文章。
这一节的主要内容是OpenCV在Android NDK开发中的应用,包括下面几个方面的内容:
- 如何实现Static Initialization从而不需要安装OpenCV Manager运行含OpenCV library的app
- 对十份论文和报告中的关于OpenCV和Android NDK开发的总结
- 如何使用Android中的摄像头,常见的问题有哪些?
- OpenCV 和 Android NDK 整合开发的一般途径
1.实现Static Initialization
实现Static Initialization就是指将OpenCV Library添加到app package中,不需要安装OpenCV Manager这个app就能运行,官方文档有介绍,但是不详细,尤其是最后那句代码到底要放在什么地方很多人都不清楚,其实并不需要像官方文档中介绍的那样配置,我想在这里介绍下如何修改FaceDetection项目的源码来做到这点。(最好是找一个包含jni代码的项目进行修改)
- [1]打开jni下的Android.mk文件,修改OpenCV的那一部分,将
off
设置为on
,并设置OpenCV_LIB_TYPE
为SHARED
,结果如下:
1
2
3
4
| OpenCV_CAMERA_MODULES:=on
OpenCV_INSTALL_MODULES:=on OpenCV_LIB_TYPE:=SHARED include ${OpenCVROOT}/sdk/native/jni/OpenCV.mk |
- [2]打开FdActivity.java文件,在其中添加一个静态初始化块代码,它是用来加载
OpenCV_java
库的,由于FaceDetection中还用了另一个库detection_based_tracker(用于人脸跟踪),所以要在else
子句中加载进来:
1
2
3
4
5
6 7 8 | static {
Log.i(TAG, "OpenCV library load!"); if (!OpenCVLoader.initDebug()) { Log.i(TAG, "OpenCV load not successfully"); } else { System.loadLibrary("detection_based_tracker");// load other libraries } } |
- [3]删除FdActivity.java的OnResume()方法的最后那句,不让它去访问OpenCV Manager。
1
2
3
4
5
| @Override
public void onResume() { super.onResume(); //OpenCVLoader.initAsync(OpenCVLoader.OpenCV_VERSION_2_4_3, this, mLoaderCallback);// } |
- [4]修改FdActivity.java的OnCreate()方法,从上面的
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this)
代码块中拷贝try-catch
块放到OnCreate的setContentView()
之后,然后拷贝mOpenCVCameraView.enableView();
放到mOpenCVCameraView = (CameraBridgeViewBase) findViewById(R.id.fd_activity_surface_view);
之后,修改后的OnCreate()方法如下:
1
2
3
4
5
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | public void onCreate(Bundle savedInstanceState) { Log.i(TAG, "called onCreate"); super.onCreate(savedInstanceState); getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); setContentView(R.layout.face_detect_surface_view); // try { // load cascade file from application resources InputStream is = getResources().openRawResource(R.raw.lbpcascade_frontalface); File cascadeDir = getDir("cascade", Context.MODE_PRIVATE); mCascadeFile = new File(cascadeDir, "lbpcascade_frontalface.xml"); FileOutputStream os = new FileOutputStream(mCascadeFile); byte[] buffer = new byte[4096]; int bytesRead; while ((bytesRead = is.read(buffer)) != -1) { os.write(buffer, 0, bytesRead); } is.close(); os.close(); mJavaDetector = new CascadeClassifier(mCascadeFile.getAbsolutePath()); if (mJavaDetector.empty()) { Log.e(TAG, "Failed to load cascade classifier"); mJavaDetector = null; } else Log.i(TAG, "Loaded cascade classifier from " + mCascadeFile.getAbsolutePath()); mNativeDetector = new DetectionBasedTracker(mCascadeFile.getAbsolutePath(), 0);// hujiawei cascadeDir.delete(); } catch (IOException e) { e.printStackTrace();
|