Brief introduction
This tutorial is after I have trampled the pit many times, and refer to the online many OpenCV on Android configuration tutorial summed up, hoping to help learn mobile image processing friends less detours.
This is my first time in the book published articles, if there are shortcomings, I hope you dalao can correct me, I will promptly revise. Configuration on if you encounter problems, you can also leave a comment in the comments, I will try to help solve.
if reproduced, please indicate the source http://www.jianshu.com/p/b260ebb1c180.
If you are using Android Studio, refer to the next Chapter OpenCV on Android environment configuration up-to-date & most comprehensive guide (Android Studio article).
Environment
Computer: WINDOWS10
java:jdk1.8.0_131
Eclipse:neon.3 Release (4.6.3)
adt:adt-23.0.7
Ndk:android Studio2.3 comes with the latest NDK
opencv:v3.2.0
sdk:25.2.5 (download separately, please do not use with Android studio, otherwise you will not be able to create Android project correctly on Eclipse)
Note: The above configuration is basically the latest version
First, create OpenCV Demo
Just create a normal eclipse Android project, there is nothing important to say, if this is not, it is recommended to first learn the basics of Android. Here I create a project named Opencvdemo , with the package named Com.demo.opencv.
Second, choose the environment you need
1, if you only want to use the application layer to write programs, please read the following OpenCV Java Library usage guide ;
2, if you only want to quickly image processing in the original layer , please skip to the following OpenCV NDK Library usage guide ;
3, if you want to use OpenCV Java Library and native library , please refer to OpenCV mixed use guide ;
Next I briefly describe the difference and pros and cons of both.
1. The difference between using the OpenCV Java Library and the NDK library
In short, if you use the OpenCV Java library, you only need to write code at the application layer using the Java language, and the OpenCV Java library is aidl connected OpenCV Manager for image processing.
If you are using the OpenCV NDK library, you can write code in the native layer using C + +, and this involves JNI.
Although the programming languages used are different, the end result is to implement the image processing function at the native level, because the OpenCV Java library simply encapsulates the native code (c/s + +) in Java (JNI) and packages it into a so file, which is deposited into the OpenCV Manager , external applications are called through Aidl, which is why it is necessary to install the OpenCV manager with the Java library. But I will be in the OpenCV Java Library Usage Guide describes a method that does not require the installation of OpenCV manager to compensate for its shortcomings, while the OpenCV Hybrid usage Guide provides a simpler approach.
2. Advantages and disadvantages of using OpenCV Java Library and NDK Library
Disadvantages of the Java library:
If you're using a Java library, you'll need to install an additional OpenCV Manager file on your phone, in addition to the apps you've written, in the OpenCV Android sdk/apk/ directory. According to the APK schema you have written (if you only use Java development, you can not consider the APK schema) and your Phone cup architecture selection of the corresponding apk file, generally these two choice Armeabi architecture can be compatible with the vast majority of mobile phones.
Advantages of the Java library:
1. It is easy to realize the image processing on Android client without the knowledge of C + +, which is very suitable for Java language programmer.
2, because there are two applications (their own program and OpenCV Manager), you will get more memory processing space (an Android app default allocation memory limit is 24M).
3, the Java library encapsulates several camera display controls, such as: Javacameraview,nativecameraview (the control has been canceled in the current OpenCV3.2), we can use a small amount of code to achieve camera data collection-- > Display a series of operations.
The advantages of the NDK library:
1, if you use the native library, you can completely abandon the installation of OpenCV Manager, and due to the image processing at the bottom, its processing speed will increase (but because of the Android high version of the optimization, plus OpenCV Java library is actually called its original layer of the library, So the gap is not obvious).
2, using the NDK library, you need to use c\c++ programming, this method is more convenient for the program from Visual Studio porting.
The disadvantages of the NDK library:
Need a certain C\c++ foundation, if involves calls the camera, need to write the buffer frame, avoids the data frame blockage. You must also be familiar with JNI function operations, when memory and references are freed, and so on. If you want to render images at the bottom of OpenGL ES, you need to have some knowledge of the android underlying and OpenGL ES (but not necessarily the former).
Third, OpenCV Java Library Usage Guide environment configuration
First step : Eclipse menu->file->import->android->existing Android Code into Workspace (if this option is not Make sure that the ADT on your eclipse is configured correctly, and then import OpenCV Android sdk\ Sdk\java this project.
1.png
To prevent mis-operation of the OpenCV library, it is recommended that copy project into workspace be checked to copy the library to your working folder. Then finish, if an error occurs after importing, set the project build target to Android5.0 or more (because it is usually Camera2 error, CAMERA2 only exists in android5.0+), The specific method is the project right mouse button, select Properties, and then click on Android, select Android5.0 above the version can, and then OK, here I choose is 6.0.
2.png
Second Step : in your project right-click also into the page, library Select Add, add OpenCV library (such as), OK, after your project will be able to use the OpenCV Java function.
3.pngDemo Writing
Create a Java image processing class Opencv_java. Java (please ignore my name)
Opencv_java. Java content:
public class OpenCV_Java extends BaseLoaderCallback { private boolean isInit = false; private Context context; public OpenCV_Java(Context context){ super(context); this.context = context; } @Override public void onManagerConnected(int status) { switch (status) { case LoaderCallbackInterface.SUCCESS: isInit = true; break; default: isInit = false; super.onManagerConnected(status); break; } } public void toGary(Bitmap bitmap){ if(isInit){ Mat mat = new Mat(); Utils.bitmapToMat(bitmap, mat); Imgproc.cvtColor(mat, mat,Imgproc.COLOR_RGBA2GRAY ); Utils.matToBitmap(mat, bitmap); }else{ Toast.makeText(context, "OpenCV init error", Toast.LENGTH_LONG).show(); } }}
Mainactivity.java content:
public class Mainactivity extends Activity implements Onclicklistener {private ImageView ImageView; Private Bitmap Bitmap; Private Button showbtn, processbtn; Private Opencv_java Javautil = new Opencv_java (this); @Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); Setcontentview (R.layout.activity_main); ImageView = (ImageView) Findviewbyid (R.id.imageview); SHOWBTN = (Button) Findviewbyid (r.id.show); Showbtn.setonclicklistener (this); PROCESSBTN = (Button) Findviewbyid (r.id.process); Processbtn.setonclicklistener (this); } @Override public void Onresume () {super.onresume (); if (! Opencvloader.initdebug ()) {Opencvloader.initasync (opencvloader.opencv_version_3_2_0, this, javaUtil); } else {javautil.onmanagerconnected (loadercallbackinterface.success); }} @Override public void OnClick (View v) {if (v = = SHOWBTN) {bitmap = Bitmapfactory.decoderesource (Getresources (), r.drawable.ic_launcher); Imageview.setimagebitmap (bitmap); } else {if (bitmap! = null) {//Avoid two times processing javautil.togary (bitmap); Imageview.setimagebitmap (bitmap); bitmap = null; } } }}
Layout content:
<relativelayout xmlns:android= "http://schemas.android.com/apk/res/android" xmlns:tools= "http// Schemas.android.com/tools "android:layout_width=" match_parent "android:layout_height=" match_parent "> <Imag Eview android:id= "@+id/imageview" android:layout_width= "match_parent" android:layout_height= "Match_pa Rent "/> <linearlayout android:layout_width=" match_parent "android:layout_height=" Wrap_content " Android:layout_alignparentbottom= "true" android:orientation= "horizontal" > <button Android Oid:id= "@+id/show" android:layout_width= "match_parent" android:layout_height= "Wrap_content" android:layout_weight= "1" android:text= "show"/> <button android:id= "@+id/process" Android:layout_width= "Match_parent" android:layout_height= "Wrap_content" Android:layout_we ight= "1" android:text= "process"/&Gt </LinearLayout></RelativeLayout>
Installing OpenCV Manager
Its location is located in the opencv-android-sdk\apk directory, select the appropriate APK program, the general choice of opencv_3.2.0_manager_3.20_armeabi.apk can be.
Run Demo
Package the project compilation into an APK, install to the phone, run, and click on the button to show its effect:
4.png
Click the button process to convert it to a grayscale image, as shown below:
5.png
- Note: If OpenCV is not initialised correctly appears. Applicationwill is shut down, maybe your OpenCV manager program is different from your CPU architecture, choose the right apk. If the phone version is relatively high, it is possible that the mobile phone will prevent your app to call OpenCV Manager, the purpose is to prevent the malicious software wake-up (such as Baidu family bucket), the solution to Baidu (because there is no unified method). Abandon OpenCV Manager: Installing an extra apk is very unfriendly to the user, but using C/D + + programming makes it more difficult for some Java programmers, so we should think of the best of both worlds, which helps developers use Java to develop quickly and give users a good experience.
Ideas:
The Java library is essentially a Java package for the NDK library, where so files are placed within OpenCV Manager, data is exchanged through aidl, and image processing is achieved.
Workaround:
If we put the NDK library inside OpenCV Manager into our app, wouldn't it be possible to abandon OpenCV Manager and implement image processing? The answer is yes, we will opencv-android-sdk\sdk\native\libs\[the schema] directory (here to choose the appropriate architecture, generally with Armeabi) libopencv_java3.so under your project libs\[schema] directory (manually created yourself), the project structure
6.png
And then load this so library statically in your Mainactivity.java.
public class MainActivity extends Activity implements OnClickListener { private ImageView imageView; private Bitmap bitmap; private Button showBtn, processBtn; private OpenCV_Java javaUtil = new OpenCV_Java(this); static{ System.loadLibrary("opencv_java3"); } @Override protected void onCreate(Bundle savedInstanceState) { ......下面内容不变
Compile and install, and you'll be able to unload your OPENCV manager. The result is the same as the previous operation.
This method is not perfect, because in this program, you only realize the color image grayscale image, but you installed the native library, the APK is full of 4.39M, compared to the previous 194k, nearly 20 times times the growth. However, if your application is large and the size of the so file is fixed, this method will be a good choice.
Iv. OpenCV NDK Library usage Guide Environment configuration
First step: Configure the NDK environment
Go to menu->window->preferences->android->ndk, set the NDK location path, note: Make sure that the path exists ndk-build.cmd File. Such as:
7.png
Step Two: Configure the JNI environment
Here I'll use the quick way to configure:
1, right-click on your project Android Tools->add native support-> Enter the appropriate name- > OK, I'll use the default "Opencvdemo" directly here.
2. Create a new XML file locally and copy the following to modify the path in it.
<?xml version= "1.0" encoding= "UTF-8"? ><cdtprojectproperties><section name= " Org.eclipse.cdt.internal.ui.wizards.settingswizards.IncludePaths "><language name=" C,cpp ">< Includepath>d:/android/android-sdk/ndk-bundle/platforms/android-9/arch-arm/usr/include</includepath> <includepath>d:/android/android-sdk/ndk-bundle/sources/cxx-stl/gnu-libstdc++/4.9/include</includepath ><includepath>d:/android/android-sdk/ndk-bundle/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi/ include</includepath><includepath>d:/android/android-sdk/ndk-bundle/sources/cxx-stl/gnu-libstdc++/ 4.9/libs/armeabi-v7a/include</includepath><includepath>d:/android/android-sdk/ndk-bundle/ toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64/lib/gcc/arm-linux-androideabi/4.9.x/include</ includepath><includepath>d:/opencv/opencv-android-sdk/sdk/native/jni/include</includepath></ Language></section><section name= "Org.eclipSe.cdt.internal.ui.wizards.settingswizards.Macros "><language name=" C,cpp "></language></ Section></cdtprojectproperties>
3, the project right-click the last properties, and then select C + + general, Path and Symbols,:
8.png
Click Import Settings->browse, select the above XML file locally on the computer, click Finish, the environment will be imported successfully.
Next, check to see if the environment is correct.
1. See if the path exists: Follow the instructions to switch the compiler to C + + editor mode:
9.png
Expand the project to see if the path under the Include directory is dimmed (for example), and can be expanded , if all are met, to indicate that the path exists.
10.png
2, check the environment is normal. Go to the JNI directory, open OpenCVDemo.cpp, use CTRL + left mouse button on #include<jni.h>, if Eclipse can open jni.h this file, your JNI environment will be built successfully.
Step Two: Configure the OPENCV NDK environment
1, copy the following into the Android.mk file, where opencv_android_sdk please set to the correct path, but also note my comments in the manifest file .
Local_path: = $ (call My-dir) include $ (clear_vars) # ##################################################### ###### #这里改成你的路径, the remainder of the split line is constant OPENCV_ANDROID_SDK: = D:/opencv/opencv_android_sdk#opencv_bulid_type: = NDK #默认NDK环境, Opencv_java3.so is not automatically imported, so OpenCV Java library opencv_bulid_type is not supported: = JAVA_AND_NDK #将自动导入openCV_java3. So to support JAVA libraries (no installation required OpenCV Manager) ifeq ($ (opencv_bulid_type), java_and_ndk) Opencv_lib_type: = SHARED opencv_install_modules: = Onelse OPE Ncv_lib_type: = Staticendif ifdef opencv_android_sdk ifneq ("", "$ (wildcard $ (OPENCV_ANDROID_SDK)/opencv.mk)") include ${opencv_android_sdk}/opencv.mk else include ${opencv_android_sdk}/sdk/native/jni/opencv.mk Endifelse include. /.. /sdk/native/jni/opencv.mkendif# ########################################################### #动态链接日志库LOCAL_LDLIBS + =-llog-ljnigraphicslocal_module: = opencvdemolocal_src_files: = Opencvdemo.cppinclude $ (BUILD_SHARED_LIBRARY)
2. Add application.mk files under the JNI directory
The contents are as follows:
APP_STL := gnustl_staticAPP_CPPFLAGS := -frtti -fexceptionsAPP_ABI := armeabiAPP_PLATFORM := android-8APP_OPTIM := debug
To this end, the NDK environment is configured.
Demo Writing
The layout file is the same as the Java demo above, Mainactivity.java content is as follows:
public class Mainactivity extends Activity implements Onclicklistener {private ImageView ImageView; Private Bitmap Bitmap; Private Button showbtn, processbtn; Private OPENCV_NDK Nativeutil = new Opencv_ndk (); @Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); Setcontentview (R.layout.activity_main); ImageView = (ImageView) Findviewbyid (R.id.imageview); SHOWBTN = (Button) Findviewbyid (r.id.show); Showbtn.setonclicklistener (this); PROCESSBTN = (Button) Findviewbyid (r.id.process); Processbtn.setonclicklistener (this); } @Override public void OnClick (View v) {if (v = = showbtn) {bitmap = Bitmapfactory.decoderesourc E (Getresources (), r.drawable.ic_launcher); Imageview.setimagebitmap (bitmap); } else {if (bitmap! = null) {nativeutil.togary (bitmap); Imageview.setimagebitmap (bitmap); bitmap = null; } } }}
It can be seen that there is not much change. The contents of Opencv_ndk.java are as follows:
public class OpenCV_NDK { static{ System.loadLibrary("OpenCVDemo"); } native void toGary(Object bitmap);}
is not particularly simple ^_^. Then use the Javah command in the console to generate the JNI header file, where I use a key generation (referring to "Android C Advanced Programming using the NDK"), the eclipse configuration is as follows:
Menu Run->external tools->external Tools configurations, double-click Program and the right side will create a new interface. The configuration is as follows:
Main tab
Name:Generate C and C + + Headerfile
Location:${system_path:javah}
Working Directory:${project_loc}/jni
Arguments:-classpath "${project_classpath};
${env_var:android_sdk_home}/platforms/android-14/android.jar "${java_type_name}
Switch to the Refresh tab:
Check Refresh resource up completionand select the project containing the selected resource in the list
Switch to the Common tab and tick on external Tools.
Configuration complete (the above configuration changes according to the actual situation, I recommend using the Javah command to generate the header file)
Where android_sdk_home is a variable i created in My Computer environment configuration, pointing to the SDK path.
Then place your mouse point in the Opencv_ndk.java and click on the location:
11.png
After a few seconds, the com_demo_opencv_opencv_ndk.h header file will be generated (this file name is related to your package name and class name).
Modify the OpenCVDemo.cpp to the following:
#include "com_demo_opencv_OpenCV_NDK.h"#include <opencv2/opencv.hpp>#include <android/bitmap.h>using namespace cv;JNIEXPORT void JNICALL Java_com_demo_opencv_OpenCV_1NDK_toGary (JNIEnv *env, jobject thiz, jobject bitmap){ AndroidBitmapInfo bitmapInfo; void* bitmapPixels; int width, height, ret; //解析bitmap if ((ret = AndroidBitmap_getInfo(env, bitmap, &bitmapInfo)) < 0) { return; } if (bitmapInfo.format != ANDROID_BITMAP_FORMAT_RGBA_8888) { return ; } if ((ret = AndroidBitmap_lockPixels(env, bitmap, &bitmapPixels)) < 0) { return; } width = bitmapInfo.width; height = bitmapInfo.height; Mat bgra(height, width, CV_8UC4, bitmapPixels); Mat gary; cvtColor(bgra,gary,COLOR_RGBA2GRAY); cvtColor(gary,bgra,COLOR_GRAY2BGRA); AndroidBitmap_unlockPixels(env, bitmap);}
Then compile the run, the result is the same as the Java run result, no need to install OpenCV Manager, this method compiles the installation package only 951KB, image processing time I did not calculate, should be similar.
V. OpenCV Mixed Use Guide
Assuming you've looked at the first two configurations and are accustomed to Java development, but feel that the OpenCV Java library is not providing enough methods to use hybrid development, congratulations, that's part of what you need. This part of the content is very small, summed up in two parts:
1. Import the OpenCV Java library and associate your app, refer to the OpenCV Java Library Usage Guide (remember to write the contents of the so library statically loaded, but so files do not need to be imported manually).
2, configure the JNI environment and NDK environment, refer to the OpenCV NDK Library usage guide .
3, modify android.mk file content:opencv_bulid_type: = NDK for opencv_bulid_type: = Java_and_ndk.
Then compile, this time android.mk will pack your native code into a libopencvdemo.so file and put it in your Libs directory with libopencv_java3.so .
12.png
This makes it easy to install OPENCV Manager without installing Java and C + + images, while avoiding manual import of libopencv_java3.so, note: The code for static import so must have .
Vi. Summary
This tutorial is dedicated to helping OPENCV newcomers to the rapid configuration, there may be shortcomings, acceptance of suggestions and criticisms, follow-up will be supplemented and improved. At the same time welcome everyone to explore the knowledge of Android image processing, and common progress.
OpenCV on Android Environment Configuration latest & most comprehensive guide (eclipse article)