这篇教程展示了Android应用可以使用OpenCV(通过OpenCV应用助手类)的最简单的方法。这个应用通过使用OpenCV的Java API或者原生的摄像头API,从摄像头实时抓取预览框,并全屏模式显示。而且该应用支持用户在OpenCV Java模式和原生模式之间切换。
仔细观察下面AndroidManifest.xml文件的特殊许可,有这个才能被允许使用摄像头设备:
<uses-permissionandroid:name="android.permission.CAMERA"/>
<uses-featureandroid:name="android.hardware.camera"android:required="false"/>
<uses-featureandroid:name="android.hardware.camera.autofocus"android:required="false"/>
<uses-featureandroid:name="android.hardware.camera.front"android:required="false"/>
<uses-feature
android:name="android.hardware.camera.front.autofocus"android:required="false"/>
同时注意,AndroidManifest.xml文件中下面这行,它用来使能应用全屏模式运行:
<application
android:icon="@drawable/icon"
android:label="@string/app_name"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
本篇教程,仅仅定义了Android Activity类,并且用到了OpenCV的辅助视觉类<<Add hyperlink to description of the OpenCV Viewclass>>。该应用的布局在tutorial1_surface_view.xml文件中声明如下:
<FrameLayoutxmlns: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:visibility="gone"
android:id="@+id/tutorial1_activity_java_surface_view"
opencv:show_fps="true" opencv:camera_id="any" />
<org.opencv.android.NativeCameraView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:visibility="gone"
android:id="@+id/tutorial1_activity_native_surface_view"
opencv:show_fps="true" opencv:camera_id="any" />
</FrameLayout>
上面这段声明创建且隐藏了两个预定义的OpenCv类型全屏视窗。根据用户在应用菜单中的选择,每一个都能变成可见的。
该应用Activity类在Tutorial1Activity.java文件中定义。通过OpenCV管理Android服务(OpenCV Manager Android service)异步初始化OpenCV的代码如下:
BaseLoaderCallback mLoaderCallback = newBaseLoaderCallback(this) {
@Override
public void onManagerConnected(int status) {
switch (status) {
caseLoaderCallbackInterface.SUCCESS:
{
Log.i(TAG,"OpenCV loaded successfully");
mOpenCvCameraView.enableView();
} break;
default:
{
super.onManagerConnected(status);
} break;
}
}
};
@Override
public void onResume() {
super.onResume();
OpenCVLoader.initAsync( OpenCVLoader.OPENCV_VERSION_2_4_3,
this,mLoaderCallback );
}
注意,不允许使用OpenCV Java调用或者加载原生库,在调用这个回调函数之前调用OpenCV的函数。
这个Tutorial1Activity类implements CvCameraViewListener2接口,允许应用订阅onCameraFrame回调函数。这个回调函数在显示它之前,从摄像头分发了一个新的框架来处理它。订阅代码如下:
@Override
public void onResume() {
super.onResume();
OpenCVLoader.initAsync( OpenCVLoader.OPENCV_VERSION_2_4_3,
this,mLoaderCallback );
}
@Override
public void onCreate(BundlesavedInstanceState) {
// …
mOpenCvCameraView.setCvCameraViewListener(this);
}
接收到一个新的框架,acivity类并不处理它,仅仅是返回该框架,显示如下:
public Mat onCameraFrame(CvCameraViewFrameinputFrame) {
return inputFrame.rgba();
}