2

Android Project that I am facing error has OpenCV & custom implementation of some cpp classes for image processing. I have include opencv-3-3-0-android-sdk in CMakeLists.txt which is used for building native components.

 include_directories( ../opencv-3-3-0-android-sdk/sdk/native/jni/include/)
 add_library( lib_opencv
         SHARED
         IMPORTED )
 set_target_properties( lib_opencv
                   PROPERTIES IMPORTED_LOCATION
                   ${PROJECT_SOURCE_DIR}/../opencv-3-3-0-android-sdk/sdk/native/libs/${ANDROID_ABI}/libopencv_java3.so )

While invoking following method it throws error:

void saveMat(const cv::Mat& mat, std::string dst){
        cv::imwrite(dst, mat);//throws error - undefined reference
}

Getting following error while running the project which states that cannot reference to imwrite. Though

 error: undefined reference to 'cv::imwrite(cv::String const&, cv::_InputArray const&, std::__ndk1::vector<int, std::__ndk1::allocator<int> > const&)'.

Though on navigation to that function using ctrl does take me to proper function which is inside opencv2/imgcodecs.hpp.

 CV_EXPORTS_W bool imwrite( const String& filename, InputArray img,
          const std::vector<int>& params = std::vector<int>());

To me it seems like linkage error. Is there any idea why while running the application it throws above mentioned error?

Vikalp Patel
  • 10,669
  • 6
  • 61
  • 96
  • Is your opencv built with gnu_stl? Do you use c++_stl in your native code? – Dmitrii Z. Dec 05 '18 at 11:18
  • @DmitriiZ. Using C++_Stl for native code. – Vikalp Patel Dec 05 '18 at 11:24
  • You need to either use gnu_stl in your native code or build opencv with c++_stl. – Dmitrii Z. Dec 05 '18 at 11:24
  • See https://stackoverflow.com/questions/52886556/how-to-rebuild-opencv-with-c-static/52886775#52886775 – Dmitrii Z. Dec 05 '18 at 11:25
  • @DmitriiZ. Thanks dude. But I'm using `opencv-3-3-0-android-sdk` which is the output of running make & make install command. Please enlighten me more on this. – Vikalp Patel Dec 05 '18 at 11:30
  • And was it configured to use c++_stl? (the first command in linked answer) Note that by default opencv is built with gnu_stl, so if you just download it from opencv website - you would need to use gnu_stl. – Dmitrii Z. Dec 05 '18 at 11:57
  • @DmitriiZ. Can you tell me how one can figure it out whether it's configured using c++_stl or gnu_stl? As I have got this whole project bundled with opencv3.3.0 android sdk. So not sure whether they downloaded and then build or not. – Vikalp Patel Dec 05 '18 at 12:17
  • @VikalpPatel Have you solved this problem? – Jess Yuan Dec 12 '19 at 03:10

1 Answers1

0

I have encountered this same issue, except 3 years after the OP I am now working with version 4.5.5 of the OpenCV for Android SDK.

The solution to the linking error is to make sure CMake can find the necessary library package via a little configuration setting in your CMakeLists.txt

In older versions of OpenCV the library might have been released as a single large (monolithic) library, the "lib_opencv" that your CMakeLists.txt references.

However OpenCV has grown too large to lump it all into a single library, when your Android loads the library via JNI it takes up valuable memory, which is a critical resource on mobile platforms. So OpenCV currently provides a core library plus a number of optional libraries/packages. You will always load the core library but only load the optional packages your application actually needs.

My CMakeLists.txt looks like this (note you might need different settings depending on your version of CMAKE and OpenCV):

project(mynativeapp)

cmake_minimum_required(VERSION 3.18)

set(OpenCV_DIR ${CMAKE_SOURCE_DIR}/opencv-mobile-4.5.5-android/sdk/native/jni)
# include any additional OpenCV package names in the argument list below:
find_package(OpenCV REQUIRED core imgproc imgcodecs)

add_library(mynativeapp SHARED mynativeapp.cpp myalgorithm.cpp ndkcamera.cpp)

target_link_libraries(mynativeapp ${OpenCV_LIBS} camera2ndk mediandk)

In my case the linking error disappeared as soon as I added imgcodecs to the find_package() argument list.

gb96
  • 1,674
  • 1
  • 18
  • 26