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.
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.