OpenCV2.4.9 For Android + Android Studio (with gradle)配置教程

好久没来科创了,现在荒凉好多啊- -。 发一篇教程提高下访问~
原文在我博客

OpenCV的配置一直是个最麻烦的问题,2.4.6以后windows环境下 vs配置我就出错好几十次,来来回回弄了好多遍
之前在实验室弄,为了配合其他人才用的vs2010,现在蹲宿舍干了,改用更简洁的Qt了,qt配置OPENCV方便很多,几句话就搞定了。
 
人机交互的作业是写一个以图搜图的demo,之前虽然在实验室干过类似的东西,但是现在又得用安卓配置OpenCV了,又是麻烦了我一整天。前几天终于成了,记录一下。

配置环境的过程参考了 http://stackoverflow.com/questions/17767557/how-to-use-opencv-in-android-studio-using-gradle-build-tool
demo的编写参考了 http://blog.csdn.net/yanzi1225627/article/details/16917961
由于其resume后图片会消失,我做了点改动

1.准备工作

首先安装好Android Studio,要自带所有开发套件的,感觉AS比Intellij+ ADT ,eclipse系列都要好,虽然也想过Qt开发安卓,但是太小众了,不好跟人交流。
然后,保证所有环境变量配置正确,比如 JDK ADT JRE等等等等。

下载 OpenCV Android SDK ,我下的2.4.9,鉴于目前3。0无安卓sdk,2.4.10我也不敢用了,并将下载的OpenCV-2.4.9-android-sdk中的sdk文件夹中的java文件夹 重命名为 opencv


2.创建你的安卓项目(使用gradle,非gradle的教程网上资料很多)在你的工程根目录下new一个文件夹,名字任意比如libraries ,将刚才的opencv文件夹整个复制到新建的libraries里面。


3. 在android studio中,在opencv的根目录处新建一个 build.gradle文件,复制以下代码


复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
apply plugin: 'android-library' 
     
buildscript { 
     repositories { 
         mavenCentral() 
    
     dependencies { 
         classpath 'com.android.tools.build:gradle:1.0.0' 
    
     
android { 
     compileSdkVersion 21 
     buildToolsVersion "21.1.2" 
     
     defaultConfig { 
         minSdkVersion 13 
         targetSdkVersion 21 
         versionCode 2490 
         versionName "2.4.9" 
    
     
     sourceSets { 
         main { 
             manifest.srcFile 'AndroidManifest.xml' 
             java.srcDirs = ['src'] 
             resources.srcDirs = ['src'] 
             res.srcDirs = ['res'] 
             aidl.srcDirs = ['src'] 
        
    
}


注意其中的versionName 改为你自己下载的OpenCV的版本号,compileSdkVersion和minSdkVersion和targetSdkVersion要和你..\工程名\app\目录下的build.gradle中的设置一样
 

   dependencies {  
       classpath 'com.android.tools.build:gradle:1.0.0'
中的gradle版本要和你工程根目录下的build.gradle(不是app下的)中的版本一样,

关于gradle文件的解释如下
http://www.cnblogs.com/youxilua/archive/2013/05/20/3087935.html

图片:20141218225157805.jpg



4.在工程根目录的 settings.gradle 中添加以下代码,改动之后会提示你需要sync,点sync now


include ':libraries:opencv'  

5.在你需要用到opencv的model的/src/main文件夹下新建一个jniLibs文件夹。将刚才下载的OpenCV-2.4.9-android-sdk/sdk/native/libs中的文件拷贝进来。 就是各种.so .a文件,相当于win下的dll文件,程序靠引用这些动态链接库工作。另外一点就是,libs下的文件夹不一定要全部复制,根据你运行的平台复制对应的文件夹即可,对应关系如图,也跟之后的OpenCV Manager有关 (版本号自行对应)

图片:20131124131308687.png


6.在刚才..工程名\app\ 目录下的build.gradle 中的dependency下添加以下代码


compile project(':libraries:opencv')    

该sync now的都sync 就可以开始编写你的程序了

7.灰度化demo

首先看下opencv官网的流程图 http://docs.opencv.org/platforms/android/service/doc/UseCases.html

图片:20131124130504437.png


从2.4之后,为了和Android的系统架构保持同步,准确说是吸收Android框架层的优点,引入了OpenCV Manager的概念,其本质就是一个Service,用来管理OpenCV动态链接库(即你之前拷贝的那个jniLibs里的东西)。

APP在运行时会首先检查OpenCV Manager存在不,如果不存在则会提示安装。如果存在,就会连接这个服务,进一步初始化加载OpenCV库。  所以第一步就是先在你的目标手机上安装 OpenCV Manager ,apk在 ..\OpenCV-2.4.9-android-sdk\apk 下版本对应之前的图。

具体的代码跟 http://blog.csdn.net/yanzi1225627/article/details/16917961 没什么不同,这里只提两点。



复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class MyActivity extends Activity implements HelperCallbackInterface
{
private BaseLoaderCallback mOpenCVCallBack = new BaseLoaderCallback( this ) {
    @Override
    public void onManagerConnected( int status) {
      switch (status) {
        case LoaderCallbackInterface.SUCCESS:
        {
           Log.i(TAG, "OpenCV loaded successfully" );
           // Create and set View
           mView = new puzzle15View(mAppContext);
           setContentView(mView);
        } break ;
        default :
        {
           super .onManagerConnected(status);
        } break ;
      }
    }
};
   
/** Call on every application resume **/
@Override
protected void onResume()
{
     Log.i(TAG, "Called onResume" );
     super .onResume();
   
     Log.i(TAG, "Trying to load OpenCV library" );
     if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_6, this , mOpenCVCallBack))
     {
         Log.e(TAG, "Cannot connect to OpenCV Manager" );
     }
}


以上截取官方文档 http://docs.opencv.org/platforms/android/service/doc/BaseLoaderCallback.html

任何opencv项目都需要这两个步骤,在initAsync 加载OpenCV Library 所有其他的操作必须在这一步成功之后才能执行。

我最后的程序被ADT自带的虚拟机坑了好久,再次告诫各位不要用AVD,只要不用AVD应该都会成功~

图片:20141218233353918.jpg


附demo代码:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package com.example.ras.myapplication;
        
import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.OpenCVLoader;
import org.opencv.android.Utils;
import org.opencv.core.Mat;
import org.opencv.imgproc.Imgproc;
        
import android.support.v7.app.ActionBarActivity;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.Button;
import android.widget.TextView;
        
        
public class MainActivity extends ActionBarActivity {
        
     Button btnProcess;
     Bitmap srcBitmap;
     Bitmap grayBitmap;
     Bitmap MaskBitmap;
     ImageView imgLena;
     TextView OpCVversion;
       
        
     private static final String TAG = "MainActivity" ;
        
     private static boolean flag = true ;
     private static boolean isFirst = true ;                      // Grey
        
        
        
     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, "Load success" );
                     break ;
                 default :
                     super .onManagerConnected(status);
                     Log.i(TAG, "Load fail" );
                     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.button);
         imgLena = (ImageView)findViewById(R.id.imageView);
         OpCVversion = (TextView)findViewById(R.id.textView3);
        
            
         OpCVversion.setText( "Ver: " + OpenCVLoader.OPENCV_VERSION_2_4_9);
         Log.i(TAG, "initUI sucess..." );
        
     }
        
     public void procSrc2Gray(){
         Mat rgbMat = new Mat();
         Mat grayMat = new Mat();
         srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.lena);
         grayBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), 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 OnClickListener{
        
         @Override
         public void onClick(View v) {
             // TODO Auto-generated method stub
             if (isFirst)
             {
                 procSrc2Gray();
                 isFirst = false ;
             }
             if (flag){
                 imgLena.setImageBitmap(grayBitmap);
                 btnProcess.setText( "Origin" );
                 flag = false ;
             }
             else {
                 imgLena.setImageBitmap(srcBitmap);
                 btnProcess.setText( "Grey" );
                 flag = true ;
             }
         }
        
     }
        
        
        
     @Override
     public boolean onCreateOptionsMenu(Menu menu) {
         // Inflate the menu; this adds items to the action bar if it is present.
         getMenuInflater().inflate(R.menu.menu_main, menu);
         return true ;
     }
        
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         // Handle action bar item clicks here. The action bar will
         // automatically handle clicks on the Home/Up button, so long
         // as you specify a parent activity in AndroidManifest.xml.
         int id = item.getItemId();
        
         //noinspection SimplifiableIfStatement
         if (id == R.id.action_settings) {
             return true ;
         }
        
         return super .onOptionsItemSelected(item);
     }
        
     @Override
     protected void onResume() {
         // TODO Auto-generated method stub
         super .onResume();
         //load OpenCV engine and init OpenCV library
         isFirst = true ;
         OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_9, this , mLoaderCallback);
         Log.i(TAG, "onResume sucess load OpenCV..." );
        
     }
}
[1211于2014-12-22 20:17编辑了帖子]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值