在之前的篇章中,我们完成了Android平台开发环境的配置,也找到了剔除OpenCV Manager API的办法,那么接下来我们开始从零开始,完成一个个人的程序,实现功能如下:

1.识别指定的图片,并用彩色框绘制图片边缘

2.在识别的图片上显示一个3D的模型

不难看出,这实际上就是AR最初步的功能,当然要完成这个功能却需要完成很多事情,步骤:

打开相机—>获取图像流—>模式识别—>对象跟踪—>绘制模型

===============================分割线=====================================

在这里,我们主要是调用OpenCV android SDK中的API来实现打开相机的功能。

一、知识准备:

1.了解Android工程如何运行在设备上

2.了解C/C++编译过程,能够读懂makefile


二、实现流程:

1.打开Eclipse,新建一个空白的Android工程:

项目名称为OpenCV_Test:


2.为新建工程引入OpenCV Library - 3.1.0库工程:

选择工程,右键点击Properties(属性),然后在Android页签中,用Add功能添加一个库工程引用。


3.打开src目录下面的MainActivity,由于我们的目标是在应用中通过OpenCV的Java API实现打开相机全屏显示,并获取预览框,所以MainActivity需要实现CvCameraViewListener2接口,可以实现三个方法,分别是:onCameraViewStartedonCameraViewStoppedonCameraFrame关键的图像处理写在onCameraFrame函数中:


4.修改AndroidManifest.xml文件:

添加相机的相关权限:

<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android.hardware.camera" android:required="false"/>
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
设置应用的界面主题为没有顶部标题栏且全屏显示的,在application标签中添加:

<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >

5.为界面布局文件添加显示相机内容的组件:

打开res/layout下面的activity_main.xml布局文件,往布局中添加一个OpenCV的视觉组件JavaCameraView

<RelativeLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:opencv="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

<org.opencv.android.JavaCameraView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/camera_view"
opencv:show_fps="true"
opencv:camera_id="any"/>

</RelativeLayout>


6.回到MainActivity中,完成API的调用:

声明一个CameraBridgeViewBase对象,用于存放activity_main.xml中的JavaCameraView组件,并在OnCreate中实现绑定和添加事件监听:

mCVCamera = (CameraBridgeViewBase) findViewById(R.id.camera_view);
mCVCamera.setCvCameraViewListener(this);


7.添加C/C++编译支持,即Add Native Support,这是为了不依赖于OpenCV Manager,直接引入库文件进行编译:


记住这里的填写的名称就是引入的库文件被编译生成.so文件的名称:


打开生成的jni目录下的Android.mk文件,这个是C/C++编译和链接时使用到的makefile配置文件,稍微做一点点修改内容,在“include $(CLEAR_VARS)”后面添加以下内容:

OPENCV_CAMERA_MODULES:=on
OPENCV_INSTALL_MODULES:=on
OPENCV_LIB_TYPE:=SHARED
ifdef OPENCV_ANDROID_SDK
ifneq ("","$(wildcard $(OPENCV_ANDROID_SDK)/OpenCV.mk)")
include ${OPENCV_ANDROID_SDK}/OpenCV.mk
else
include ${OPENCV_ANDROID_SDK}/sdk/native/jni/OpenCV.mk
endif
else
include ../../sdk/native/jni/OpenCV.mk
endif
如此,我们就完成了库文件的引入操作,那么接下来就是让相机的输入帧展示在预览组件JavaCameraView上。


8.修改public Mat onCameraFrame(CvCameraViewFrame inputFrame)回调函数的内容了,这个函数在相机刷新每一帧都会调用一次,而且每次的输入参数就是当前相机视图信息,我们直接获取其中的RGBA信息作为Mat数据返回给显示组件即可:

/**
* 图像处理都写在此处
*/
@Override
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
//直接返回输入视频预览图的RGBA数据并存在Mat数据中
return inputFrame.rgba();
}


9.以上操作中,我们在OnCreate函数中已经获取到mCVCamera对象,只有调用mCVCamera.enableView()之后,预览组件才会显示每一帧的Mat图像,但是在显示之前我们必须先确保OpenCV的库文件已经加载完成,所以调用此方法需要进行异步处理:

/**
* 通过OpenCV管理Android服务,异步初始化OpenCV
*/
BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
@Override
public void onManagerConnected(int status){
switch (status) {
case LoaderCallbackInterface.SUCCESS:
Log.i(TAG,"OpenCV loaded successfully");
mCVCamera.enableView();
break;
default:
break;
}
}
};

所以只有当mLoaderCallback收到LoaderCallbackInterface.SUCCESS消息的时候,才会打开预览显示,那么这个消息是从哪里发出来的呢,这就需要我们重写Activity的onRusume方法了,因为每次当前Activity激活都会调用此方法,所以可以在此处检测OpenCV的库文件是否加载完毕:

@Override
public void onResume() {
super.onResume();
if (!OpenCVLoader.initDebug()) {
Log.d(TAG,"OpenCV library not found!");
} else {
Log.d(TAG, "OpenCV library found inside package. Using it!");
mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
}
};


三、结果展示:

至此,我们就完成了设备 相机打开以及 输入预览数据的获取,运行在设备上可以看到:

更多相关文章

  1. 对于Android的文件结构介绍
  2. 浅析Android的资源打包和安装后Apk文件的下落
  3. Android 启动系统相机,相册,裁剪图片及6.0权限管理
  4. android 文件读取(assets)
  5. JAVA环境下创建JSP文件报错: The superclass "javax.servlet.http
  6. 【JavaWeb-6】HttpServletResponse的字符字节输出流、编码、文件
  7. Java 简单解决springmvc获取properties文件里面中文内容出现论码
  8. 解决Eclipse建立Maven项目后无法建立src/main/java资源文件夹的
  9. java读写中文文件

随机推荐

  1. 【Android】Android中的数据传递(2)
  2. Android--ExpandbleView源码学习一---Exp
  3. Qt for Android获取手机序列号
  4. Android百度地图SDK:隐藏比例尺,隐藏百度LO
  5. 新版NDK环境搭建(免Cygwin,超级快)
  6. 【Fragment】 Android Fragment生命周期
  7. Android_布局属性大全
  8. android发送restful风格的http请求
  9. Android应用程序键盘(Keyboard)消息处理机
  10. 阅读《Android 从入门到精通》(31)——Inte