Search code examples
androidc++opencvndk-build

Issue using functions from opencv shared libraries cross compiled for android


I was trying to build and execute a cpp code that links few opencv shared libraries that I had cross compiled for android but while trying to utilize the namespace cv or trying to use a function of opencv, it says undeclared identifier. I did try this documentation here: https://developer.android.com/ndk/guides/prebuilts but was unable to get it working. Also I referred to another stackoverflow question for reference here: OpenCV with Android NDK Undefined References as well. Any guidance on how to link them and import opencv functions properly which I am probably missing out here would be really helpful.

trial_onnx.cpp file

#include <iostream>
#include <fstream>
#include <cstring>
#include <opencv2/ml/ml.hpp>
#include <opencv2/dnn/dnn.hpp>
#include <opencv2/imgcodecs/imgcodecs.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/core/mat.hpp>

    
#include "trial_onnx.h"

using namespace std;


void execute_main() {
    std::cout << "Hello World"<<std::endl;

    cv::Mat mat1;
    
}

trial_onnx.h file

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

void execute_main();
#ifdef __cplusplus
}
#endif // __cplusplus

Android.mk file

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := opencv_ml
LOCAL_SRC_FILES := /home/ubuntu/trial/opencv-4.5.5-android-sdk/OpenCV-android-sdk/sdk/native/libs/arm64-v8a/libopencv_ml.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)

LOCAL_MODULE := opencv_dnn
LOCAL_SRC_FILES := /home/ubuntu/trial/opencv-4.5.5-android-sdk/OpenCV-android-sdk/sdk/native/libs/arm64-v8a/libopencv_dnn.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
#LOCAL_PATH := $(call my-dir)


LOCAL_MODULE := opencv_imgcodecs
LOCAL_SRC_FILES := /home/ubuntu/trial/opencv-4.5.5-android-sdk/OpenCV-android-sdk/sdk/native/libs/arm64-v8a/libopencv_imgcodecs.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)

#LOCAL_PATH := $(call my-dir)

LOCAL_MODULE := opencv_imgproc
LOCAL_SRC_FILES := /home/ubuntu/trial/opencv-4.5.5-android-sdk/OpenCV-android-sdk/sdk/native/libs/arm64-v8a/libopencv_imgproc.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)

#LOCAL_PATH := $(call my-dir)

LOCAL_MODULE := opencv_core
LOCAL_SRC_FILES := /home/ubuntu/trial/opencv-4.5.5-android-sdk/OpenCV-android-sdk/sdk/native/libs/arm64-v8a/libopencv_core.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)

LOCAL_MODULE := opencv_highgui
LOCAL_SRC_FILES := /home/ubuntu/trial/opencv-4.5.5-android-sdk/OpenCV-android-sdk/sdk/native/libs/arm64-v8a/libopencv_highgui.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)

LOCAL_SHARED_LIBRARIES = opencv_ml opencv_dnn opencv_imgcodecs opencv_highgui opencv_imgproc opencv_core opencv


LOCAL_ARM_MODE := arm
    

LOCAL_MODULE   := libtrial


LOCAL_SRC_FILES := inc/trial_onnx.h src/trial_onnx.cpp 

LOCAL_C_INCLUDES := ${LOCAL_PATH}/inc

LOCAL_LDLIBS += -llog -ldl

Output

[arm64-v8a] Install        : libopencv_core.so => libs/arm64-v8a/libopencv_core.so
[arm64-v8a] Install        : libopencv_dnn.so => libs/arm64-v8a/libopencv_dnn.so
[arm64-v8a] Install        : libopencv_highgui.so => libs/arm64-v8a/libopencv_highgui.so
[arm64-v8a] Install        : libopencv_imgcodecs.so => libs/arm64-v8a/libopencv_imgcodecs.so
[arm64-v8a] Install        : libopencv_imgproc.so => libs/arm64-v8a/libopencv_imgproc.so
[arm64-v8a] Install        : libopencv_ml.so => libs/arm64-v8a/libopencv_ml.so
[arm64-v8a] Compile++      : trial <= trial_onnx.cpp
[arm64-v8a] SharedLibrary  : lib_trial.so
./obj/local/arm64-v8a/objs/trial/src/trial_onnx.o: In function `execute_main':
/home/ubuntu//trial/./src/trial_onnx.cpp:19: undefined reference to `cv::Mat::Mat()'
/home/ubuntu/trial/./src/trial_onnx.cpp:21: undefined reference to `cv::Mat::~Mat()'
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [obj/local/arm64-v8a/lib_trial.so] Error 1

If I skip using cv:: in the cpp file the following outputs pops up, this does make sense but its able to identify the cv::Mat type is present in core/mat.hpp then why not identify cv::mat in other case baffles me:

    [arm64-v8a] Install        : libopencv_core.so => libs/arm64-v8a/libopencv_core.so
    [arm64-v8a] Install        : libopencv_dnn.so => libs/arm64-v8a/libopencv_dnn.so
    [arm64-v8a] Install        : libopencv_highgui.so => libs/arm64-v8a/libopencv_highgui.so
    [arm64-v8a] Install        : libopencv_imgcodecs.so => libs/arm64-v8a/libopencv_imgcodecs.so
    [arm64-v8a] Install        : libopencv_imgproc.so => libs/arm64-v8a/libopencv_imgproc.so
    [arm64-v8a] Install        : libopencv_ml.so => libs/arm64-v8a/libopencv_ml.so
    [arm64-v8a] Compile++      : trial <= trial_onnx.cpp
    [arm64-v8a] SharedLibrary  : lib_trial.so
./src/trial_onnx.cpp:19:5: error: unknown type name 'Mat'; did you mean
      'cv::Mat'?
    Mat mat1;
    ^~~
    cv::Mat

./opencv2/core/mat.hpp:801:18: note: 'cv::Mat' declared here
class CV_EXPORTS Mat
                 ^
1 error generated.

Solution

  • I've fixed the issue myself, it was a linking issue along with modifying the Android.mk file accordingly. For others who may encounter the issue: My Android.Mk file after the fix looks like

    LOCAL_PATH := $(call my-dir)
    
    include $(CLEAR_VARS)
    LOCAL_ARM_MODE := arm
    
      
    
    include $(CLEAR_VARS)
    
    LOCAL_MODULE := opencv_core
    LOCAL_SRC_FILES := /home/ubuntu/opencv/modules/core/libopencv_core.so
    LOCAL_EXPORT_C_INCLUDES := /home/ubuntu/opencv/modules/core/include
    include $(PREBUILT_SHARED_LIBRARY)
    
    
    include $(CLEAR_VARS)
    LOCAL_MODULE := opencv_imgcodecs
    LOCAL_SRC_FILES := /home/ubuntu/opencv/modules/imgcodecs/include/opencv2/libopencv_imgcodecs.so
    include $(PREBUILT_SHARED_LIBRARY)
       
    
    include $(CLEAR_VARS)
    LOCAL_MODULE   := lib_trial
    
    
    LOCAL_SRC_FILES := inc/trial_onnx.h src/trial_onnx.cpp
    
    LOCAL_C_INCLUDES := ${LOCAL_PATH}/inc
    LOCAL_LDLIBS += -llog -ldl
    LOCAL_SHARED_LIBRARIES := opencv_core opencv_imgcodecs
    
    
    include $(BUILD_SHARED_LIBRARY)
    

    My CPP file: trial_onnx.cpp looks like:

    #include <iostream>
    #include <fstream>
    #include <cstring>
    #include </home/ubuntu/opencv/modules/core/include/opencv2/core.hpp>
    #include </home/ubuntu/opencv/modules/imgcodecs/include/opencv2/imgcodecs.hpp>
    #include </home/ubuntu/opencv/modules/core/include/opencv2/core/mat.hpp>
    
        
    #include "trial_onnx.h"
    
    using namespace std;
    
    
    void execute_main() {
        std::cout << "Hello World"<<std::endl;
    
        cv::Mat imageBGR;
        imageBGR = cv::imread("cat.jpeg", 0);
        std::cout << "Width : " << imageBGR.cols << endl;
        std::cout << "Height: " << imageBGR.rows << endl;
        
    }
    

    Rest of the files remain the same.