当前位置: 移动技术网 > IT编程>开发语言>Java > cocos creator 集成 opencv native 和 opencv java

cocos creator 集成 opencv native 和 opencv java

2020年07月08日  | 移动技术网IT编程  | 我要评论
时下人工智能大火,公司需要做一个智能识别图案的app,需要在cocos creator中集成opencv,现将趟坑得出的流程记录下来,让有同样需求的技术人少趟坑。操作系统 macOS10.15.5cocos creator 版本 1.9.3android studio 版本opencv 版本 3.0.0为什么不用最新的opencv 4.3.0版本呢,因为我的cocos creator工程用的是ndk14构建的,而opencv4.3.0是用更高版本的ndk构建的,它们之间APP_STL不兼

       时下人工智能大火,公司需要做一个智能识别图案的app,需要在cocos creator中集成opencv,现将趟坑得出的流程记录下来,让有同样需求的技术人少趟坑。

操作系统 macOS10.15.5

cocos creator 版本 1.9.3

android studio 版本 3.5.2

opencv 版本 3.0.0

为什么不用最新的opencv 4.3.0版本呢,因为我的cocos creator工程用的是ndk14构建的,而opencv4.3.0是用更高版本的ndk构建的,它们之间APP_STL不兼容(gnustl_static/c++_shared),ndk14只能用gnustl_static,所以只能降版本到opencv3.0.0了。

考虑到性能问题,用native和jni的方式集成opencv。

又考虑到易用问题,同时集成openv  java包。

一、到opencv官网下载3.0.0版本的android包。

二、cocos creator 用android-26 的 API Level构建android工程。然后将opencv中native目录(上图红框)整个拷贝到android工程中的app目录下面,改名opencv-native,如下图所示:

三、修改app/jni/Android.mk,添加opencv操作模块:

TH := $(call my-dir)


# ============================================原来的cocos2djs模块
include $(CLEAR_VARS)

LOCAL_MODULE := cocos2djs_shared

LOCAL_MODULE_FILENAME := libcocos2djs

ifeq ($(USE_ARM_MODE),1)
LOCAL_ARM_MODE := arm
endif

LOCAL_SRC_FILES := hellojavascript/main.cpp \
                   ../../../Classes/AppDelegate.cpp \
                   ../../../Classes/jsb_module_register.cpp

LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../../Classes

ifeq ($(USE_ANY_SDK),1)
LOCAL_SRC_FILES += ../../../Classes/anysdk/SDKManager.cpp \
                   ../../../Classes/anysdk/jsb_anysdk_basic_conversions.cpp \
                   ../../../Classes/anysdk/manualanysdkbindings.cpp \
                   ../../../Classes/anysdk/jsb_anysdk_protocols_auto.cpp

LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../Classes/anysdk

LOCAL_WHOLE_STATIC_LIBRARIES := PluginProtocolStatic
endif


LOCAL_STATIC_LIBRARIES := cocos2d_js_static

LOCAL_EXPORT_CFLAGS := -DCOCOS2D_DEBUG=2 -DCOCOS2D_JAVASCRIPT


include $(BUILD_SHARED_LIBRARY)


# ============================================新增opencv操作模块
include $(CLEAR_VARS)

OPENCV_INSTALL_MODULES:=on
OPENCV_CAMERA_MODULES:=off
OPENCV_LIB_TYPE:=STATIC

ifeq ("$(wildcard $(OPENCV_MK_PATH))","")
include opencv-native/jni/OpenCV.mk
else
include $(OPENCV_MK_PATH)
endif

LOCAL_MODULE    := opencv
LOCAL_SRC_FILES := ../src/org_cocos2dx_javascript_OpenCVHelper.cpp \
                   ../../../Classes/mycv/android/cJSON.c \
                   ../../../Classes/mycv/android/CVFunc.cpp \
                   ../../../Classes/mycv/android/ObjDetectionBase.cpp \
                   ../../../Classes/mycv/android/ObjDetectionPuzzle.cpp


LOCAL_C_INCLUDES := $(LOCAL_PATH)/../src \
                    $(LOCAL_PATH)/../opencv-native/jni/include \
                    $(LOCAL_PATH)/../../../Classes/mycv/android


LOCAL_LDLIBS += -landroid   ## *【注意:landroid 可以调试打印出android的log信息,否则不行】*
LOCAL_STATIC_LIBRARIES += cpufeatures

include $(BUILD_SHARED_LIBRARY)

# ==============================================================

$(call import-module, scripting/js-bindings/proj.android)

四、修改app/build.gradle,添加opencv模块编译指令:

    defaultConfig {
        applicationId "org.cocos2d.client"
        minSdkVersion 21
        targetSdkVersion PROP_TARGET_SDK_VERSION
        versionCode 1
        versionName "1.0"

        externalNativeBuild {
            ndkBuild {
                if (!project.hasProperty("PROP_NDK_MODE") || PROP_NDK_MODE.compareTo('none') != 0) {
                    // skip the NDK Build step if PROP_NDK_MODE is none
                    targets 'opencv','cocos2djs'
                    arguments 'NDK_TOOLCHAIN_VERSION=4.9'
                    arguments 'APP_PLATFORM=android-' + PROP_TARGET_SDK_VERSION

                    def module_paths = [project.file("../../../cocos2d-x"),
                                        project.file("../../../cocos2d-x/cocos"),
                                        project.file("../../../cocos2d-x/external")]
                    if (Os.isFamily(Os.FAMILY_WINDOWS)) {
                        arguments 'NDK_MODULE_PATH=' + module_paths.join(";")
                    } else {
                        arguments 'NDK_MODULE_PATH=' + module_paths.join(':')
                    }

                    arguments '-j' + Runtime.runtime.availableProcessors()
                    abiFilters.addAll(PROP_APP_ABI.split(':').collect { it as String })
                }
            }
        }

        ndk { //by panda tf
            abiFilters 'x86','armeabi-v7a'
        }
    }

targets 中加上opencv ,如上图所示。

到这里opencv native 就集成完毕了,然后就可以通过jni方式在java中调用opencv c++代码了:

java 文件 app/src/org/cocos2dx.javascript/OpenCVHelper.java:

package org.cocos2dx.javascript;

public class OpenCVHelper {
    static {
        System.loadLibrary("opencv");
    }
    public static native int[] gray(int[] buf, int w, int h);
}

c++ 文件 app/src/org_cocos2dx_javascript_OpenCVHelper.cpp:


#include "org_cocos2dx_javascript_OpenCVHelper.h"
#include <opencv2/opencv.hpp>
#include <string.h>


#include <Android/log.h>
#include <Android/asset_manager.h>
#include <Android/asset_manager_jni.h>

#define TAG "cn.linjk.ihouse.jni"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,TAG ,__VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,TAG ,__VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,TAG ,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,TAG ,__VA_ARGS__)
#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,TAG ,__VA_ARGS__)

////////////////////////////////////////////////////////////////////////////////

extern "C" {

    ////////////////////////////////////////////////////////////////////////////test
JNIEXPORT jintArray JNICALL Java_org_cocos2dx_javascript_OpenCVHelper_gray
        (JNIEnv *env, jclass obj, jintArray buf, jint w, jint h) {

    jint *cbuf;
    cbuf = env->GetIntArrayElements(buf, JNI_FALSE );//将JNI数组转换为基本类型数组
    if (cbuf == NULL) {
        return NULL;
    }

    cv::Mat mat(h, w, CV_8UC4, (unsigned char *)cbuf);
    cv::cvtColor(mat, mat, cv::COLOR_RGBA2GRAY);
    cv::cvtColor(mat, mat, cv::COLOR_GRAY2RGBA);
    int channel = mat.channels();

    int* ptr = (int*)mat.ptr(0);
    int size = w * h;
    jintArray result = env->NewIntArray(size);      //生成新的数组
    env->SetIntArrayRegion(result, 0, size, ptr);   //为result赋值
    env->ReleaseIntArrayElements(buf, cbuf, 0);     //释放内存
    return result;
}

}

然后在android studio的terminal中进入到app/src目录下面执行指令生成 app/src/org_cocos2dx_javascript_OpenCVHelper.h头文件:

javac org/cocos2dx/javascript/OpenCVHelper.java
javah -classpath ./ -jni org.cocos2dx.javascript.OpenCVHelper

然后就可以在java中通过OpenCVHelper.gray(...)调用了。

 

对于集成opencv java包比较简单,直接导入工程就可以了,导入后在app/build.gradle中添加依赖:

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation project(':libcocos2dx')
    implementation project(path: ':openCVLibrary300')
}

以上,打完收工。

 

广告时间:

免费隧道,内网穿透,远程办公可用:

 

本文地址:https://blog.csdn.net/pz060214/article/details/106882826

如您对本文有疑问或者有任何想说的,请 点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网