android opencv3.1,Android Developent with OpenCV3.1

sam_code@hotmail.com

本文参考:

http://docs.opencv.org/2.4/doc/tutorials/introduction/android_binary_package/dev_with_OCV_on_Android.html#dev-with-ocv-on-android

http://docs.opencv.org/2.4/doc/tutorials/introduction/android_binary_package/O4A_SDK.html#o4a-sdk

0. 准备工作:

在开发机上:JDK, Android SDK, NDK, Eclipse,

ADT和CDT Eclipse插件等。并且安装了OpenCV4Android.

在运行环境中,OpenCV_3.1.0_Manager_3.10_armeabi-v7a.apk需要安装(SDK中提供不同Core和指令集的APK,根据运行环境不同而安装不同APK)

1. Android

Project使用OpenCV Library:

1.1:OpenCV Manager介绍:

从OpenCV-2.4.2 For Android 版本开始, OpenCV Manager就用作为Android

Project提供支持,帮助它使用OpenCV library.

OpenCV Manager是一个Android Service,

用来在用户终端上管理OpenCV Library.

它允许在同一设备上,多个应用程序访问同一套共享库,并提供以下好处:

A:节约内存空间,所有APP均使用Service中同一份二进制代码,并且不需要把native

library编译进每一个APP中。

B: 对所有支持平台均提供硬件优化。

C: 支持update和bug fix.

1.2:Java代码使用OpenCV:

1.2.1: 使用程序异步初始化方式使用OpenCV:

官方推荐使用异步初始化方式, 它通过之前安装好的OpenCV Manager访问OpenCV Library。

具体路径如下:

A:增加OpenCV Library Project到workspace中。

File -> Import -> Existing

project in your workspace.

a4c26d1e5885305701be709a3d33442f.png

编译之。则会生成opencv_library-3.1.0.jar

B: 导入异步初始化的例子程序--15 puzzle:

a4c26d1e5885305701be709a3d33442f.png

C: 把OpenCV Library 作为Jar库加入Application:

a4c26d1e5885305701be709a3d33442f.png

注意:Application的Project Build target与OpenCV Library Project的Build

Target相同。

D: 在Activity中添加:

private BaseLoaderCallback mLoaderCallback = new

BaseLoaderCallback(this) {

@Override

public void onManagerConnected(int status) {

switch (status) {

case LoaderCallbackInterface.SUCCESS:

{

Log.i(TAG, "OpenCV loaded successfully");

mOpenCvCameraView.setOnTouchListener(Puzzle15Activity.this);

mOpenCvCameraView.enableView();

} break;

default:

{

super.onManagerConnected(status);

} break;

}

}

};

这里要注意这个抽象类:

abstract class BaseLoaderCallback

抽象类不是无法实例化么? 但其实可以这样理解,在这里创建了一个匿名的类为BaseLoaderCallback的子类。

作为Activity的内部类。

这个抽象类有两个方法:

Method

Summary

void

Callback

method, called after OpenCV library initialization.

void

Callback

method, called in case the package installation is needed.

注意:OpenCV文档中明确说: OnManagerConnectedcallback

will be called in UI

thread

由于不允许在Initialization Finish完成前调用OpenCV API或Native

API。所以任何OpenCV相关调用都应该在此Callback之后。

E:OpenCVLoader:

Helper class provides common initialization methods for OpenCV

library.

Method

Summary

static boolean

Version,

android.content.Context

Loads

and initializes OpenCV library using OpenCV Engine service.

static boolean

Loads

and initializes OpenCV library from current application

package.

@Override

public void

onResume()

{

super.onResume();

if (!OpenCVLoader.initDebug()) {

Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager

for initialization");

OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this,

mLoaderCallback);

} else {

Log.d(TAG, "OpenCV library found inside package. Using it!");

mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);

}

}

initDebug():

Loads and initializes OpenCV library from current application

package. Roughly, it's an analog of

system.loadLibrary("opencv_java").

从本应用程序包内载入和初始化OpenCV

Library,相当于:system.loadLibrary("opencv_java3");

如果本地APP包含了OpenCV Library, 则返回True。 否则,返回false.

这里,我们使用OpenCV Manager, 并没有加入OpenCV Native

Library。所以返回false.

initAsync():

Loads and initializes OpenCV library using OpenCV Engine

service.

使用OpenCV Manager 初始化。

整个逻辑关系就是:

在onResume()时,使用initDebug()判断是否为本App Package

OpenCV Library. 如果是,则手动调用:

mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);

如果不是,则说明应该使用initAsync()调用OpenCV Manager来初始化。 OpenCV Manager

初始化完成后,则会调用onManagerConnected

F:如果要使用Camera,则还需要添加Camera权限。

完整例子,从15-puzzle为基础做的例子,它使用Async

Init模式,所以完全不需要把Native库加进来。

package com.android.example.spinner;

import org.opencv.android.BaseLoaderCallback;

import org.opencv.android.CameraBridgeViewBase;

import org.opencv.android.LoaderCallbackInterface;

import org.opencv.android.OpenCVLoader;

import org.opencv.core.Mat;

import

org.opencv.android.CameraBridgeViewBase.CvCameraViewListener;

import org.opencv.android.JavaCameraView;

import android.app.Activity;

import android.content.Context;

import android.content.SharedPreferences;

import android.os.Bundle;

import android.util.Log;

import android.view.View;

import android.view.WindowManager;

import android.widget.AdapterView;

import android.widget.ArrayAdapter;

import android.widget.Spinner;

import android.widget.TextView;

import android.widget.Toast;

import android.widget.AdapterView.OnItemSelectedListener;

public class SpinnerActivity extends Activity implements

CvCameraViewListener

{

private static final String TAG

= "SamInfo";

private CameraBridgeViewBase

mOpenCvCameraView;

private BaseLoaderCallback mLoaderCallback = new

BaseLoaderCallback(this) {

@Override

public void onManagerConnected(int status) {

switch (status) {

case LoaderCallbackInterface.SUCCESS:

{

Log.i(TAG, "OpenCV loaded successfully");

mOpenCvCameraView.enableView();

} break;

default:

{

super.onManagerConnected(status);

} break;

}

}

};

@Override

public void

onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

//setContentView(R.layout.main);

getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

Log.d(TAG, "Creating and setting view");

mOpenCvCameraView = (CameraBridgeViewBase) new

JavaCameraView(this, -1);

setContentView(mOpenCvCameraView);

mOpenCvCameraView.setVisibility(CameraBridgeViewBase.VISIBLE);

// 这里创建一个JavaCameraView,它是CameraBridgeViewBase的子Class. 而CameraBridgeViewBase又是SurfaceView的子Class。

//

同时,直接把这个CameraBridegViewBase设置为Layout。且可见,而且屏幕又不会灭

mOpenCvCameraView.setCvCameraViewListener(this);

//这句话很关键,指出当前CameraBridgeViewBase被谁所监听。监听者会在开始,结束,有数据时被调用。

}

@Override

public void

onResume() {

super.onResume();

if (!OpenCVLoader.initDebug()) {

Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager

for initialization");

OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this,

mLoaderCallback);

} else {

Log.d(TAG, "OpenCV library found inside package. Using it!");

mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);

}

// 此前解释过

}

@Override

public void

onPause() {

super.onPause();

if (mOpenCvCameraView != null)

mOpenCvCameraView.disableView();

}

@Override

public void onCameraViewStarted(int width, int

height) {

// TODO Auto-generated method

stub

Log.e(TAG,

String.format("onCameraViewStarted: w:%d. H:%d", width,

height));

}

@Override

public void onCameraViewStopped() {

// TODO Auto-generated method

stub

Log.e(TAG,

"onCameraViewStopped()");

}

@Override

public Mat onCameraFrame(Mat inputFrame) {

// TODO Auto-generated method

stub

Log.e(TAG,

"onCameraFrame()");

return inputFrame;

}

//这里每帧有数据时被调用,可以处理这个数据,处理后的数据返回,返回值则被显示在SurfaceView。

}

1.2.2:应用程序使用静态初始化方式使用OpenCV Library:

除了使用Async init 的方式使用OpenCV Library外,还有个Static

Init方式使用。但如果使用这个方式,则意味着所有OpenCV 二进制要包含进本App

Package。这个方法大都使用在开发阶段,产品release阶段,还是以Async init 方式为宜。

A:增加OpenCV Library Project到workspace中。

File -> Import -> Existing

project in your workspace.

a4c26d1e5885305701be709a3d33442f.png

B:把OpenCV Library 作为Jar库加入Application:

a4c26d1e5885305701be709a3d33442f.png

C:如果App没有JNI部分,则直接copy

OpenCV-android-sdk/sdk/native/libs//libopencv_java3.so

到工程libs/

例如:

# cp

OpenCV-android-sdk/sdk/native/libs/armeabi-v7a/libopencv_java3.so

OpenCV-android-sdk/samples/Spinner/libs/armeabi-v7a/

此时,因为本地Package内包含 libopencv_java3.so

. 所以initDebug()返回True。

D:如果APP有JNI部分,则不用再去手动copy动态库,而是在Android.mk中添加:

OPENCV_CAMERA_MODULES:=on

OPENCV_INSTALL_MODULES:=on

此时,编译中,会自动把libopencv_java3.so copy过来,和jni模块编译出的库放在一起。

这是,在Linux版本中,常会出现类似:ndk-build.cmd无法使用等。

需要设置两点:

1. NDK目录。

2. ndk-build 指令。

分别设置如下:

1. NDK 目录

方法一: Window -->Preferences-->Android-->NDK

a4c26d1e5885305701be709a3d33442f.png

方法二:

window-->Preferences-->C/C++-->build variables

a4c26d1e5885305701be709a3d33442f.png

2. 修改ndk-build.cmd问题:

这个在Eclipse下比较难找;

右击项目, Build Path-->Configure Build Path -->C++ build

a4c26d1e5885305701be709a3d33442f.png

把ndk-build.cmd 修改为ndk-build即可

附录:OpenCV API:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值