Multiple improvements in OpenCV examples build.
authorAlexander Smorkalov <alexander.smorkalov@itseez.com>
Tue, 4 Feb 2014 09:25:47 +0000 (13:25 +0400)
committerAlexander Smorkalov <alexander.smorkalov@itseez.com>
Thu, 6 Feb 2014 11:32:57 +0000 (15:32 +0400)
EMBED_CUDA and FORCE_EMBED_OPENCV flags added to cmake macro add_android_project;
INSTALL_CUDA_LIBRARIES option added to OpenCV.mk
opencv_dynamicuda library installation with enabled OPENCV_INSTALL_MODULES flag fixed;
CUDA initialization apportunity added to OpenCVLoader.initDebug();
Tutorial-4-CUDA sample reimplemented with static OpenCV and CUDA initialization.

cmake/OpenCVDetectAndroidSDK.cmake
cmake/OpenCVGenAndroidMK.cmake
cmake/OpenCVUtils.cmake
cmake/templates/OpenCV.mk.in
modules/java/generator/src/java/android+OpenCVLoader.java
modules/java/generator/src/java/android+StaticHelper.java
samples/android/tutorial-4-cuda/CMakeLists.txt
samples/android/tutorial-4-cuda/jni/Android.mk
samples/android/tutorial-4-cuda/src/org/opencv/samples/tutorial4/Tutorial4Activity.java

index d9e1021..af74271 100644 (file)
@@ -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
index 447aea2..ee52fa6 100644 (file)
@@ -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})
index 13461e8..9fa94bb 100644 (file)
@@ -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})
index 104ddb6..97330e8 100644 (file)
@@ -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
index 46e62eb..0892e3a 100644 (file)
@@ -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);
     }
 
     /**
index 8d0629c..10442c9 100644 (file)
@@ -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)
         {
index a011b33..da9fe98 100644 (file)
@@ -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()
index 3d709df..e14b199 100644 (file)
@@ -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
 
index c1753b6..6a8cb5e 100644 (file)
@@ -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() {