Reputation: 23
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
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