被Android Studio下配置OpenCV的问题折磨了快一周,昨天终于搞定了。
不知道是不是版本改进的问题,我的配置过程与网上大量的教程不太一样,更简单了。下面总结一下,希望能帮助到有需要的朋友。
第一节 软件的下载
1. 1 Android Studio 3.2 https://developer.android.google.cn/studio/
1. 2 OpenCV 3.4.4 https://sourceforge.net/projects/opencvlibrary/files/3.4.4/opencv-3.4.4-android-sdk.zip/download
1. 3 Android SDK (android-sdk_r24.4.1-windows) http://www.androiddevtools.cn/
安装Android Studio 3.2,解压OpenCV 3.4.4和Android SDK (android-sdk_r24.4.1-windows)。
第二节 在Android Studio上进行配置
这是关键环节,也是折磨我好多天的环节
2.1 Android Studio中 sdk 的配置
点击File->Project Structure,在SDk Location标题下的 Android SDK Location处填写本机sdk所在的文件夹。
2.2 创建一个新工程,采取默认配置就行。我选择API 21,Empty模板。
2.3 配置OpenCV
2.3.1 导入OpenCV module: File -> New -> Import Module
然后选择OpenCV文件夹中sdk->java文件夹即可
点击OK之后
会自动显示Module Name。然后点击Next,Finish。
等待gradle更新。之后会出现
这个问题。先别急,我们将这个问题标注为 problem 1,稍后解决。
我们首先要修改openCVLibrary343目录下的build.gradle文件中的3个参数,使其与app下build.gradle中的参数一致。
点击以下两个文件
修改openCVLibrary343目录下的build.gradle文件中的3个参数,使其与app下build.gradle中的参数一致。箭头所指为错误的参数,需要修改。
这是app下build.gradle文件的参数
openCVLibrary343目录下的build.gradle文件改为下面这个德行
然后打开openCVLibrary343目录下manifests文件夹下AndroidManifest.xml,注释掉右侧箭头指向的
<use-sdk android: ... ..../>字段。
这样就解决掉了problem 1。
然后点击右上角 Try again 来同步gradle工程
下面来添加依赖。点击File ->Project Structure。然后依次从左到右点击下图箭头所指的选项
出现下图,点OK
OK之后,已经完成添加依赖。
此时,已经可以实现工程的打包,并安装在手机上。但是此时如果运行依赖于OpenCV的代码,会报错,会被要求安装OpenCV Manager。
解决这个问题: 将OpenCV sdk下native下的libs文件夹复制,即下图
粘贴到app\src\main目录下,如下左图。并更名为jniLibs,ru'x如下右图。
我们搞一个bmp文件,命名为a.bmp,扔到app\src\main\res\drawable目录中来测试。
至此,打包安装到手机吧,大功告成。
测试为使用OpenCV进行图片的灰度化。测试结果如下
代码
1. 布局文件activity_main.xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="16dp"
android:paddingBottom="16dp"
tools:context=".MainActivity">
<ImageView
android:id="@+id/img_huaishi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"/>
<Button
android:id="@+id/btn_gray_process"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/img_huaishi"
android:layout_centerHorizontal="true"
android:layout_marginTop="206dp"
android:text="灰度化" />
</RelativeLayout>
2. MainActivity.java
package com.example.administrator.ocvtest01;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.android.Utils;
import org.opencv.core.Mat;
import org.opencv.imgproc.Imgproc;
//import com.example.lenovo.R;
public class MainActivity extends AppCompatActivity {
Button btnProcess;
Bitmap srcBitmap;
Bitmap grayBitmap;
ImageView imgHuaishi;
private static boolean flag = true;
//private static boolean isFirst = true;
private static final String TAG = "MainActivity";
//OpenCV库加载并初始化成功后的回调函数
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
@Override
public void onManagerConnected(int status) {
// TODO Auto-generated method stub
switch (status){
case BaseLoaderCallback.SUCCESS:
Log.i(TAG, "成功加载");
break;
default:
super.onManagerConnected(status);
Log.i(TAG, "加载失败");
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initUI();
btnProcess.setOnClickListener(new ProcessClickListener());
}
public void initUI(){
btnProcess = (Button)findViewById(R.id.btn_gray_process);
imgHuaishi = (ImageView)findViewById(R.id.img_huaishi);
Log.i(TAG, "initUI sucess...");
}
public void procSrc2Gray(){
Mat rgbMat = new Mat();
Mat grayMat = new Mat();
srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.a);
grayBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), Bitmap.Config.RGB_565);
Utils.bitmapToMat(srcBitmap, rgbMat);//convert original bitmap to Mat, R G B.
Imgproc.cvtColor(rgbMat, grayMat, Imgproc.COLOR_RGB2GRAY);//rgbMat to gray grayMat
Utils.matToBitmap(grayMat, grayBitmap); //convert mat to bitmap
Log.i(TAG, "procSrc2Gray sucess...");
}
private class ProcessClickListener implements View.OnClickListener {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
// if(isFirst)
// {
procSrc2Gray();
// isFirst = false;
// }
if(flag){
imgHuaishi.setImageBitmap(grayBitmap);
btnProcess.setText("查看原图");
flag = false;
}
else{
imgHuaishi.setImageBitmap(srcBitmap);
btnProcess.setText("灰度化");
flag = true;
}
}
}
@Override
public void onResume()
{
super.onResume();
if (!OpenCVLoader.initDebug()) {
Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager for initialization");
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this, mLoaderCallback);
} else {
Log.d(TAG, "OpenCV library found inside package. Using it!");
mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
}
}
}
祝大家愉快!
总结:与常见的文献不同
1. 不需要ndk
2. 直接将 OpenCV sdk下native下的libs文件夹复制,粘贴到app\src\main目录下,并更名为jniLibs即可。不需要为此更改build.gradle文件!!!!切记!!不用更改。改了肯定出错。
引用稍后奉上,我去做饭先