diff --git a/cmake/OpenCVDetectAndroidSDK.cmake b/cmake/OpenCVDetectAndroidSDK.cmake index d9e10213ae..af7427194e 100644 --- a/cmake/OpenCVDetectAndroidSDK.cmake +++ b/cmake/OpenCVDetectAndroidSDK.cmake @@ -180,7 +180,7 @@ unset(__android_project_chain CACHE) # add_android_project(target_name ${path} NATIVE_DEPS opencv_core LIBRARY_DEPS ${OpenCV_BINARY_DIR} SDK_TARGET 11) macro(add_android_project target path) # parse arguments - set(android_proj_arglist NATIVE_DEPS LIBRARY_DEPS SDK_TARGET IGNORE_JAVA IGNORE_MANIFEST) + set(android_proj_arglist NATIVE_DEPS LIBRARY_DEPS SDK_TARGET IGNORE_JAVA IGNORE_MANIFEST EMBED_CUDA FORCE_EMBED_OPENCV) set(__varname "android_proj_") foreach(v ${android_proj_arglist}) set(${__varname}${v} "") @@ -303,6 +303,46 @@ macro(add_android_project target path) add_custom_command(TARGET ${JNI_LIB_NAME} POST_BUILD COMMAND ${CMAKE_STRIP} --strip-unneeded "${android_proj_jni_location}") endif() endif() + + # copy opencv_java, tbb if it is shared and dynamicuda if present if FORCE_EMBED_OPENCV flag is set + if(android_proj_FORCE_EMBED_OPENCV) + set(native_deps ${android_proj_NATIVE_DEPS}) + # filter out gpu module as it is always static library on Android + list(REMOVE_ITEM native_deps "opencv_gpu") + if(ENABLE_DYNAMIC_CUDA) + list(APPEND native_deps "opencv_dynamicuda") + endif() + foreach(lib ${native_deps}) + get_property(f TARGET ${lib} PROPERTY LOCATION) + get_filename_component(f_name ${f} NAME) + add_custom_command( + OUTPUT "${android_proj_bin_dir}/libs/${ANDROID_NDK_ABI_NAME}/${f_name}" + COMMAND ${CMAKE_COMMAND} -E copy "${f}" "${android_proj_bin_dir}/libs/${ANDROID_NDK_ABI_NAME}/${f_name}" + DEPENDS "${lib}" VERBATIM + COMMENT "Embedding ${f}") + list(APPEND android_proj_file_deps "${android_proj_bin_dir}/libs/${ANDROID_NDK_ABI_NAME}/${f_name}") + endforeach() + endif() + + # copy all needed CUDA libs to project if EMBED_CUDA flag is present + if(android_proj_EMBED_CUDA) + set(android_proj_culibs ${CUDA_npp_LIBRARY} ${CUDA_LIBRARIES}) + if(HAVE_CUFFT) + list(INSERT android_proj_culibs 0 ${CUDA_cufft_LIBRARY}) + endif() + if(HAVE_CUBLAS) + list(INSERT android_proj_culibs 0 ${CUDA_cublas_LIBRARY}) + endif() + foreach(lib ${android_proj_culibs}) + get_filename_component(f "${lib}" NAME) + add_custom_command( + OUTPUT "${android_proj_bin_dir}/libs/${ANDROID_NDK_ABI_NAME}/${f}" + COMMAND ${CMAKE_COMMAND} -E copy "${lib}" "${android_proj_bin_dir}/libs/${ANDROID_NDK_ABI_NAME}/${f}" + DEPENDS "${lib}" VERBATIM + COMMENT "Embedding ${f}") + list(APPEND android_proj_file_deps "${android_proj_bin_dir}/libs/${ANDROID_NDK_ABI_NAME}/${f}") + endforeach() + endif() endif() # build java part diff --git a/cmake/OpenCVGenAndroidMK.cmake b/cmake/OpenCVGenAndroidMK.cmake index 45193a2732..cacc6ca22e 100644 --- a/cmake/OpenCVGenAndroidMK.cmake +++ b/cmake/OpenCVGenAndroidMK.cmake @@ -59,6 +59,24 @@ if(ANDROID) ocv_list_filterout(OPENCV_EXTRA_COMPONENTS_CONFIGMAKE "libcu") ocv_list_filterout(OPENCV_EXTRA_COMPONENTS_CONFIGMAKE "libnpp") + if(HAVE_CUDA) + # CUDA runtime libraries and are required always + set(culibs ${CUDA_LIBRARIES}) + + # right now NPP is requared always too + list(INSERT culibs 0 ${CUDA_npp_LIBRARY}) + + if(HAVE_CUFFT) + list(INSERT culibs 0 ${CUDA_cufft_LIBRARY}) + endif() + + if(HAVE_CUBLAS) + list(INSERT culibs 0 ${CUDA_cublas_LIBRARY}) + endif() + endif() + + ocv_convert_to_lib_name(CUDA_RUNTIME_LIBS_CONFIGMAKE ${culibs}) + # split 3rdparty libs and modules foreach(mod ${OPENCV_MODULES_CONFIGMAKE}) if(NOT mod MATCHES "^opencv_.+$") @@ -69,6 +87,10 @@ if(ANDROID) list(REMOVE_ITEM OPENCV_MODULES_CONFIGMAKE ${OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE}) endif() + if(ENABLE_DYNAMIC_CUDA) + set(OPENCV_DYNAMICUDA_MODULE_CONFIGMAKE "dynamicuda") + endif() + # GPU module enabled separately list(REMOVE_ITEM OPENCV_MODULES_CONFIGMAKE "opencv_gpu") list(REMOVE_ITEM OPENCV_MODULES_CONFIGMAKE "opencv_dynamicuda") @@ -84,6 +106,7 @@ if(ANDROID) string(REPLACE ";" " " ${lst} "${${lst}}") endforeach() string(REPLACE "opencv_" "" OPENCV_MODULES_CONFIGMAKE "${OPENCV_MODULES_CONFIGMAKE}") + string(REPLACE ";" " " CUDA_RUNTIME_LIBS_CONFIGMAKE "${CUDA_RUNTIME_LIBS_CONFIGMAKE}") # prepare 3rd-party component list without TBB for armeabi and mips platforms. TBB is useless there. set(OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE_NO_TBB ${OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE}) diff --git a/cmake/OpenCVUtils.cmake b/cmake/OpenCVUtils.cmake index 13461e82c1..9fa94bb8bd 100644 --- a/cmake/OpenCVUtils.cmake +++ b/cmake/OpenCVUtils.cmake @@ -448,6 +448,20 @@ macro(ocv_convert_to_full_paths VAR) endmacro() +# convert list of paths to libraries names without lib prefix +macro(ocv_convert_to_lib_name var) + set(__tmp "") + foreach(path ${ARGN}) + get_filename_component(__tmp_name "${path}" NAME_WE) + string(REGEX REPLACE "^lib" "" __tmp_name ${__tmp_name}) + list(APPEND __tmp "${__tmp_name}") + endforeach() + set(${var} ${__tmp}) + unset(__tmp) + unset(__tmp_name) +endmacro() + + # add install command function(ocv_install_target) install(TARGETS ${ARGN}) diff --git a/cmake/templates/OpenCV.mk.in b/cmake/templates/OpenCV.mk.in index 104ddb6dd2..97330e8545 100644 --- a/cmake/templates/OpenCV.mk.in +++ b/cmake/templates/OpenCV.mk.in @@ -19,8 +19,9 @@ OPENCV_3RDPARTY_LIBS_DIR:=@OPENCV_3RDPARTY_LIBS_DIR_CONFIGCMAKE@ OPENCV_BASEDIR:=@OPENCV_BASE_INCLUDE_DIR_CONFIGCMAKE@ OPENCV_LOCAL_C_INCLUDES:=@OPENCV_INCLUDE_DIRS_CONFIGCMAKE@ OPENCV_MODULES:=@OPENCV_MODULES_CONFIGMAKE@ +OPENCV_DYNAMICUDA_MODULE:=@OPENCV_DYNAMICUDA_MODULE_CONFIGMAKE@ -OPENCV_HAVE_GPU_MODULE=@OPENCV_HAVE_GPU_MODULE_CONFIGMAKE@ +OPENCV_HAVE_GPU_MODULE:=@OPENCV_HAVE_GPU_MODULE_CONFIGMAKE@ OPENCV_USE_GPU_MODULE:= ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) @@ -31,7 +32,7 @@ ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) endif endif -CUDA_RUNTIME_LIBS:=cufft npps nppi nppc cudart +CUDA_RUNTIME_LIBS:=@CUDA_RUNTIME_LIBS_CONFIGMAKE@ ifeq ($(OPENCV_LIB_TYPE),) OPENCV_LIB_TYPE:=@OPENCV_LIBTYPE_CONFIGMAKE@ @@ -67,7 +68,7 @@ else endif endif -ifeq (${OPENCV_CAMERA_MODULES},on) +ifeq ($(OPENCV_CAMERA_MODULES),on) ifeq ($(TARGET_ARCH_ABI),armeabi) OPENCV_CAMERA_MODULES:=@OPENCV_CAMERA_LIBS_ARMEABI_CONFIGCMAKE@ endif @@ -98,6 +99,13 @@ define add_opencv_module include $(PREBUILT_$(OPENCV_LIB_TYPE)_LIBRARY) endef +define add_cuda_module + include $(CLEAR_VARS) + LOCAL_MODULE:=$1 + LOCAL_SRC_FILES:=$(CUDA_TOOLKIT_DIR)/targets/armv7-linux-androideabi/lib/lib$1.so + include $(PREBUILT_SHARED_LIBRARY) +endef + define add_opencv_3rdparty_component include $(CLEAR_VARS) LOCAL_MODULE:=$1 @@ -115,6 +123,15 @@ endef ifeq ($(OPENCV_MK_$(OPENCV_TARGET_ARCH_ABI)_ALREADY_INCLUDED),) ifeq ($(OPENCV_INSTALL_MODULES),on) $(foreach module,$(OPENCV_LIBS),$(eval $(call add_opencv_module,$(module)))) + ifneq ($(OPENCV_DYNAMICUDA_MODULE),) + $(eval $(call add_opencv_module,$(OPENCV_DYNAMICUDA_MODULE))) + endif + endif + + ifeq ($(OPENCV_USE_GPU_MODULE),on) + ifeq ($(INSTALL_CUDA_LIBRARIES),on) + $(foreach module,$(CUDA_RUNTIME_LIBS),$(eval $(call add_cuda_module,$(module)))) + endif endif $(foreach module,$(OPENCV_3RDPARTY_COMPONENTS),$(eval $(call add_opencv_3rdparty_component,$(module)))) @@ -159,6 +176,11 @@ endif ifeq ($(OPENCV_INSTALL_MODULES),on) LOCAL_$(OPENCV_LIB_TYPE)_LIBRARIES += $(foreach mod, $(OPENCV_LIBS), opencv_$(mod)) + ifeq ($(OPENCV_LIB_TYPE),SHARED) + ifneq ($(OPENCV_DYNAMICUDA_MODULE),) + LOCAL_$(OPENCV_LIB_TYPE)_LIBRARIES += $(OPENCV_DYNAMICUDA_MODULE) + endif + endif else LOCAL_LDLIBS += -L$(call host-path,$(LOCAL_PATH)/$(OPENCV_LIBS_DIR)) $(foreach lib, $(OPENCV_LIBS), -lopencv_$(lib)) endif @@ -170,8 +192,12 @@ endif LOCAL_LDLIBS += $(foreach lib,$(OPENCV_EXTRA_COMPONENTS), -l$(lib)) ifeq ($(OPENCV_USE_GPU_MODULE),on) + ifeq ($(INSTALL_CUDA_LIBRARIES),on) + LOCAL_SHARED_LIBRARIES += $(foreach mod, $(CUDA_RUNTIME_LIBS), $(mod)) + else + LOCAL_LDLIBS += -L$(CUDA_TOOLKIT_DIR)/targets/armv7-linux-androideabi/lib $(foreach lib, $(CUDA_RUNTIME_LIBS), -l$(lib)) + endif LOCAL_STATIC_LIBRARIES+=libopencv_gpu - LOCAL_LDLIBS += -L$(CUDA_TOOLKIT_DIR)/targets/armv7-linux-androideabi/lib $(foreach lib, $(CUDA_RUNTIME_LIBS), -l$(lib)) endif #restore the LOCAL_PATH diff --git a/modules/java/generator/src/java/android+OpenCVLoader.java b/modules/java/generator/src/java/android+OpenCVLoader.java index 46e62eb347..0892e3af3c 100644 --- a/modules/java/generator/src/java/android+OpenCVLoader.java +++ b/modules/java/generator/src/java/android+OpenCVLoader.java @@ -48,7 +48,17 @@ public class OpenCVLoader */ public static boolean initDebug() { - return StaticHelper.initOpenCV(); + return StaticHelper.initOpenCV(false); + } + + /** + * Loads and initializes OpenCV library from current application package. Roughly, it's an analog of system.loadLibrary("opencv_java"). + * @param InitCuda load and initialize CUDA runtime libraries. + * @return Returns true is initialization of OpenCV was successful. + */ + public static boolean initDebug(boolean InitCuda) + { + return StaticHelper.initOpenCV(InitCuda); } /** diff --git a/modules/java/generator/src/java/android+StaticHelper.java b/modules/java/generator/src/java/android+StaticHelper.java index 8d0629c8d3..10442c904d 100644 --- a/modules/java/generator/src/java/android+StaticHelper.java +++ b/modules/java/generator/src/java/android+StaticHelper.java @@ -7,11 +7,21 @@ import android.util.Log; class StaticHelper { - public static boolean initOpenCV() + public static boolean initOpenCV(boolean InitCuda) { boolean result; String libs = ""; + if(InitCuda) + { + loadLibrary("cudart"); + loadLibrary("nppc"); + loadLibrary("nppi"); + loadLibrary("npps"); + loadLibrary("cufft"); + loadLibrary("cublas"); + } + Log.d(TAG, "Trying to get library list"); try @@ -52,7 +62,7 @@ class StaticHelper { try { System.loadLibrary(Name); - Log.d(TAG, "OpenCV libs init was ok!"); + Log.d(TAG, "Library " + Name + " loaded"); } catch(UnsatisfiedLinkError e) { diff --git a/samples/android/tutorial-4-cuda/CMakeLists.txt b/samples/android/tutorial-4-cuda/CMakeLists.txt index a011b33492..da9fe9871d 100644 --- a/samples/android/tutorial-4-cuda/CMakeLists.txt +++ b/samples/android/tutorial-4-cuda/CMakeLists.txt @@ -1,15 +1,16 @@ set(sample example-tutorial-4-cuda) -ocv_check_dependencies(opencv_core opencv_java opencv_gpu) +ocv_check_dependencies(opencv_core opencv_features2d opencv_java opencv_gpu) if (OCV_DEPENDENCIES_FOUND) if(BUILD_FAT_JAVA_LIB) set(native_deps opencv_java opencv_gpu) else() - set(native_deps opencv_gpu) + set(native_deps opencv_core opencv_features2d opencv_java opencv_gpu) endif() - add_android_project(${sample} "${CMAKE_CURRENT_SOURCE_DIR}" LIBRARY_DEPS ${OpenCV_BINARY_DIR} SDK_TARGET 11 ${ANDROID_SDK_TARGET} NATIVE_DEPS ${native_deps}) + add_android_project(${sample} "${CMAKE_CURRENT_SOURCE_DIR}" LIBRARY_DEPS ${OpenCV_BINARY_DIR} SDK_TARGET 11 ${ANDROID_SDK_TARGET} NATIVE_DEPS ${native_deps} EMBED_CUDA ON FORCE_EMBED_OPENCV ON) + if(TARGET ${sample}) add_dependencies(opencv_android_examples ${sample}) endif() diff --git a/samples/android/tutorial-4-cuda/jni/Android.mk b/samples/android/tutorial-4-cuda/jni/Android.mk index 3d709dff3b..e14b1990f2 100644 --- a/samples/android/tutorial-4-cuda/jni/Android.mk +++ b/samples/android/tutorial-4-cuda/jni/Android.mk @@ -2,6 +2,8 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) +INSTALL_CUDA_LIBRARIES:=on +OPENCV_INSTALL_MODULES:=on CUDA_TOOLKIT_DIR=$(CUDA_TOOLKIT_ROOT) include ../../sdk/native/jni/OpenCV.mk diff --git a/samples/android/tutorial-4-cuda/src/org/opencv/samples/tutorial4/Tutorial4Activity.java b/samples/android/tutorial-4-cuda/src/org/opencv/samples/tutorial4/Tutorial4Activity.java index c1753b68cc..6a8cb5ec04 100644 --- a/samples/android/tutorial-4-cuda/src/org/opencv/samples/tutorial4/Tutorial4Activity.java +++ b/samples/android/tutorial-4-cuda/src/org/opencv/samples/tutorial4/Tutorial4Activity.java @@ -49,29 +49,6 @@ public class Tutorial4Activity extends Activity implements CvCameraViewListener2 { Log.i(TAG, "OpenCV loaded successfully"); - // Check CUDA support - if (Gpu.getCudaEnabledDeviceCount() <= 0) - { - Log.e(TAG, "No CUDA capable device found!"); - AlertDialog InitFailedDialog = new AlertDialog.Builder(Tutorial4Activity.this).create(); - InitFailedDialog.setTitle("OpenCV CUDA error"); - InitFailedDialog.setMessage("CUDA compatible device was not found!"); - InitFailedDialog.setCancelable(false); // This blocks the 'BACK' button - InitFailedDialog.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new OnClickListener() { - - public void onClick(DialogInterface dialog, int which) { - Tutorial4Activity.this.finish(); - } - }); - InitFailedDialog.show(); - } - else - { - // Load native library after(!) OpenCV initialization - Log.i(TAG, "Found CUDA capable device!"); - System.loadLibrary("cuda_sample"); - mOpenCvCameraView.enableView(); - } } break; default: { @@ -120,7 +97,32 @@ public class Tutorial4Activity extends Activity implements CvCameraViewListener2 public void onResume() { super.onResume(); - OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_8, this, mLoaderCallback); + if (OpenCVLoader.initDebug(true)) + { + // Check CUDA support + if (Gpu.getCudaEnabledDeviceCount() <= 0) + { + Log.e(TAG, "No CUDA capable device found!"); + AlertDialog InitFailedDialog = new AlertDialog.Builder(Tutorial4Activity.this).create(); + InitFailedDialog.setTitle("OpenCV CUDA error"); + InitFailedDialog.setMessage("CUDA compatible device was not found!"); + InitFailedDialog.setCancelable(false); // This blocks the 'BACK' button + InitFailedDialog.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + Tutorial4Activity.this.finish(); + } + }); + InitFailedDialog.show(); + } + else + { + // Load native library after(!) OpenCV initialization + Log.i(TAG, "Found CUDA capable device!"); + System.loadLibrary("cuda_sample"); + mOpenCvCameraView.enableView(); + } + + } } public void onDestroy() {