AndroidOpenCV配置与SimpleDemo

来源:互联网 发布:白金数据观后感 编辑:程序博客网 时间:2024/05/16 03:29

作者

郑楠

链接提供

陈榆

听项目组员说,Android上也能撸OpenCV,而且还是纯Java。还在寝室的等发霉我立马关掉了屁股开始尝试。闲话就说到这,开始正事。主要步骤还是按照官方文档来,嘛,不过也遇到了几个坑,下面会一一列出。

致谢

https://www.youtube.com/watch?v=JIHfqzTdOcQ
http://stackoverflow.com/questions/27470313/opencv-service-intent-must-be-explicit-android-5-0-lolipop#
http://opencv.org/

准备

IDE Gradle OpenCV SDK Android Studio 2.1.2 com.android.tools.build:gradle:2.1.2 OpenCV-2.4.9-android-sdk

配置

解压SDK包,里面的文件如下

SDK目录

使用 Android Studio 建立一个新项目,选择 Empty Activity 。 右键项目,按如图所示操作。

生成JNI目录

JNI目录命名

然后进入 OpenCV-2.4.9-android-sdk\sdk\native\libs 把目录复制到新建立的JNI目录中

第一个坑

注意,这里要根据你手机的CPU指令集来复制,如果一次性全都复制过去的话,运行的时候可能会在Logout中输出 Cannot load library “opencv_java”。 我的手机是 Nexus 6 CPU APQ8084AB 指令集是 ARMv7,因此仅仅将 armeabi-v7a 这个目录复制到 app\src\main\jniLibs 目录下即可

导入官方 SDK Module,按如图所示操作

导入Model

这里要根据实际路径设置
选择Model

导入之后可能会报SDK错误,这时候需要进入导入的 Model 中修改的 build.gradle 文件,把targetSdkVersion 修改成和你的App一样的版本。修改完的截图如下

buildGradle修改

右键 app,依次选择 Open Model Settings, Dependencies, 选择 加号, Module dependency, openCVLibrary249, OK 这样就成功导入 JavaSDK 了。

Demo

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="org.ubibots.opencvchess">    <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"/>    <uses-feature        android:name="android.hardware.camera.front"        android:required="false"/>    <uses-feature        android:name="android.hardware.camera.front.autofocus"        android:required="false"/>    <application        android:allowBackup="true"        android:icon="@mipmap/ic_launcher"        android:label="@string/app_name"        android:supportsRtl="true"        android:theme="@android:style/Theme.NoTitleBar.Fullscreen">        <activity            android:name=".MainActivity"            android:screenOrientation="landscape">            <intent-filter>                <action                    android:name="android.intent.action.MAIN" />                <category                    android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>    </application></manifest>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    xmlns:opencv="http://schemas.android.com/apk/res-auto"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context="org.ubibots.opencvchess.MainActivity">    <org.opencv.android.JavaCameraView        android:layout_width="match_parent"        android:layout_height="match_parent"        android:visibility="gone"        android:id="@+id/HelloOpenCvView"        opencv:show_fps="true"        opencv:camera_id="any"/></RelativeLayout>

MainActivity.java

package org.ubibots.opencvchess;import android.app.Activity;import android.os.Bundle;import android.util.Log;import android.view.SurfaceView;import android.view.WindowManager;import org.opencv.android.BaseLoaderCallback;import org.opencv.android.CameraBridgeViewBase;import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;import org.opencv.android.LoaderCallbackInterface;import org.opencv.android.OpenCVLoader;import org.opencv.core.Mat;public class MainActivity extends Activity implements CvCameraViewListener2 {    private static final String TAG = "MainActivity";    static {        if(!OpenCVLoader.initDebug()){            Log.d(TAG, "OpenCV not loaded!");        }else {            Log.d(TAG, "OpenCV loaded!");        }    }    private CameraBridgeViewBase openCvCameraView;    @Override    protected void onCreate(Bundle savedInstanceState) {        Log.i(TAG, "called onCreate");        super.onCreate(savedInstanceState);        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);        setContentView(R.layout.activity_main);        openCvCameraView = (CameraBridgeViewBase) findViewById(R.id.HelloOpenCvView);        openCvCameraView.setVisibility(SurfaceView.VISIBLE);        openCvCameraView.setCvCameraViewListener(this);    }    private BaseLoaderCallback baseLoaderCallback = new BaseLoaderCallback(this) {        @Override        public void onManagerConnected(int status) {            switch (status) {                case LoaderCallbackInterface.SUCCESS: {                    Log.i(TAG, "OpenCV loaded successfully");                    openCvCameraView.enableView();                }                break;                default: {                    super.onManagerConnected(status);                }                break;            }        }    };    @Override    public void onResume() {        super.onResume();        OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_9, this, baseLoaderCallback);    }    @Override    public void onPause() {        super.onPause();        if(openCvCameraView != null){            openCvCameraView.disableView();        }    }    public void onDestroy(){        super.onDestroy();        if(openCvCameraView != null){            openCvCameraView.disableView();        }    }    public void onCameraViewStarted(int width, int height){    }    public void onCameraViewStopped(){    }    public Mat onCameraFrame(CvCameraViewFrame inputFrame){        return inputFrame.rgba();    }}

第二个坑

由于我的手机系统是 Android6.0 因此运行的时候会报错
java.lang.IllegalArgumentException: Service Intent must be explicit: Intent { act=org.opencv.engine.BIND }
这个是由于系统 5.0 开始安卓的机制更改,需要修改 SDK Module 中 src\main\java\org\opencv\android\AsyncServiceHelper 文件 修改后如图

修改SDK

1 0