OpenCV4Android机器视觉应用入门 -引言
OpenCV是开源的C++机器视觉框架。OpenCV整体模块分明,算法优秀且速度很快,是很优秀的机器视觉框架。
Android业务程序一般采用Java编写,但是在以下情境下需要C++的配合:
公司的C++代码遗产,希望在移动平台继续使用;IOS和Android的跨平台需求;安全性考虑,C++编译出的so库很难被反编译;速度考虑,C++的运行速度可能比Java在JVM上快(以前的说法了,现在JVM优化的很好);突破系统的限制,例如 如何突破24M内存的限制,为Android程序分配到更多内存与底层硬件交互,下面是android中Camera一些代码片段
android . hardware . Camera ; 
//自动对焦功能
 public  final  void  autoFocus ( AutoFocusCallback  cb ) 
    { 
        synchronized  ( mAutoFocusCallbackLock )  { 
            mAutoFocusCallback  =  cb ; 
        } 
        native_autoFocus ();   //调用本地方法,实现摄像机自动对焦功能
      } 
    private  native  final  void  native_autoFocus ();  // 本地方法 , 用C / C ++ 实现  
JNI内容有很多应用入门 ,由于OpenCV所利用的JNI技术只要会写HelloWorld就可以啦,先推荐大家一本书Pro Android C++ with the NDK(密码:g4F4),有兴趣的童鞋可以看一看,这里的文章我们只如何用JNI写出HelloWorld~
-----------------------昏割线----------------------
1. Android的java代码
我们实现最基本的功能,点一下按钮显示HelloWorld,再点一下复原,HelloWorld的文字从C++代码中获取。阿军就利用Android Studio开发,基本都是默认设置给大家演示一下啦~
页面布局:activity_main.xml
<?xml version="1.0" encoding="utf-8"?> 
 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:paddingBottom= "@dimen/activity_vertical_margin" 
    android:paddingLeft= "@dimen/activity_horizontal_margin" 
    android:paddingRight= "@dimen/activity_horizontal_margin" 
    android:paddingTop= "@dimen/activity_vertical_margin" 
    android:orientation= "vertical" 
    tools:context= "demo.hello.MainActivity" > 
    
        android:id= "@+id/send_hello" 
        android:layout_width= "wrap_content" 
        android:layout_height= "wrap_content" 
        android:text= "Hello" /> 
    
        android:id= "@+id/say_hello" 
        android:layout_width= "wrap_content" 
        android:layout_height= "wrap_content" 
        android:layout_marginTop= "10dp"  /> 
    
 
MainActivity.java
package  demo.hello ; 
import  android.support.v7.app.AppCompatActivity ; 
import  android.os.Bundle ; 
import  android.view.View ; 
import  android.widget.Button ; 
import  android.widget.TextView ; 
public  class  MainActivity  extends  AppCompatActivity  { 
    private  Button  bnSendHello ; 
    private  TextView  tvSayHello ; 
    private  boolean  isSayHello  =  false ; 
    @Override 
    protected  void  onCreate ( Bundle  savedInstanceState )  { 
        super . onCreate ( savedInstanceState ); 
        setContentView ( R . layout . activity_main ); 
        bnSendHello  =  ( Button ) findViewById ( R . id . send_hello ); 
        tvSayHello  =  ( TextView )  findViewById ( R . id . say_hello ); 
        final  HelloWorld  helloWorld  =  new  HelloWorld (); 
        bnSendHello . setOnClickListener ( new  View . OnClickListener ()  { 
            @Override 
            public  void  onClick ( View  v )  { 
                if (! isSayHello )  { 
                    //从本地方法中获取字符串
                      tvSayHello . setText ( helloWorld . getString ()); 
                    bnSendHello . setText ( "RETURN" ); 
                    isSayHello  =  true ; 
                } else { 
                    tvSayHello . setText ( " " ); 
                    bnSendHello . setText ( "HELLO" ); 
                    isSayHello  =  false ; 
                } 
            } 
        }); 
    } 
} 
 
HelloWorld.java
package  demo.hello ; 
/**
  * Created by wcjzj on 2016/6/10.
  */ 
public  class  HelloWorld  { 
static  { 
try  { 
//加载编译好的动态库
              System . loadLibrary ( "HelloWorld" ); 
        } catch  ( Exception  e ){ 
            e . printStackTrace (); 
        } 
    } 
//本地方法,获取字符串
      public  native  String  getString (); 
} 
 
以上完成了Java层代码的编写,HelloWorld.java里完成动态库的加载和本地方法的声明。
2. HelloWorld.java中本地方法头文件生成
在Android Studio的termial窗口输入
一是:如果在HelloWorld.java中import了其他类(比如import android.graphics.Bitmap;),则需要-classpath
参数设定加载类的路径,比如说我现在的项目应该设置为
set classpath=C:\Users\wcjzj\Documents\work\android\Hello\app\src\main\java 
然后再生成h文件
javah -classpath . -jni demo.hello.HelloWorld 
否则,会提示无法加载类之类的错误
二是:如果提示没有找到javah之类的,需要把jdk的bin地址添加到环境路径path中
3. 建立jni文件夹存放c++/c文件
sourceSets.main {
      jni.srcDirs 'src/main/java/myjni'
  }
 
或者点击右键new->Folder->JNI Folder会自动在build.gradle添加如上代码,这里我们使用默认的配置,在java下建立jni文件夹,把上一步生成的demo_hello_HelloWorld.h剪切到jni文件夹中。
4. 编译运行效果如下
---------------------昏割线--------------------
阿军终于写完了,原来写新手教程这么累的啊....
这个是入门篇哦,如果对jni感兴趣最好把我推荐的那本书看了哦~我今天辛苦一下,还能再更一篇呢~^ ^
[2]OpenCV4Android机器视觉应用入门 -不使用OpenCV Manager的三种方法-法1:纯java层开发 - 王传军的文章 - 知乎专栏
[3]OpenCV4Android机器视觉应用入门 -不使用OpenCV Manager的三种方法-法2:java和native混编 - 行深般若 - 知乎专栏
[4]OpenCV4Android机器视觉应用入门 -不使用OpenCV Manager的三种方法-法3:纯native方法 - 王传军的文章 - 知乎专栏
[5]OpenCV4Android机器视觉应用入门 -拍照预览界面动态绘图
[6]OpenCV4IOS静态库制作
                                                (编辑:南平站长网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!