我在Android Studio 1.3+上使用原生OpenCv 2.4.11(3.0.0也没问题)时遇到了麻烦,并且支持新的ndk。关于.mk文件的所有教程,但我想将它与新的实验gradle一起使用
使用Kiran回答OpenCV in Android Studio
我在java中工作得很好。我也改变了
gradle-wrapper.properties:
Student
的build.gradle(应用):
distributionUrl=https\://services.gradle.org/distributions/gradle-2.5-all.zip
的build.gradle(模块):
classpath 'com.android.tools.build:gradle-experimental:0.2.0'
通过这些更改,我可以在jni文件夹下的c ++文件中调用我的本机虚拟函数。 CLION也支持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')
}
和其他人......当我宣布cv :: Mat mat;给我这个错误:
#include <opencv2/core/core.hpp>
c ++代码:
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
更新
- 添加&#34; z&#34;到ldLibs
- 添加了android.productFlavors块
现在编译成功了,应用程序启动了第二个,然后崩溃了这个消息
事件日志:
#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());
}
}
调试信息:
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
答案 0 :(得分:20)
经过几周的疼痛,我成功了。这是我的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
}
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")) } } }
在app模块中更改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") }
创建dir 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,你应该做它所要求的一切。