转自http://blog.csdn.net/yanzi1225627/article/details/16917961点击打开链接

开发环境:windows+ADT Bundle+CDT+OpenCV-2.4.4-android-sdk

一、OpenCV2.4简介

OpenCV近年来发展迅猛,随着Android智能终端的发展,越来越多的传统科研平台都转向Android移动终端。记得2010年人们还不大知道Android,当时第一次用OpenCV还是用的1.0.2版本在VC6.0上。早期的OpenCV只提供C语言接口,你要申请个矩阵还得CvMat *mat = cvCreateMat(...)写一大串,这样做是为了保证程序的运行效率,带来的不便是要开发者手动管理内存分配,稍有不慎内存泄漏那是常有的事。在OpenCV的发展历程上,第一次飞跃是2009年10月1日发布的2.0版本,该版本支持C++接口 了,是直接从1.2版本跳到2.0。不久又推出了2.1,自此后想要移植OpenCV至嵌入式系统,在编译时必须借助CMake工具,而以往的不用。 第二次飞跃是在2010年6月发布的2.3、2.3.1版本,除提供C++接口向下兼容C接口外,新增了Java接口,且是对准Android平台。更重要的是以前官方不支持ndk-build,这次终于一统JNI接口调用方式,方便在Android上开发使用。2012年4月2日发布了2.4版本,支持windows/Linux、Mac/Android/IOS四大系统。 最新的版本是2013年11月11日发布的2.7版本。我电脑上配置的是2.4.4版本。 从2.4之后,为了和Android的系统架构保持同步,准确说是吸收Android框架层的优点,引入了OpenCV Manager的概念,其本质就是一个Service,用来管理OpenCV动态链接库。它工作在APP和OpenCV的动态链接库之间。OpenCV Manager的结构就是模仿Android的Binder机制。其架构图如下:
APP在运行时会首先检查OpenCV Manager存在不,如果不存在则会提示安装。如果存在,就会连接这个服务,进一步初始化加载OpenCV库。流程如下:
对于开发者而言,了解即可。从应用层面讲,将OpenCV-2.4.4-android-sdk解压后,会看到如下文件夹:
其中sdk就是开包时要用到的包,samples是自带的示例,doc是说明文档,apk则就是OpenCV Manager。手机想要运行基于OpenCV的Java接口的程序,就必须先安OpenCV Manager。
不同的手机选择不同的版本,如果是英特尔平台就选那个带x86的。比较老的手机不支持ARMv7的选第三个。根据android的版本选择前两个。我手机支持的是第一种。安装后即可。

二、Android APP通过Java接口调OpenCV

1、配置

配置其实比较简单,比之前的用JNI接口调OpenCV要简单很多,不过为了保持同步,也即以后的开发中可以随意混用Java接口和JNI接口,我们仍将压缩包解压到跟工作空间平级的目录。然后将解压后的sdk文件夹命名为OpenCV4Android-sdk,拷贝到新建的工作空间中。假设新建的工作空间名为OpenCV4Android。
【备注:这里让它两平级是为了以后JNI调用时无需修改mk文件。注意解压后会嵌套一个目录,把它拷到最外层。sdk文件夹命名和拷贝到新的工作空间都不是必须的。】 打开Eclipse切换到这个新的工作空间,右键import---General---Existing Projects into workspaces,选择OpenCV解压后的那个sdk包。导入后看是否有错误,我的是提示找不到java.util.List这个包,原来是没有加载进来Android的SDK。选中项目,按快捷键Alter + Enter,点Android,选中一个SDK,要求3.0以上。然后clean一下,看bin文件夹下的opencv library - 2.4.4.jar是否生成,如果它生成了就表示已经导入成功。

2、新建项目并引入上面的jar包

任意新建一个Android Application Project,然后选中该项目快捷键Alter + Enter,在下面的加库区域点Add,将导入工作空间的opencv sdk选中:
可以看到在Android Dependencies中将刚到导包bin目录下生成的jar文件导进去了。之后就可以使用opencv的API了。 【备注:说白了就是为了把这个jar包导进来。在生成这个jar包后可以把它拷出来,新建一个user library参见导原生camera到eclipse这篇, 之后将包加进来是一样的。这个包只有200多kb,也可以将其直接拷贝到工程目录下的libs文件夹,也是ok的。但是这样做后,就看不到jar包里具体的子包了,如org.opencv.ml这些。】

3、一个完成的demo:将一个图片灰度化

项目名字为GrayProcess,下面贴源码: 布局文件: [html] view plain copy print ?
  1. <RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:paddingBottom="@dimen/activity_vertical_margin"
  6. android:paddingLeft="@dimen/activity_horizontal_margin"
  7. android:paddingRight="@dimen/activity_horizontal_margin"
  8. android:paddingTop="@dimen/activity_vertical_margin"
  9. tools:context=".MainActivity">
  10. <TextView
  11. android:layout_width="wrap_content"
  12. android:layout_height="wrap_content"
  13. android:layout_alignParentTop="true"
  14. android:text="@string/wellcome_words"/>
  15. <ImageView
  16. android:id="@+id/img_huaishi"
  17. android:layout_width="wrap_content"
  18. android:layout_height="wrap_content"
  19. android:background="@drawable/nanhuaijin"
  20. android:layout_centerInParent="true"/>
  21. <Button
  22. android:id="@+id/btn_gray_process"
  23. android:layout_width="wrap_content"
  24. android:layout_height="wrap_content"
  25. android:layout_below="@id/img_huaishi"
  26. android:layout_centerHorizontal="true"
  27. android:text="灰度化"/>"
  28. </RelativeLayout>
java文件: [java] view plain copy print ?
  1. packagecom.example.grayprocess;
  2. importorg.opencv.android.BaseLoaderCallback;
  3. importorg.opencv.android.OpenCVLoader;
  4. importorg.opencv.android.Utils;
  5. importorg.opencv.core.Mat;
  6. importorg.opencv.imgproc.Imgproc;
  7. importandroid.app.Activity;
  8. importandroid.graphics.Bitmap;
  9. importandroid.graphics.Bitmap.Config;
  10. importandroid.graphics.BitmapFactory;
  11. importandroid.os.Bundle;
  12. importandroid.os.Handler;
  13. importandroid.util.Log;
  14. importandroid.view.Menu;
  15. importandroid.view.View;
  16. importandroid.view.View.OnClickListener;
  17. importandroid.widget.Button;
  18. importandroid.widget.ImageView;
  19. publicclassMainActivityextendsActivity{
  20. ButtonbtnProcess;
  21. BitmapsrcBitmap;
  22. BitmapgrayBitmap;
  23. ImageViewimgHuaishi;
  24. privatestaticbooleanflag=true;
  25. privatestaticbooleanisFirst=true;
  26. privatestaticfinalStringTAG="MainActivity";
  27. //OpenCV库加载并初始化成功后的回调函数
  28. privateBaseLoaderCallbackmLoaderCallback=newBaseLoaderCallback(this){
  29. @Override
  30. publicvoidonManagerConnected(intstatus){
  31. //TODOAuto-generatedmethodstub
  32. switch(status){
  33. caseBaseLoaderCallback.SUCCESS:
  34. Log.i(TAG,"成功加载");
  35. break;
  36. default:
  37. super.onManagerConnected(status);
  38. Log.i(TAG,"加载失败");
  39. break;
  40. }
  41. }
  42. };
  43. @Override
  44. protectedvoidonCreate(BundlesavedInstanceState){
  45. super.onCreate(savedInstanceState);
  46. setContentView(R.layout.activity_main);
  47. initUI();
  48. btnProcess.setOnClickListener(newProcessClickListener());
  49. }
  50. @Override
  51. publicbooleanonCreateOptionsMenu(Menumenu){
  52. //Inflatethemenu;thisaddsitemstotheactionbarifitispresent.
  53. getMenuInflater().inflate(R.menu.main,menu);
  54. returntrue;
  55. }
  56. publicvoidinitUI(){
  57. btnProcess=(Button)findViewById(R.id.btn_gray_process);
  58. imgHuaishi=(ImageView)findViewById(R.id.img_huaishi);
  59. Log.i(TAG,"initUIsucess...");
  60. }
  61. publicvoidprocSrc2Gray(){
  62. MatrgbMat=newMat();
  63. MatgrayMat=newMat();
  64. srcBitmap=BitmapFactory.decodeResource(getResources(),R.drawable.nanhuaijin);
  65. grayBitmap=Bitmap.createBitmap(srcBitmap.getWidth(),srcBitmap.getHeight(),Config.RGB_565);
  66. Utils.bitmapToMat(srcBitmap,rgbMat);//convertoriginalbitmaptoMat,RGB.
  67. Imgproc.cvtColor(rgbMat,grayMat,Imgproc.COLOR_RGB2GRAY);//rgbMattograygrayMat
  68. Utils.matToBitmap(grayMat,grayBitmap);//convertmattobitmap
  69. Log.i(TAG,"procSrc2Graysucess...");
  70. }
  71. privateclassProcessClickListenerimplementsOnClickListener{
  72. @Override
  73. publicvoidonClick(Viewv){
  74. //TODOAuto-generatedmethodstub
  75. if(isFirst)
  76. {
  77. procSrc2Gray();
  78. isFirst=false;
  79. }
  80. if(flag){
  81. imgHuaishi.setImageBitmap(grayBitmap);
  82. btnProcess.setText("查看原图");
  83. flag=false;
  84. }
  85. else{
  86. imgHuaishi.setImageBitmap(srcBitmap);
  87. btnProcess.setText("灰度化");
  88. flag=true;
  89. }
  90. }
  91. }
  92. @Override
  93. protectedvoidonResume(){
  94. //TODOAuto-generatedmethodstub
  95. super.onResume();
  96. //loadOpenCVengineandinitOpenCVlibrary
  97. OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_4,getApplicationContext(),mLoaderCallback);
  98. Log.i(TAG,"onResumesucessloadOpenCV...");
  99. //newHandler().postDelayed(newRunnable(){
  100. //
  101. //@Override
  102. //publicvoidrun(){
  103. ////TODOAuto-generatedmethodstub
  104. //procSrc2Gray();
  105. //}
  106. //
  107. //},1000);
  108. }
  109. }
功能很简单,就是将一个图片灰度化,然后再次点击恢复成原来的。里面有几个需要注意的事项: a、Bitmap和Mat互相转换:Utils.bitmapToMat Utils.matToBitmap b、加载一个图片到Bitmap:BitmapFactory.decodeResource(getResources(), R.drawable.nanhuaijin); c、颜色转换:Imgproc.cvtColor(rgbMat, grayMat, Imgproc.COLOR_RGB2GRAY); d、grayBitmap的格式Config.ARGB_8888和Config.RGB_565都是可以的 e、最重要的一点:app在找OpenCV里的一些包时必须在onResume函数OpenCVLoader.initAsync()之后,否则会找不到库。最初我将procSrc2Gray();放在initUI()之后直接挂掉,后来放到OpenCVLoader.initAsync()依旧不行。除了上面代码里的方法外,还可以用一个延迟,默认等加载完包初始化后,再进行图像处理的操作: [java] view plain copy print ?
  1. newHandler().postDelayed(newRunnable(){
  2. @Override
  3. publicvoidrun(){
  4. //TODOAuto-generatedmethodstub
  5. procSrc2Gray();
  6. }
  7. },1000);
这样就ok了,在按键监听里无需在判断是否是第一次了。程序运行结果:

最后解释下OpenCV4Android的4应该是for的意思。另外,近年来还流行个词叫JavaCV。它和OpenCV4Android完全补一个概念,但都是java接口调用OpenCv。后文会撰文介绍其搭建方式和使用。通过JNI的方式调用OpenCV参见:http://blog.csdn.net/yanzi1225627/article/details/8525720

三、OpenCV网站导航

1、http://opencv.org/这是OpenCV的官方网站

2、http://wiki.opencv.org.cn/index.php/这是国内的官网老版

3、http://www.opencv.org.cn/国内的官网新版 鉴于自OpenCV新增C++接口后,国内的书籍就很少,几乎没有。尤其是增加OpenCV4Android Java接口后就更少了。后续将以专栏围绕翻译OpenCV4Android Java/C++ API,及介绍如何将数字图像处理与Android APP开发融合。 -------本文系原创,转载请注明作者yanzi1225627,欢迎大家加入OpenCV4Android开发联盟群:66320324,备注yanzi
示例中的代码下载:http://download.csdn.net/detail/yanzi1225627/6602691

更多相关文章

  1. 修改系统Android版本,版本号
  2. Android(安卓)SDK版本更新
  3. Android(安卓)SDK与ADT不匹配的问题 This Android(安卓)SDK requ
  4. Ubuntu上安装和使用Android(安卓)Studio
  5. android webview 设置
  6. Android实现圆角弹框功能
  7. android listview 自动加载
  8. Android(安卓)加载服务器上的图片
  9. android加载效果,带百分比的

随机推荐

  1. android eclipse 项目相互引用设置
  2. Android 封装http请求的工具类
  3. 智能手机软件平台 Android VS iPhone OS:
  4. 找回Kitkat的AppOps
  5. android 前后台切换 回调
  6. Android通过TCPIP协议实现断点续传上传实
  7. Android——字符高亮显示
  8. 【Android测试工具】02. Android抓包解析
  9. Android开机自启
  10. android 的动画