K22
K22

Reputation: 23

OpenCV in native library creating errors

I'm using OpenCV 3.4.5 with native library and I used CMake (CMakeLists.txt) for this.

Before this project I tried very simple code with same way (that was converting realtime RGB camera video to gray video) and it was working successfully.

Now I'm trying to make a realtime face detection (not recognization) project with the same way.

Here's my native-lib.cpp file in project.

#include "opencv2/core.hpp"
#include <jni.h>
#include <opencv2/imgproc.hpp>
#include <opencv2/opencv.hpp>
#include <string>

using namespace cv;


using namespace std;
void detect (Mat& frame);
extern "C"
JNIEXPORT void JNICALL Java_com_example_alas02_NativeClass_testFunction(JNIEnv *env, jclass type,jlong addrRgba){
    Mat &frame = *(Mat *) addrRgba;
    detect(frame);
}
void detect (Mat& frame){
    String face_cascade_name = "/storage/emulated/0/ony.xml";
    String eyes_cascade_name = "/storage/emulated/0/moe.xml";
    CascadeClassifier face_cascade;
    CascadeClassifier eyes_cascade;


    if( !face_cascade.load( face_cascade_name ) ){ printf("--(!)Error loading\n"); return; };
    if( !eyes_cascade.load( eyes_cascade_name ) ){ printf("--(!)Error loading\n"); return; };


    std::vector<Rect> faces;
    Mat frame_gray;

    cvtColor( frame, frame_gray, CV_BGR2GRAY );
    equalizeHist( frame_gray, frame_gray );

    //-- Detect faces
    face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30, 30) );

    for( size_t i = 0; i < faces.size(); i++ )
    {
        Point center( faces[i].x + faces[i].width*0.5, faces[i].y + faces[i].height*0.5 );
        ellipse( frame, center, Size( faces[i].width*0.5, faces[i].height*0.5), 0, 0, 360, Scalar( 255, 0, 255 ), 4, 8, 0 );

        Mat faceROI = frame_gray( faces[i] );
        std::vector<Rect> eyes;

        //-- In each face, detect eyes
        eyes_cascade.detectMultiScale( faceROI, eyes, 1.1, 2, 0 |CV_HAAR_SCALE_IMAGE, Size(30, 30) );

        for( size_t j = 0; j < eyes.size(); j++ )
        {
            Point center( faces[i].x + eyes[j].x + eyes[j].width*0.5, faces[i].y + eyes[j].y + eyes[j].height*0.5 );
            int radius = cvRound( (eyes[j].width + eyes[j].height)*0.25 );
            circle( frame, center, radius, Scalar( 255, 0, 0 ), 4, 8, 0 );
        }
    }
}

Note: there's any sync error but when I'm trying to build it it gives me errors like;

Build command failed.
Error while executing process C:\Users\k22\AppData\Local\Android\Sdk\cmake\3.6.4111459\bin\cmake.exe with arguments {--build C:\Users\k22\AndroidStudioProjects\alas02\app\.externalNativeBuild\cmake\debug\x86_64 --target native-lib}
[1/2] Building CXX object CMakeFiles/native-lib.dir/src/main/cpp/native-lib.cpp.o
[2/2] Linking CXX shared library ..\..\..\..\build\intermediates\cmake\debug\obj\x86_64\libnative-lib.so
FAILED: cmd.exe /C "cd . && C:\Users\k22\AppData\Local\Android\Sdk\ndk-bundle\toolchains\llvm\prebuilt\windows-x86_64\bin\clang++.exe  --target=x86_64-none-linux-android21 --gcc-toolchain=C:/Users/k22/AppData/Local/Android/Sdk/ndk-bundle/toolchains/llvm/prebuilt/windows-x86_64 --sysroot=C:/Users/k22/AppData/Local/Android/Sdk/ndk-bundle/toolchains/llvm/prebuilt/windows-x86_64/sysroot -fPIC -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -fno-addrsig -Wa,--noexecstack -Wformat -Werror=format-security   -std=gnu++11 -O0 -fno-limit-debug-info  -Wl,--exclude-libs,libgcc.a -Wl,--exclude-libs,libatomic.a -static-libstdc++ -Wl,--build-id -Wl,--warn-shared-textrel -Wl,--fatal-warnings -Wl,--no-undefined -Qunused-arguments -Wl,-z,noexecstack -shared -Wl,-soname,libnative-lib.so -o ..\..\..\..\build\intermediates\cmake\debug\obj\x86_64\libnative-lib.so CMakeFiles/native-lib.dir/src/main/cpp/native-lib.cpp.o  -llog ../../../../src/main/jniLibs/x86_64/libopencv_java3.so -latomic -lm && cd ."
C:\Users\k22\AndroidStudioProjects\alas02\app\src\main\cpp/native-lib.cpp:35: error: undefined reference to 'cv::CascadeClassifier::detectMultiScale(cv::_InputArray const&, std::__ndk1::vector<cv::Rect_<int>, std::__ndk1::allocator<cv::Rect_<int> > >&, double, int, int, cv::Size_<int>, cv::Size_<int>)'

C:\Users\k22\AndroidStudioProjects\alas02\app\src\main\cpp/native-lib.cpp:46: error: undefined reference to 'cv::CascadeClassifier::detectMultiScale(cv::_InputArray const&, std::__ndk1::vector<cv::Rect_<int>, std::__ndk1::allocator<cv::Rect_<int> > >&, double, int, int, cv::Size_<int>, cv::Size_<int>)'

clang++: error: linker command failed with exit code 1 (use -v to see invocation)

ninja: build stopped: subcommand failed.

Upvotes: 1

Views: 491

Answers (1)

Alex Cohn
Alex Cohn

Reputation: 57173

You are using libopencv_java3.so. It is not compatible with recent releases of NDK. See https://stackoverflow.com/a/50686467/192373.

The win-win solution is to switch to OpenCV 4. This may require some minor changes in your code.

To stay with OpenCV 3.4.5, you can step back to older NDK release (not recommended), or rebuild libopencv_java3.so with the latest NDK (adventurous).

Upvotes: 2

Related Questions