AndroidOpenCV配置与SimpleDemo

作者

郑楠

链接提供

陈榆

听项目组员说,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包,里面的文件如下

AndroidOpenCV配置与SimpleDemo_第1张图片

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

AndroidOpenCV配置与SimpleDemo_第2张图片

AndroidOpenCV配置与SimpleDemo_第3张图片

然后进入 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,按如图所示操作

AndroidOpenCV配置与SimpleDemo_第4张图片

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

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

AndroidOpenCV配置与SimpleDemo_第5张图片

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

Demo

AndroidManifest.xml


<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


<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 文件 修改后如图

AndroidOpenCV配置与SimpleDemo_第6张图片

你可能感兴趣的:(OpenCV)