NDK & OpenCV

如何建立一個OpenCV相機

  • 先建立一個class -> OpenNativeClass.java
// OpenNativeClass.java

public class OpenNativeClass {
    public native static int convertGray(long matAddrRgba, long matAddrGray);
}
  • 這裡convertGray會跳出ERROR,先不用理會,儲存後先Rebuild Project一次
  • 然後到Terminal輸入: cd app/src/main 先進行資料夾切換 再輸入: javah -d jni -classpath ../../build/intermediates/classes/debug YourPackageName.OpenNativeClass

  • 會發現main下面多了一個jni資料夾 先複製your_package_name_OpenNativeClass.h直接貼上,並重新命名為your_package_name_OpenNativeClass.cpp

OpenNativeClass.h修改為:

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

using namespace cv;
using namespace std;
#ifndef _Included_com_klapper_opencvcamera_OpenNativeClass
#define _Included_com_klapper_opencvcamera_OpenNativeClass
#ifdef __cplusplus
extern "C" {
#endif

int toGray(Mat img, Mat& gray);

JNIEXPORT jint JNICALL Java_com_klapper_opencvcamera_OpenNativeClass_convertGray
  (JNIEnv *, jclass, jlong, jlong);

#ifdef __cplusplus
}
#endif
#endif

OpenNativeClass.cpp修改為:

#include <Your_Package_Name_OpenNativeClass.h>

JNIEXPORT jint JNICALL Java_your_package_name_OpenNativeClass_convertGray
  (JNIEnv *, jclass, jlong addrRgba, jlong addrGray){
    Mat& mRgb = *(Mat*)addrRgba;
    Mat& mGray = *(Mat*)addrGray;

    int conv;
    jint retVal;
    conv = toGray(mRgb, mGray);

    retVal = (jint)conv;
    return retVal;
}

    int toGray(Mat img, Mat& gray){
        cvtColor(img, gray, CV_RGBA2GRAY);
        if(gray.rows==img.rows && gray.cols==img.cols)
            return 1;
        return 0;
    }

新增Android.mk & Application.mk

於剛剛.h.cpp檔案的資料夾jni新增兩個檔案

Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

OPENCVROOT:=D:/androidSample/OpenCVCamera/app/src/main
OPENCV_CAMERA_MODULES:=on
OPENCV_INSTALL_MODULES:=on
OPENCV_LIB_TYPE:=SHARED
include ${OPENCVROOT}/native/jni/OpenCV.mk

LOCAL_SRC_FILES  := com_klapper_opencvcamera_OpenNativeClass.cpp

LOCAL_LDLIBS     += -llog -ldl

LOCAL_MODULE     := MyOpencvLibs

include $(BUILD_SHARED_LIBRARY)

Application.mk

APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := armeabi-v7a
APP_PLATFORM := android-16

修改build.gradle

android:
    defaultConfig {

        ...
        ...

        externalNativeBuild {
            cmake {
                cppFlags "-std=c++11","-frtti","-fexceptions"
            }
        }
        ndk{
            abiFilters 'armeabi-v7a','x86', 'armeabi','mips'
        }
    }

    sourceSets.main{
            jni.srcDirs =[]
    }
    task ndkBuild(type: Exec, description: 'Compile JNI source via NDK'){
        commandLine "C:/XXXXXX/AppData/Local/Android/Sdk/ndk-bundle/ndk-build.cmd",
                'NDK_PROJECT_PATH=build/intermediates/ndk',
                'NDK_LIBS_OUT=src/main/jniLibs',
                'APP_BUILD_SCRIPT=src/main/jni/Android.mk',
                'NDK_APPLICATION_MK=src/main/jni/Application.mk'
    }
    tasks.withType(JavaCompile){
        compileTask -> compileTask.dependsOn ndkBuild
    }

基本配置完成

修改主程式- MainActivity.java

public class MainActivity extends AppCompatActivity implements CameraBridgeViewBase.CvCameraViewListener2{
    private static final String TAG = "MainActivity";
    JavaCameraView javaCameraView;
    Mat mRgba, imgGray,imgCanny,mGray;
    static{
        System.loadLibrary("MyOpencvLibs");
    }

    BaseLoaderCallback mLoaderCallBack = new BaseLoaderCallback(this) {
        @Override
        public void onManagerConnected(int status) {
            switch(status){
                case BaseLoaderCallback.SUCCESS:
                    javaCameraView.enableView();
                    break;
                default:
                    super.onManagerConnected(status);
                    break;
            }
            super.onManagerConnected(status);
        }
    };


    static {

    }

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

        javaCameraView = (JavaCameraView)findViewById(R.id.java_camera_view);

        javaCameraView.setVisibility(SurfaceView.VISIBLE);
        javaCameraView.setCvCameraViewListener(this);


    }


    @Override
    protected void onPause(){
        super.onPause();
        if(javaCameraView!=null)
            javaCameraView.disableView();
    }

    @Override
    protected void onDestroy(){
        super.onDestroy();
        if(javaCameraView!=null)
            javaCameraView.disableView();
    }

    @Override
    protected void onResume(){
        super.onResume();
        if(OpenCVLoader.initDebug()){
            Log.d(TAG, "static initializer: successfully");
            mLoaderCallBack.onManagerConnected(LoaderCallbackInterface.SUCCESS);
        }else{
            Log.d(TAG, "static initializer: Load fault.");
            OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_13,this,mLoaderCallBack);
        }
    }


    @Override
    public void onCameraViewStarted(int width, int height) {
        mRgba = new Mat(height,width, CvType.CV_8UC4);
        mGray = new Mat(height,width, CvType.CV_8UC1);
        imgGray = new Mat(height,width, CvType.CV_8UC1);
        imgCanny = new Mat(height,width, CvType.CV_8UC4);

    }

    @Override
    public void onCameraViewStopped() {
        mRgba.release();
    }

    @Override
    public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
        mRgba = inputFrame.rgba();

        OpenNativeClass.convertGray(mRgba.getNativeObjAddr(),mGray.getNativeObjAddr());

        //Imgproc.cvtColor(mRgba,imgGray,Imgproc.COLOR_RGB2GRAY);
        //Imgproc.Canny(imgGray,imgCanny,30,150);

        return mGray;
    }
}

於activity_layout.xml 新增widget

<org.opencv.android.JavaCameraView
        android:id="@+id/java_camera_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

於AndroidManifest.xml 新增權限

<uses-permission android:name="android.permission.CAMERA"/>
    <uses-feature android:name="android.hardware.camera" android:required="false"/>
    <uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
    <uses-feature android:name="android.hardware.camera.front" android:required="false"/>
    <uses-feature android:name="android.hardware.camera.front.autofocus" android:required="false"/>

results matching ""

    No results matching ""