0

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.
Jeru Luke
  • 20,118
  • 13
  • 80
  • 87
ashwinjoseph
  • 359
  • 3
  • 12
  • Well, you never include any OpenCV headers... – Dan Mašek Feb 15 '22 at 15:39
  • I am not getting an idea as to how to import the functions in .so files to be frank. Could you guide me on that? – ashwinjoseph Feb 15 '22 at 16:42
  • You need to have installed OpenCV headers matching those pre-built OpenCV binaries, tell the compiler where to find them, and then `#include` them like any other c++ library header -- in this case `#include "opencv2/opencv.hpp"` would probably do. | Oh, and you should probably get rid of those `using namespace` statements there. They're unnecessary in this example, and [asking for trouble](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) anyway. – Dan Mašek Feb 15 '22 at 20:51
  • Hi Dan, as you have mentioned, I have imported the relevant header files as well but upon building the same issue pops up again. Got any other ideas? – ashwinjoseph Feb 16 '22 at 13:09
  • `undefined reference to `cv::Mat::Mat()'` -- that's a step forward. The compilation succeeded, but you forgot to link your shared library with the appropriate OpenCV library. – Dan Mašek Feb 16 '22 at 14:25
  • Yes, linking was indeed the issue as you suggested. Was able to fix it. Thanks a lot for your efforts to help. Really appreciated! – ashwinjoseph Feb 17 '22 at 12:33

1 Answers1

0

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.

ashwinjoseph
  • 359
  • 3
  • 12