【源码分析】Opencv-免装OpenCV Manager
来源:互联网 发布:数据库int长度 编辑:程序博客网 时间:2024/06/16 06:51
最近在接触opencv做图像处理的时候,发现直接使用OpenCV-2.4.10-android-sdk【在opencv自带的face-demo里可以看到怎么使用】在运行的时候需要安装一个OpenCV Manager,究竟是什么情况呢,下面通过源码分析一下:
在opencv源码里面的sample-face-demo的MainActivity的onResume函数会执行以下命令
@Override public void onResume() { super.onResume(); OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_10, MainActivity.this, mLoaderCallback)} }
opencv源码
/** * Loads and initializes OpenCV library using OpenCV Engine service. * @param Version OpenCV library version. * @param AppContext application context for connecting to the service. * @param Callback object, that implements LoaderCallbackInterface for handling the connection status. * @return Returns true if initialization of OpenCV is successful. */ public static boolean initAsync(String Version, Context AppContext, LoaderCallbackInterface Callback) { return AsyncServiceHelper.initOpenCV(Version, AppContext, Callback); }
这个函数会去加载并初始化opencv库,使用opencv引擎服务
接着进去
AsyncServiceHelper.initOpenCV
public static boolean initOpenCV(String Version, final Context AppContext, final LoaderCallbackInterface Callback) { AsyncServiceHelper helper = new AsyncServiceHelper(Version, AppContext, Callback); //绑定服务 //helper.mServiceConnection是回调接口 if (AppContext.bindService(new Intent("org.opencv.engine.BIND"), helper.mServiceConnection, Context.BIND_AUTO_CREATE)) { return true; } else { AppContext.unbindService(helper.mServiceConnection); InstallService(AppContext, Callback); return false; } }
在这个函数里面可以看到会去绑定相关的opencv引擎服务
绑定就需要用到OpenCV Manager的帮助了
helper.mServiceConnection是回调接口
那么onServiceConnected函数究竟做了什么?我们一探究竟
public void onServiceConnected(ComponentName className, IBinder service){Log.d(TAG, "Service connection created");mEngineService = OpenCVEngineInterface.Stub.asInterface(service);if (null == mEngineService){//注意,这里就去执行安装OpenCV Manager Log.d(TAG, "OpenCV Manager Service connection fails. May be service was not installed?"); InstallService(mAppContext, mUserAppCallback);}else{ mServiceInstallationProgress = false; ................ //省略了一部分代码 }}
一旦判断引擎服务为空,也就是连接失败的时候,就会执行
InstallService(mAppContext, mUserAppCallback);
进去可以看到
protected static void InstallService(final Context AppContext, final LoaderCallbackInterface Callback) { if (!mServiceInstallationProgress) { Log.d(TAG, "Request new service installation"); InstallCallbackInterface InstallQuery = new InstallCallbackInterface() { private LoaderCallbackInterface mUserAppCallback = Callback; public String getPackageName() { return "OpenCV Manager"; } public void install() { Log.d(TAG, "Trying to install OpenCV Manager via Google Play"); //这里会从Google Play 去下载OpenCV Manager 来安装 //安装成功返回true boolean result = InstallServiceQuiet(AppContext); if (result) { mServiceInstallationProgress = true; Log.d(TAG, "Package installation started"); } else { Log.d(TAG, "OpenCV package was not installed!"); int Status = LoaderCallbackInterface.MARKET_ERROR; Log.d(TAG, "Init finished with status " + Status); Log.d(TAG, "Unbind from service"); Log.d(TAG, "Calling using callback"); mUserAppCallback.onManagerConnected(Status); } public void cancel(){ Log.d(TAG, "OpenCV library installation was canceled"); int Status = LoaderCallbackInterface.INSTALL_CANCELED; Log.d(TAG, "Init finished with status " + Status); Log.d(TAG, "Calling using callback"); mUserAppCallback.onManagerConnected(Status); } public void wait_install() { Log.e(TAG, "Instalation was not started! Nothing to wait!"); } } } }
InstallServiceQuiet(AppContext);
protected static final String TAG = "OpenCVManager/Helper"; protected static boolean InstallServiceQuiet(Context context) { boolean result = true; try { //执行安装 Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(OPEN_CV_SERVICE_URL)); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent); } catch(Exception e) { result = false; } return result; }
拨开层层迷雾,终于可以看到执行安装Opnecv Manager的代码了,可以看到是通过Uri去下载
OPEN_CV_SERVICE_URL
/** * URL of OpenCV Manager page on Google Play Market. */ protected static final String OPEN_CV_SERVICE_URL = "market://details?id=org.opencv.engine";
安装完成就通过LoaderCallbackInterface回调处理相关逻辑
那么问题来了,可不可以绕过安装Opencv Manager,直接就能运行程序呢?答案是有的
在Opencv 3.30安装包里面也有Face-detection的Demo,里面的FdActivity的onResume函数改成以下:
@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_2_4_10, MainActivity.this, mLoaderCallback); } else { Log.d(TAG, "OpenCV library found inside package. Using it!"); mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS); } }
加了这个就可以实现不安装Opencv Manager 也能运行opencv的程序了
好,那它究竟是怎么工作的呢?
直接进入函数看
/** * Loads and initializes OpenCV library from current application package. Roughly, it's an analog of system.loadLibrary("opencv_java"). * @return Returns true is initialization of OpenCV was successful. */ public static boolean initDebug() { return StaticHelper.initOpenCV(false); }
看它的注释就可以知道
只要加载opencv的libs里面的libopencv_java.so就可以了
因此只需要把opencv3.30的开发包里面的libopencv_java.so导入到工程就可以了
具体步骤:
导入动态库
我这里只用了armeabi的架构,所以要去配置build_gradle
defaultConfig里面添加
android配置libs路径,我这里使用默认路径,所以要配置
最后在CMakeLists.txt 简单 配置
最后 Sync 一下项目就可以了
2017/10/26学习Opencv总结。
- 【源码分析】Opencv-免装OpenCV Manager
- OpenCV watershed 源码分析
- Opencv--Hog源码分析
- opencv源码分析:cvCreateTreeCascadeClassifier
- opencv AutoBuffer源码分析
- opencv Ptr源码分析
- opencv--cvThreshold源码分析
- opencv源码分析
- Opencv源码分析
- Opencv源码分析HoughCircles
- opencV源码分析之HOG
- opencv源码分析:icvGetTrainingDataCallback简介
- opencv中featureselect源码分析
- (OpenCV)HOG源码分析
- 【opencv】goodFeaturesToTrack源码分析-1
- 【OpenCV源码分析】core-Algorithm
- OpenCV之hog源码分析
- opencv grab cut源码分析
- vue.js指令v-for使用以及下标索引的获取
- 坚持
- (二)机器学习笔记之数据预处理
- 获取IP的地理位置
- Doing Homework
- 【源码分析】Opencv-免装OpenCV Manager
- NOIP2017模拟赛 约瑟夫游戏(数学乱搞)
- Web部署应用
- 数据可视化(二)Matplotlib pandas简易入门
- 使用Java语言实现对MySQL数据库的基本操作
- 宏的实例总结
- javascript----原型总结(3)(原型链)
- redis学习系列(十一)--redis-复制功能实践
- aapt命令可以查看包信息