Note: This article is no longer maintained by the author, as most development is now done in Android Studio. Only the Android Studio chapter will be maintained. If you insist on using Eclipse, make sure all environments are consistent with this article.
Introduction to the
This tutorial is after I stepped On the pit many times, and combined with many online OpenCV On Android configuration tutorial summary, do hope to help learn OpenCV friends less detour. If you run into problems with the configuration, leave them in the comments and I’ll do my best to help.
If you are using Android Studio, please refer to the next chapter OpenCV On Android Best Environment Configuration Guide (Android Studio).
If reproduced, please indicate the source
The environment
- Computer: Windows 10
- Java: jdk1.8.0 _172
- Eclipse: Photon Release (4.8.0)
- ADT: ADT – 24.0.2
- NDK: The latest NDK that comes with Android Studio
- OpenCV: V3.4.1
- SDK: 25.2.5 (updated from 24.4.1)
Note: The above configuration is basically the latest version. Eclipse can share an NDK with Android Studio, but the SDK is not universal, or you won’t be able to create Android projects properly on Eclipse.
Create OpenCV Demo
Start by creating a normal Android application. Note that we need to set the Minimum Required SDK to API15 and above so that it is compatible with 95% of Android phones on the market without introducing potential bugs. If an error occurs here, make sure your JDK, ADT, and SDK are configured correctly.
So I’m going to create a project called OpenCVDemo, package called com.demo. Opencv, OK.
OpenCV Java library usage guide
2.1. Environment Configuration
The first step: Eclipse menu ->File->Import->Android->Existing Android Code Into Workspace, then Import OpenCV Android SDK\ SDK\ Java directory.
To prevent misoperation of the OpenCV library, it is recommended to check Copy Project into Workspace, Copy the library to your working folder, and then click Finish.
If an error occurs after the import, set the Project build Target to Android5.0 or higher (because Camera2 is only available on Android5.0+). The specific steps are as follows:
Right-click the project, select Properties -> Android, select Android5.0 or higher, then Apply and Close.
Here I chose 5.0.1.
Step 2: Go to the previous page and click the Add button in the Library to Add the OpenCV Library. When finished, your project will be able to call the OpenCV Java function.
2.2. Demo writing
Create a Java class called opencv_java.java with the following contents:
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(); }}}Copy the code
Then there is MainActivity, which looks like this:
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(a) {
super.onResume();
if(! OpenCVLoader.initDebug()) { OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION,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 secondary processing
javaUtil.toGary(bitmap);
imageView.setImageBitmap(bitmap);
bitmap = null; }}}}Copy the code
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" >
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="horizontal" >
<Button
android: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_weight="1"
android:text="process"/>
</LinearLayout>
</RelativeLayout>
Copy the code
The code is written, but it cannot run at this point because OpenCV Manager.apk is not installed on the phone.
2.3. Install OpenCV Manager
In the opencv-Android-sdk \apk directory, select the appropriate APK program to install (generally choose Opencv_3.2.0_Manager_3.20_armeabi. apk).
2.4. Run Demo
Compile and package the project into APK, install it to the mobile phone, run it, click the button “show”, perform gray processing on the image, and the effect is as shown below:
Note:
- If there is a
OpenCV was not initialised correctly.Application will be shut down
It may be that your OpenCV Manager application is different from your CPU architecture. Choose the appropriate APK. - If the mobile phone version is older, the call may not be called
OpenCV Manager
In this case, it is because the mobile phone manufacturer has made restrictions to prevent malware from waking up each other (such as Baidu Family bucket), the solution please baidu (because there is no unified method).
2.5. Discard OpenCV Manager:
Installing an additional APK is very user unfriendly, but programming with C/C++ makes it difficult for some Java programmers to implement, so we should think of a way to get the best of both worlds, which helps developers develop quickly in Java without requiring users to install additional software.
Ideas:
Java library is actually just Java encapsulation of NDK library, so file in OpenCV Manager, interactive through AIDL, so to achieve image processing.
Solution:
If we package the so files in OpenCV Manager directly into our application, we can discard OpenCV Manager.
Yes, that’s right, and OpenCV officially provides us with a ready-made SO file, Just place the libopencv_java3.so in opencv-Android-sdk/SDK/native/libs/ARM/libs/armeabi-v7a/libopencv_java3.so in your project libs/ARM/libopencv_java3.so:
Then load the so library 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"); }... The following remains the same}Copy the code
Compile and install, at this point, you can uninstall your OpenCV Manager. The result is the same as before.
Note: This method is not perfect because in this program, you only achieve the image grayscale, but introduce the so file libopencv_java3.so, apK is a full 4.39 MB, compared to the previous 194K, nearly 20 times. Unless your application is large and the size of the SO file is fixed, this is also a good choice.
OpenCV NDK library usage Guide
3.1 environment configuration
Step 1: Configure the NDK path
Go to the menu ->Window->Preferences->Android->NDK and set NDK Location. Note: Ensure that the ndk-build. CMD file exists in this path. The diagram below:
Step 2: Configure the JNI environment
Here we import the configuration file to configure:
- Right-click on your project
Android Tools->Add Native Support -> Enter an appropriate name -> OK
I’ll just use the default name. - Create a local XML file, copy the following contents into it, and
Change the path to the path of your NDK library
.
<cdtprojectproperties>
<section name="org.eclipse.cdt.internal.ui.wizards.settingswizards.IncludePaths">
<language name="c,cpp">
<includepath>D:\AndroidSDK\AndroidStudio\ndk-bundle\sysroot\usr\include</includepath>
<includepath>D: \ AndroidSDK \ AndroidStudio \ the NDK - bundle \ sources \ CXX - STL - libstdc++ \ 4.9 \ \ gnu include</includepath>
<includepath>D:\OpenCV\OpenCV-android-sdk\sdk\native\jni\include</includepath>
<includepath>D: \ AndroidSDK \ AndroidStudio \ the NDK - bundle \ toolchains \ arm - Linux - androideabi - 4.9 \ prebuilt \ Windows - x86_64 \ lib \ GCC \ arm - Linux - an Droideabi \ 4.9 \ include x</includepath>
</language>
</section>
<section name="org.eclipse.cdt.internal.ui.wizards.settingswizards.Macros">
<language name="c,cpp">
</language>
</section>
</cdtprojectproperties>
Copy the code
- Right-click the project and select the last one
Properties
And then selectC/C++ General -> Path and Symbols
, as shown in the figure:
Click Import Settings->Browse, select the above XML file locally on your computer, and click Finish to Import the environment successfully.
Step 3: Check that the environment is correct
- To switch the compiler to C/C++ editor mode:
- Check whether the Includes paths exist: Ensure that the paths exist
Not for the grey
(figure below), and both canan
.
- Check whether the environment is normal.
Go to the jNI directory, open opencvdemo. CPP, press Ctrl+ left mouse button on #include
, and if Eclipse can open the jni.h file, your JNI environment is set up successfully.
Step 4: Configure the OpenCV NDK environment
- Copy the following into
Android.mk
File, pay attention to modifyOPENCV_ANDROID_SDK
For your OpenCV path, and read the comments I added.
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Change this to your path, the rest of the dividing line remains the same
OPENCV_ANDROID_SDK := D:/OpenCV/OpenCV-android-sdk
#OPENCV_BULID_TYPE := NDK # Opencv_java3. so does not automatically import the OpenCV Java library
OPENCV_BULID_TYPE := JAVA_AND_NDK Opencv_java3. so will be automatically imported to support Java libraries (no need to install OpenCV Manager)
ifeq ($(OPENCV_BULID_TYPE), JAVA_AND_NDK)
OPENCV_LIB_TYPE := SHARED
OPENCV_INSTALL_MODULES := on
else
OPENCV_LIB_TYPE := STATIC
endif
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
endif
else
include. /.. /sdk/native/jni/OpenCV.mkendif
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# dynamic link log library
LOCAL_LDLIBS += -llog -ljnigraphics
LOCAL_MODULE := OpenCVDemo
LOCAL_SRC_FILES := OpenCVDemo.cpp
include $(BUILD_SHARED_LIBRARY)
Copy the code
- Add in the JNI directory
Application.mk
File, as follows:
APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := all
APP_PLATFORM := android-15
APP_OPTIM := debug
Copy the code
At this point, the NDK environment is configured.
3.2. Demo preparation
Use the previous layout file and modify the mainActivity. Java content 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.decodeResource(getResources(), R.drawable.ic_launcher);
imageView.setImageBitmap(bitmap);
} else {
if(bitmap ! =null) {
nativeUtil.toGary(bitmap);
imageView.setImageBitmap(bitmap);
bitmap = null; }}}}Copy the code
As you can see, MainActivity doesn’t change much from before.
Then opencv_ndk.java will look like this:
public class OpenCV_NDK {
static {
System.loadLibrary("OpenCVDemo");
}
native void toGary(Object bitmap);
}
Copy the code
Isn’t it very simple?
Now you just need to generate the header file for the toGary() native method. This step needs to use javah command. For details, please refer to Baidu.
Then change 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;
/ / parse 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);
}
Copy the code
Note: the above method name must be the same as the method name in the generated header file, otherwise it will not be called.
The result is the same as the previous Java code, but there is no need to install OpenCV Manager. The installation package compiled by this method is only 951KB. I also recommend developing OpenCV applications using NDK.
OpenCV mixed use guide
If you’ve looked at the first two configurations, are used to Java development, but feel that the OpenCV Java library doesn’t offer enough methods and want to use hybrid development, then congratulations, this section is what you need.
This section is very small, summed up in two parts:
- Import the OpenCV Java library and associate it with your application, refer to the OpenCV Java library guide (remember to write the code to load the so file, but you don’t need to import the so file manually).
- Configure the NDK environment and OpenCV environment. For details, see the OpenCV NDK library Usage Guide.
- Modify the contents of the Android.mk file
OPENCV_BULID_TYPE
byNDK
Modified toJAVA_AND_NDK
.
At compile time, libopencvdemo. so will be generated from your native code. Libopencv_java3. so will be placed in your libs directory. As shown in figure:
This makes it easy to mix Java and C ++ images without installing OpenCV Manager and automatically importing libOpencv_java3.so. Note: the code to load the so file must be written.
Six, summarized
This tutorial is designed to help newcomers to OpenCV quickly configure. If there are any shortcomings, please accept your suggestions and criticisms. We will make additions and improvements later.
At the same time, we welcome to explore the knowledge of Android image processing, common progress.