1

I'm using OpenCV C++ in my android app

my code is building and working well untill I add this line cv::imwrite(result_uri, result_image).

note : cv:imread is working

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

OpenCV 3.4.10, Ndk 21

What am I missing ? Thanks

EDIT

I'm using an Android.mk file :

# ./android/app/src/main/jni/Android.mk

# Set up paths
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

# Specify module name for System.loadLibrary() call
LOCAL_MODULE := helloworld
LOCAL_MODULE_SUFFIX := .so
LOCAL_MODULE_CLASS := SHARED_LIBRARIES

# Debug mode
NDK_DEBUG=1

# Specify C++ flags
LOCAL_CPPFLAGS := -std=c++17
LOCAL_CPPFLAGS += -fexceptions
LOCAL_CPPFLAGS += -frtti
LOCAL_CPPFLAGS += -Wall
LOCAL_CPPFLAGS += -Wextra
LOCAL_CPPFLAGS += -I$(LOCAL_PATH)/../../../../../djinni/jni
LOCAL_CPPFLAGS += -I$(LOCAL_PATH)/../../../../../djinni/cpp
LOCAL_CPPFLAGS += -I$(LOCAL_PATH)/../../../../../node_modules/djinni/support-lib/jni
LOCAL_CPPFLAGS += -I$(LOCAL_PATH)/../../../../../node_modules/djinni/support-lib
LOCAL_CPPFLAGS += -I$(LOCAL_PATH)/../../../../../src/cpp

# Specify source files
LOCAL_SRC_FILES += $(LOCAL_PATH)/../../../../../djinni/jni/NativeHelloWorld.cpp
LOCAL_SRC_FILES += $(wildcard $(LOCAL_PATH)/../../../../../src/cpp/*.cpp)
LOCAL_SRC_FILES += $(wildcard $(LOCAL_PATH)/../../../../../node_modules/djinni/support-lib/jni/*.cpp)
LOCAL_SRC_FILES += $(wildcard $(LOCAL_PATH)/../../../../../node_modules/djinni/support-lib/*.cpp)

# load opencv
OPENCVROOT:= /Users/Gasp/Library/OpenCV/OpenCV-android-sdk
OPENCV_CAMERA_MODULES:=off
OPENCV_INSTALL_MODULES:=on
OPENCV_LIB_TYPE:=SHARED
OPENCV_INSTALL_MODULES:=on
# LOCAL_STATIC_LIBRARIES += libopencv_contrib libopencv_legacy libopencv_ml libopencv_stitching libopencv_nonfree libopencv_objdetect libopencv_videostab libopencv_calib3d libopencv_photo libopencv_video libopencv_features2d libopencv_highgui libopencv_androidcamera libopencv_flann libopencv_imgproc libopencv_ts libopencv_core
include ${OPENCVROOT}/sdk/native/jni/OpenCV.mk


LOCAL_MODULE := helloworld

# Specify C++ flags
LOCAL_CPPFLAGS := -lopencv_imgcodecs
LOCAL_CPPFLAGS := -std=c++17
LOCAL_CPPFLAGS += -fexceptions
LOCAL_CPPFLAGS += -frtti
LOCAL_CPPFLAGS += -Wall
LOCAL_CPPFLAGS += -Wextra
LOCAL_CPPFLAGS += -I$(LOCAL_PATH)/../../../../../djinni/jni
LOCAL_CPPFLAGS += -I$(LOCAL_PATH)/../../../../../djinni/cpp
LOCAL_CPPFLAGS += -I$(LOCAL_PATH)/../../../../../node_modules/djinni/support-lib/jni
LOCAL_CPPFLAGS += -I$(LOCAL_PATH)/../../../../../node_modules/djinni/support-lib
LOCAL_CPPFLAGS += -I$(LOCAL_PATH)/../../../../../src/cpp


# Specify source files
LOCAL_SRC_FILES += $(LOCAL_PATH)/../../../../../djinni/jni/NativeHelloWorld.cpp
LOCAL_SRC_FILES += $(wildcard $(LOCAL_PATH)/../../../../../src/cpp/*.cpp)
LOCAL_SRC_FILES += $(wildcard $(LOCAL_PATH)/../../../../../node_modules/djinni/support-lib/jni/*.cpp)
LOCAL_SRC_FILES += $(wildcard $(LOCAL_PATH)/../../../../../node_modules/djinni/support-lib/*.cpp)


# Telling make to build the library
include $(BUILD_SHARED_LIBRARY)
GChevass
  • 205
  • 3
  • 9

2 Answers2

2

I'm assuming you used CMake to build the OpenCV library. According to this question: undefined reference to 'cv::imwrite with Android NDK, it is required that you add a compiler flag to have this functionality become available: -lopencv_imgcodecs.

In your Android.mk file, simply make sure that gets appended to your LOCAL_CPPFLAGS variable:

# Specify C++ flags
LOCAL_CPPFLAGS := -std=c++17
LOCAL_CPPFLAGS += -lopencv_imgcodecs  # Note - change is here
LOCAL_CPPFLAGS += -fexceptions
LOCAL_CPPFLAGS += -frtti
LOCAL_CPPFLAGS += -Wall
LOCAL_CPPFLAGS += -Wextra
LOCAL_CPPFLAGS += -I$(LOCAL_PATH)/../../../../../djinni/jni
LOCAL_CPPFLAGS += -I$(LOCAL_PATH)/../../../../../djinni/cpp
LOCAL_CPPFLAGS += -I$(LOCAL_PATH)/../../../../../node_modules/djinni/support-lib/jni
LOCAL_CPPFLAGS += -I$(LOCAL_PATH)/../../../../../node_modules/djinni/support-lib
LOCAL_CPPFLAGS += -I$(LOCAL_PATH)/../../../../../src/cpp

Once you put this change in, reconfigure the project and try building the source again. Make sure you clear the cache in your build directory before trying to reconfigure the project or the changes made above will not take effect.

rayryeng
  • 102,964
  • 22
  • 184
  • 193
  • thanks a lot for your answer. Sorry it's my fault I did not indicate that I was using Android.mk not Cmake I followed the template of this medium post [link](https://medium.com/@ryardley/4-connect-react-native-to-c-a2809b92095) would you have a solution for this ? or I need to switch to CMake ? – GChevass Jul 08 '20 at 10:21
  • 1
    Aha, so in your Android.mk file, simply add: `LOCAL_CPPFLAGS := -lopencv_imgcodecs`. – rayryeng Jul 08 '20 at 12:50
  • I've added `LOCAL_CPPFLAGS := -lopencv_imgcodecs` but the issue still persist : `error: undefined reference to 'cv::imwrite(cv::String const&, cv::_InputArray...` I've edited the question with the content of the Android.mk file if you see something stupid thanks ! – GChevass Jul 08 '20 at 15:13
  • dear ray, I've updated my Android.mk with `# Specify C++ flags LOCAL_CPPFLAGS := -std=c++17 LOCAL_CPPFLAGS += -lopencv_imgcodecs ...` I have hoverer still the same issue `error: undefined reference to 'cv::imwrite` Using Android studio I made a `Build > Clean Project ` and `Invalidate Cache Restart`, is there another way ? thanks again – GChevass Jul 13 '20 at 09:51
0

Other attempt :

I tried to switch to OpenCV android 4.3.0.

There is no more error during the build time about undefined references.

Hovever at runtime the line :

frame = cv::imread(trim_uri_protocal(uri), cv::IMREAD_COLOR);

(which is working both with OpenCV android 3.4.10 and with OpenCV on iOS)

is causing this error E/libc++abi: terminating with uncaught exception of type std::bad_cast: std::bad_cast

Maybe an idea to solve this one instead ?

GChevass
  • 205
  • 3
  • 9