OpenCv with Android studio 1.3+ using new gradle - undefined reference
Posted
技术标签:
【中文标题】OpenCv with Android studio 1.3+ using new gradle - undefined reference【英文标题】: 【发布时间】:2015-11-17 05:23:49 【问题描述】:我在使用原生 OpenCv 2.4.11(3.0.0 也可以)和 android Studio 1.3+ 以及新的 ndk 支持时遇到问题。所有关于 .mk 文件的教程,但我想将它与新的实验性 gradle 一起使用。
使用 Kiran 回答 OpenCV in Android Studio
我在java中实现了正常工作。我还更改了 gradle-wrapper.properties:
distributionUrl=https\://services.gradle.org/distributions/gradle-2.5-all.zip
build.gradle(应用程序):
classpath 'com.android.tools.build:gradle-experimental:0.2.0'
build.gradle(module):
apply plugin: 'com.android.model.application'
model
android
compileSdkVersion = 23
buildToolsVersion = "23.0.0"
defaultConfig.with
applicationId = "android.overloaded.nativetestv4"
minSdkVersion.apiLevel = 18
targetSdkVersion.apiLevel = 23
versionCode = 1
versionName = "1.0"
android.ndk
moduleName = "mymodule"
ldLibs += ['log']
cppFlags += "-std=c++11"
cppFlags += "-fexceptions"
cppFlags += "-I$file("C:/DevAndroid/OpenCV-android-sdk/sdk/native/jni/include")".toString()
cppFlags += "-I$file("C:/DevAndroid/OpenCV-android-sdk/sdk/native/jni/include/opencv")".toString()
ldLibs += ["android", "EGL", "GLESv2", "dl", "log", "z"] //added z
stl = "stlport_static"//"gnustl_shared" changed to stlport static
android.buildTypes
release
minifyEnabled = false
proguardFiles += file('proguard-rules.pro')
android.productFlavors //added all productFlavors code
create("arm")
ndk.with
abiFilters += "armeabi"
File curDir = file('./')
curDir = file(curDir.absolutePath)
String libsDir = curDir.absolutePath+"\\src\\main\\jniLibs\\armeabi\\" //"-L" +
ldLibs += libsDir + "libnative_camera_r4.3.0.so"
ldLibs += libsDir + "libopencv_contrib.a"
ldLibs += libsDir + "libopencv_core.a"
ldLibs += libsDir + "libopencv_highgui.a"
ldLibs += libsDir + "libopencv_imgproc.a"
ldLibs += libsDir + "libopencv_info.so"
ldLibs += libsDir + "libopencv_java.so"
ldLibs += libsDir + "libopencv_legacy.a"
ldLibs += libsDir + "libopencv_ml.a"
ldLibs += libsDir + "libopencv_ts.a"
create("armv7")
ndk.with
abiFilters += "armeabi-v7a"
File curDir = file('./')
curDir = file(curDir.absolutePath)
String libsDir = curDir.absolutePath+"\\src\\main\\jniLibs\\armeabi-v7a\\" //"-L" +
ldLibs += libsDir + "libnative_camera_r4.3.0.so"
ldLibs += libsDir + "libopencv_contrib.a"
ldLibs += libsDir + "libopencv_core.a"
ldLibs += libsDir + "libopencv_highgui.a"
ldLibs += libsDir + "libopencv_imgproc.a"
ldLibs += libsDir + "libopencv_info.so"
ldLibs += libsDir + "libopencv_java.so"
ldLibs += libsDir + "libopencv_legacy.a"
ldLibs += libsDir + "libopencv_ml.a"
ldLibs += libsDir + "libopencv_ts.a"
create("fat")
dependencies
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:appcompat-v7:23.0.0'
compile project(':openCVLibrary2411')
通过这些更改,我可以在 jni 文件夹下的 c++ 文件中调用我的原生虚拟函数。 CLion 还支持#include <opencv2/core/core.hpp>
和其他人...当我声明 cv::Mat mat;给我这个错误:
Linker failed while linking libmymodule.so failed.
C:\DevAndroid\OpenCV-android-sdk\sdk\native\jni\include/opencv2/core/mat.hpp:278: error: undefined reference to 'cv::fastFree(void*)'
C:\DevAndroid\OpenCV-android-sdk\sdk\native\jni\include/opencv2/core/mat.hpp:367: error: undefined reference to 'cv::Mat::deallocate()'
collect2.exe: error: ld returned 1 exit status
c++代码:
#include <jni.h>
#include <vector>
#include <string>
#include "helpers.h"
#include <opencv2/core/core.hpp> //This is supported by CLion
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace std;
extern "C"
JNIEXPORT jstring JNICALL
Java_android_overloaded_nativetestv4_MainActivity_FuncV1(JNIEnv *env, jclass type)
cv::Mat mat; //causing error
string s = "Cpp v1 - succ ";
return env->NewStringUTF(s.data());
更新 - 将“z”添加到 ldLibs - 添加了 android.productFlavors 块
现在编译成功,应用程序启动第二次,然后崩溃并显示此消息 事件日志:
IllegalArgumentException: Error while starting native debug session: Unable to find process for android.overloaded.nativetestv4 on device huawei-huawei_y530_u00-64a6513ccd8e
调试信息:
Restart ADB integration and try again
Waiting for process: android.overloaded.nativetestv4
DEVICE SHELL COMMAND: run-as android.overloaded.nativetestv4 mkdir -p /data/data/android.overloaded.nativetestv4/lldb/bin
DEVICE SHELL COMMAND: cat /data/local/tmp/lldb-server | run-as android.overloaded.nativetestv4 sh -c 'cat > /data/data/android.overloaded.nativetestv4/lldb/bin/lldb-server; chmod 700 /data/data/android.overloaded.nativetestv4/lldb/bin/lldb-server'
DEVICE SHELL COMMAND: rm /data/local/tmp/lldb-server
DEVICE SHELL COMMAND: cat /data/local/tmp/start_lldb_server.sh | run-as android.overloaded.nativetestv4 sh -c 'cat > /data/data/android.overloaded.nativetestv4/lldb/bin/start_lldb_server.sh; chmod 700 /data/data/android.overloaded.nativetestv4/lldb/bin/start_lldb_server.sh'
DEVICE SHELL COMMAND: rm /data/local/tmp/start_lldb_server.sh
Now Launching Native Debug Session
Error while starting native debug session: java.lang.IllegalArgumentException: Unable to find process for android.overloaded.nativetestv4 on device huawei-huawei_y530_u00-64a6513ccd8e
日志:
A/libc﹕ Fatal signal 11 (SIGSEGV) at 0x00000000 (code=1), thread 3077 (ed.nativetestv4)
【问题讨论】:
您指向的是标题的位置,而不是实际库的位置。包括“-L经过几周的痛苦,我成功了。这是我对 Android Studio 1.3.1、OpenCv 2.4.11 的正确代码。首先你应该这样做OpenCV in Android Studio (不要使用包含空格的路径,用于项目和 opencv 提取文件夹)然后,让 opencv 成为本机:
gradle-wrapper.properties:
distributionUrl=https\://services.gradle.org/distributions/gradle-2.5-all.zip
build.gradle(应用程序):
classpath 'com.android.tools.build:gradle-experimental:0.2.0'
build.gradle(模块):
apply plugin: 'com.android.model.application'
model
android
compileSdkVersion = 23
buildToolsVersion = "23.0.0"
defaultConfig.with
applicationId = "android.overloaded.nativetestv4"
minSdkVersion.apiLevel = 18
targetSdkVersion.apiLevel = 23
versionCode = 1
versionName = "1.0"
android.ndk
moduleName = "mymodule"
ldLibs += ['log']
cppFlags += "-std=c++11"
cppFlags += "-fexceptions"
cppFlags += "-I$file("C:/DevAndroid/OpenCV-android-sdk/sdk/native/jni/include")".toString()
cppFlags += "-I$file("C:/DevAndroid/OpenCV-android-sdk/sdk/native/jni/include/opencv")".toString()
// ldFlags += linkOpt
ldLibs += ["android", "EGL", "GLESv2", "dl", "log", "z"]// , "ibopencv_core"
stl = "gnustl_shared"//"gnustl_static"//"gnustl_shared"//"stlport_static"
android.buildTypes
release
minifyEnabled = false
proguardFiles += file('proguard-rules.pro')
android.productFlavors
create("arm")
ndk.with
abiFilters += "armeabi"
File curDir = file('./')
curDir = file(curDir.absolutePath)
String libsDir = curDir.absolutePath+"\\src\\main\\jniLibs\\armeabi\\" //"-L" +
ldLibs += libsDir + "libnative_camera_r4.3.0.so"
ldLibs += libsDir + "libopencv_contrib.a"
ldLibs += libsDir + "libopencv_core.a"
ldLibs += libsDir + "libopencv_highgui.a"
ldLibs += libsDir + "libopencv_imgproc.a"
ldLibs += libsDir + "libopencv_info.so"
ldLibs += libsDir + "libopencv_java.so"
ldLibs += libsDir + "libopencv_legacy.a"
ldLibs += libsDir + "libopencv_ml.a"
ldLibs += libsDir + "libopencv_ts.a"
create("armv7")
ndk.with
abiFilters += "armeabi-v7a"
File curDir = file('./')
curDir = file(curDir.absolutePath)
String libsDir = curDir.absolutePath+"\\src\\main\\jniLibs\\armeabi-v7a\\" //"-L" +
ldLibs += libsDir + "libnative_camera_r4.3.0.so"
ldLibs += libsDir + "libopencv_contrib.a"
ldLibs += libsDir + "libopencv_core.a"
ldLibs += libsDir + "libopencv_highgui.a"
ldLibs += libsDir + "libopencv_imgproc.a"
ldLibs += libsDir + "libopencv_info.so"
ldLibs += libsDir + "libopencv_java.so"
ldLibs += libsDir + "libopencv_legacy.a"
ldLibs += libsDir + "libopencv_ml.a"
ldLibs += libsDir + "libopencv_ts.a"
create("x86")
ndk.with
abiFilters += "x86"
create("mips")
ndk.with
abiFilters += "mips"
create("fat")
dependencies
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:appcompat-v7:23.0.0'
compile project(':openCVLibrary2411')
.cpp
#include <jni.h>
#include <vector>
#include <string>
#include "helpers.h"
#include <opencv2/core/core.hpp>
using namespace std;
#ifdef __cplusplus
extern "C"
#endif
JNIEXPORT jstring JNICALL
Java_android_overloaded_nativetestv4_MainActivity_FuncV1(JNIEnv *env, jclass type)
cv::Mat mat(33,22, 1);
string s = "Cpp v1 - succ, rows#:" + Helpers::ToStringNum(mat.rows);
Helpers::Log(s);
return env->NewStringUTF(s.data());
.java
package android.overloaded.nativetestv4;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity
static
System.loadLibrary("mymodule");
public static native String FuncV1();
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toast.makeText(this, FuncV1(), Toast.LENGTH_LONG).show();
((TextView)findViewById(R.id.txtInfo)).setText(FuncV1());
Android Studio 1.5.1、OpenCV 3.1 更新 1.首先你应该这样做OpenCV in Android Studio(不要使用包含空格的路径,用于项目和opencv提取文件夹),之后你应该有正常工作的Java应用程序 2.修改项目根目录下的build.gradle:
buildscript
repositories
jcenter()
dependencies
classpath "com.android.tools.build:gradle-experimental:0.4.0"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
allprojects
repositories
jcenter()
task clean(type: Delete)
delete rootProject.buildDir
-
更改 gradle-wrapper.properties:
distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-all.zip
修改opencv模块中的build.gradle:
apply plugin: 'com.android.model.library' model android compileSdkVersion = 23 buildToolsVersion = "23.0.2" defaultConfig.with minSdkVersion.apiLevel = 11 targetSdkVersion.apiLevel = 23 android.buildTypes release minifyEnabled = false proguardFiles.add(file("proguard-rules.txt"))
在应用模块中更改 build.gradle:
apply plugin: 'com.android.model.application' model android compileSdkVersion = 23 buildToolsVersion = "23.0.2" defaultConfig.with applicationId = "android.overloaded.opencv31v1" //Name of package minSdkVersion.apiLevel = 11 targetSdkVersion.apiLevel = 23 versionCode = 1 versionName = "1.0" android.ndk moduleName = "native" // Name of C++ module, for System.loadLibrary("native") cppFlags.add("-std=c++11") // Add provisions to allow C++11 functionality cppFlags.add("-fexceptions") // YOUR OPENCV DIRECTORY!!! cppFlags.add("-I$file("C:/DevAndroid/OpenCV-android-sdk/sdk/native/jni/include")".toString()) ldLibs.addAll(["android", "EGL", "GLESv2", "dl", "log", "z"]) stl = "gnustl_shared" android.buildTypes release minifyEnabled = false proguardFiles.add(file("proguard-rules.txt")) android.productFlavors create("arm") ndk.with abiFilters.add("armeabi") File curDir = file('./') curDir = file(curDir.absolutePath) String libsDir = curDir.absolutePath + "\\src\\main\\jniLibs\\armeabi\\" ldLibs.add(libsDir + "libopencv_core.a") ldLibs.add(libsDir + "libopencv_highgui.a") ldLibs.add(libsDir + "libopencv_imgproc.a") ldLibs.add(libsDir + "libopencv_java3.so") ldLibs.add(libsDir + "libopencv_ml.a") create("armv7") ndk.with abiFilters.add("armeabi-v7a") File curDir = file('./') curDir = file(curDir.absolutePath) String libsDir = curDir.absolutePath + "\\src\\main\\jniLibs\\armeabi-v7a\\" ldLibs.add(libsDir + "libopencv_core.a") ldLibs.add(libsDir + "libopencv_highgui.a") ldLibs.add(libsDir + "libopencv_imgproc.a") ldLibs.add(libsDir + "libopencv_java3.so") ldLibs.add(libsDir + "libopencv_ml.a") ldLibs.add(libsDir + "libopencv_ts.a") android.sources main jni source srcDirs += ['src/main/jniMy'] dependencies compile fileTree(dir: "libs", include: [$/*.jar/$]) compile "com.android.support:appcompat-v7:23.1.1" //Do not use 23.2.0 compile project(":openCVLibrary310")
创建目录 app/src/main/jniMy,这是存放你的 .cpp 文件的地方
可选择在 jniMy 中创建文件 chelper.c,使用以下代码:
#ifndef OPENCV31V1_CHELPER_H #define OPENCV31V1_CHELPER_H #include <jni.h> #include <vector> #include <string> #include <sstream> #include <android/log.h> using namespace std; class Helpers public: template <typename T> static string ToStringNum(T tNumber) ostringstream ostrStream; ostrStream << tNumber; return ostrStream.str(); static void Log(string s) __android_log_print(ANDROID_LOG_INFO, "My", s.data()); static void Log(std::exception ee) string s = "Exception: " + string(ee.what()) ; __android_log_print(ANDROID_LOG_INFO, "My", s.data()); static long Time() struct timespec now; clock_gettime(CLOCK_MONOTONIC, &now); return (long)((int64_t)now.tv_sec * 1000LL + now.tv_nsec /1000000LL); static string Time(long iTime) return ToStringNum(Time() - iTime) + "ms"; ; #endif //OPENCV31V1_CHELPER_H
在 jniMy 中创建文件 native_exporter.cpp,使用以下代码:
#include <jni.h> #include <string> #include <opencv2/core/core.hpp> #include "chelper.h" extern "C" JNIEXPORT jstring JNICALLJava_android_overloaded_opencv31v1_MainActivity_FuncV1(JNIEnv *env, jclass type) cv::Mat mat(33,22, CV_32FC2); string s = "Cpp v1 - succ, rows#:" +Helpers::ToStringNum(mat.rows); Helpers::Log(s); auto i = 5; for (int i2 : 1,3,5) Helpers::Log(Helpers::ToStringNum(i2)); return env->NewStringUTF(s.data());
MainActivity.java 中的代码:
package android.overloaded.opencv31v1; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.SurfaceView; import android.widget.TextView; import android.widget.Toast; import org.opencv.android.CameraBridgeViewBase; import org.opencv.core.CvType; import org.opencv.core.Mat; public class MainActivity extends AppCompatActivity implements CameraBridgeViewBase.CvCameraViewListener2 private static void Log(String sMsg)Log.i("My", "MainActivity." + sMsg ); static System.loadLibrary("opencv_java3"); System.loadLibrary("native"); public native String FuncV1(); JavaCameraViewCustom2 _javaCameraView; //Similar to JavaCameraView @Override protected void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if(getSupportActionBar() != null)getSupportActionBar().hide(); String sRes = FuncV1(); Toast.makeText(this, sRes, Toast.LENGTH_LONG).show(); ((TextView)findViewById(R.id.txtInfo)).setText(sRes); _javaCameraView = (JavaCameraViewCustom2)findViewById(R.id.cameraView); _javaCameraView.setVisibility(SurfaceView.VISIBLE); _javaCameraView.setCvCameraViewListener(this); @Override protected void onResume() super.onResume(); _javaCameraView.enableView(); @Override protected void onPause() super.onPause(); _javaCameraView.disableView(); Mat _imgBgrTemp; @Override public void onCameraViewStarted(int width, int height) _imgBgrTemp = new Mat(height,width, CvType.CV_8UC4); @Override public void onCameraViewStopped() _imgBgrTemp.release(); @Override public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) _imgBgrTemp = inputFrame.rgba(); return _imgBgrTemp;
Android Studio 会要求你更改 jdk,它还会安装新的 gradle,你应该做它要求的一切。
【讨论】:
您好,我在静态 cv::javaDescriptorExtractor* cv::javaDescriptorExtractor::create(int) 中遇到了`OpenCV 错误:错误参数(不支持指定的描述符提取器类型。),文件/builds/master_pack-android/opencv/modules/features2d/misc/java/src/cpp/features2d_manual.hpp,第374行你能帮我吗? 我在 Opencv 3.0 中找到了关于 Brief bug code.opencv.org/issues/4419 的页面。也许其他描述符/提取器也受到影响。您可以尝试使用构造函数:BriefDescriptorExtractor brief = BriefDescriptorExtractor(32); (模块)和(应用程序)是什么意思?模块 = openCVLibrary 和应用程序 = 应用程序?或者应用程序是项目的 build.gradle ?泰! 另外,#include "helpers.h" 有问题,这到底是什么? @GeraldoNeto 头文件 helpers.h 仅包含日志记录功能。我创建了那个文件,它不重要,只需删除 '#include "helpers.h"'。以上是关于OpenCv with Android studio 1.3+ using new gradle - undefined reference的主要内容,如果未能解决你的问题,请参考以下文章
关于CMake编译OpenCV时opencv_ffmpeg.dllippicv等下载失败的解决办法及感悟
[CC-CHEFGRPH]Time to Study Graphs with Chef