欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

cocos creator 集成 opencv native 和 opencv java

程序员文章站 2022-03-07 11:53:42
时下人工智能大火,公司需要做一个智能识别图案的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 集成 opencv native 和 opencv java

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

cocos creator 集成 opencv native 和 opencv java

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

cocos creator 集成 opencv native 和 opencv java

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