Android Studio NDK + OpenCV2

1. Background: NDK + JNI: It is equivalent to a middleware, which provides a native way for Java to call C/C++ code.
2. Principles and processes that you understand: C/C++ code is compiled into so (dynamic link library [CSAPP]) through NDK, and Java can get the interfaces in the C/C++ code by loading these sos, so that these interfaces can be called.

3. Process:
1) First, you need to configure the basic environment: Java + AS3.0 + LLDB + CMAKE. (SDK Manager)
2) NDK: We can go to the official website to download the official website -> extract the compressed package to the directory with the SDK.
write picture description here
3) OpenCV: Download the corresponding package from the official website .
4) Unzip the downloaded package to a folder where your user has read and write permissions.
5) Create a new project: Create it in the default way. [I tried it myself by using CMakeList, and I will add it later]
6) Create a new folder named jni under app/src/main:
write picture description here
7) Copy the Opencv/sdk/native folder into the project:
write picture description here
8) Create Android.mk Application.mk related .h and .cpp files under the jni folder just created:
write picture description here
9) Create your own interface:

#include <stdio.h>
#include <stdlib.h>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

extern "C" {
    JNIEXPORT jintArray JNICALL Java_com_example_za_xxxxxx_myapplication_TestOpen_gray
        (JNIEnv *env, jobject obj, jintArray buf, jint w, jint h) {
        jint *cbuf;
        cbuf = env->GetIntArrayElements(buf, JNI_FALSE);
        if (cbuf == NULL) {
            return 0;
        }

        Mat imgData(h, w, CV_8UC4, (unsigned char*) cbuf);

        uchar* ptr = imgData.ptr(0);
        for (int i = 0;i < w * h; ++i) {
            int grayScale = (int)(ptr[4*i+2]*0.299 + ptr[4*i+1]*0.587 + ptr[4*i+0]*0.114);
            ptr[4*i+1] = grayScale;
            ptr[4*i+2] = grayScale;
            ptr[4*i+0] = grayScale;
        }
        int size = w * h;
        jintArray result = env->NewIntArray(size);
        env->SetIntArrayRegion(result, 0, size, cbuf);
        env->ReleaseIntArrayElements(buf, cbuf, 0);
        return result;
    }

}

Among them: JNI interface naming rules:

JNIEXPORT Return type JNICALL Java_package name class name function name (you can also use javah to generate .h files)

10) Write Android.mk and Application.mk files:

#Android.mk
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

OpenCV_INSTALL_MODULES := on
OpenCV_CAMERA_MODULES := off

OPENCV_LIB_TYPE := STATIC

#为了能正确找到opencv的头文件,需要自己定义路径,在这个例子里面是这个路径,其他的视情况而定。
#ifeq ("$(wildcard $(OPENCV_MK_PATH"))", "")
include ..\..\..\..\native\jni\OpenCV.mk
#else
#include $(OPENCV_MK_PATH)
#endif

LOCAL_MODULE := test-open

#自己的文件名
LOCAL_SRC_FILES := com_example_za_xxxxxx_myapplication_TestOpen.cpp

LOCAL_LDLIBS += -lm -llog

include $(BUILD_SHARED_LIBRARY)
#使用GNU的静态(.a)STL
APP_STL := gnustl_static

#支持动态类型绑定,加入异常机制
APP_CPPFLAGS := -frtti -fexceptions

#需要编译的so的平台前面两个是大部分手机使用的平台,X86是模拟器
APP_ABI := armeabi armeabi-v7a x86

11) Create a .java under the java folder:
write picture description here
12) Java code:

public class TestOpen {
    static {
        System.loadLibrary("test-open");
    }

    public static native int[] gray(int[] buf, int w, int h);
}

The function definition in this step can be combined with the interface definition in the .cpp file, and you can roughly know the naming rules in the .cpp file.

13) Use the command line to enter the jni directory, ndk-build project:
write picture description here
14) In order to correctly reference the so compiled just now, we need to add relevant references to the build.gradle file of the app: the
write picture description here
last sentence is the reference to so, the countdown The second sentence is to prohibit the built-in NDK function.

15) Define the layout of the Activity and related Java code:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.za_xxxxxx.myapplication.MainActivity"
    android:orientation="vertical">

    <TextView
        android:id="@+id/main_textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        />

    <ImageView
        android:id="@+id/main_imageview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/blood"/>

    <Button
        android:id="@+id/main_button"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="Convert"
        android:textAlignment="center"
        android:textAllCaps="false"/>

    </LinearLayout>
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button = findViewById(R.id.main_button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Bitmap bitmap = ((BitmapDrawable)getResources().getDrawable(R.drawable.blood)).getBitmap();
                int w = bitmap.getWidth();
                int h = bitmap.getHeight();
                int[] pix = new int[w * h];
                bitmap.getPixels(pix, 0, w, 0, 0, w, h);
                int[] resultPixes = TestOpen.gray(pix, w, h);
                Bitmap result = Bitmap.createBitmap(w, h, Bitmap.Config.RGB_565);
                result.setPixels(resultPixes, 0, w, 0, 0, w, h);
                ImageView imageView = findViewById(R.id.main_imageview);
                imageView.setImageBitmap(result);
            }
        });
    }
}

16) Run the APP, you can get the following effects:
write picture description here
write picture description here

At this point, the project can be developed using OpenCV.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325898597&siteId=291194637