cocos creator 集成 opencv native 和 opencv java
时下人工智能大火,公司需要做一个智能识别图案的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