【源码分析】Opencv-免装OpenCV Manager

最近在接触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总结。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值