1. 程式人生 > >OpenCV在Android Studio上的部署

OpenCV在Android Studio上的部署

 

被Android Studio下配置OpenCV的問題折磨了快一週,昨天終於搞定了。

不知道是不是版本改進的問題,我的配置過程與網上大量的教程不太一樣,更簡單了。下面總結一下,希望能幫助到有需要的朋友。

 

第一節  軟體的下載

        1. 1 Android Studio   3.2         https://developer.android.google.cn/studio/

        1. 2 OpenCV   3.4.4                

https://sourceforge.net/projects/opencvlibrary/files/3.4.4/opencv-3.4.4-android-sdk.zip/download

        1. 3 Android SDK (android-sdk_r24.4.1-windows)                   http://www.androiddevtools.cn/

         安裝Android Studio   3.2,解壓OpenCV   3.4.4和Android SDK (android-sdk_r24.4.1-windows)。

 

第二節  在Android Studio上進行配置

         這是關鍵環節,也是折磨我好多天的環節

         2.1 Android Studio中 sdk 的配置

               點選File->Project Structure,在SDk Location標題下的 Android SDK Location處填寫本機sdk所在的資料夾。

        2.2 建立一個新工程,採取預設配置就行。我選擇API 21,Empty模板。

        2.3 配置OpenCV

2.3.1  匯入OpenCV module: File ->  New -> Import Module

然後選擇OpenCV資料夾中sdk->java資料夾即可

點選OK之後

會自動顯示Module Name。然後點選Next,Finish。

等待gradle更新。之後會出現

這個問題。先別急,我們將這個問題標註為 problem 1,稍後解決。

我們首先要修改openCVLibrary343目錄下的build.gradle檔案中的3個引數,使其與app下build.gradle中的引數一致。

點選以下兩個檔案

修改openCVLibrary343目錄下的build.gradle檔案中的3個引數,使其與app下build.gradle中的引數一致。箭頭所指為錯誤的引數,需要修改。

這是app下build.gradle檔案的引數

openCVLibrary343目錄下的build.gradle檔案改為下面這個德行

然後開啟openCVLibrary343目錄下manifests資料夾下AndroidManifest.xml,註釋掉右側箭頭指向的

<use-sdk android:  ...           ..../>欄位。

這樣就解決掉了problem 1。

然後點選右上角 Try again 來同步gradle工程

下面來新增依賴。點選File ->Project Structure。然後依次從左到右點選下圖箭頭所指的選項

出現下圖,點OK

OK之後,已經完成新增依賴。

此時,已經可以實現工程的打包,並安裝在手機上。但是此時如果執行依賴於OpenCV的程式碼,會報錯,會被要求安裝OpenCV Manager。

解決這個問題:  將OpenCV sdk下native下的libs資料夾複製,即下圖

貼上到app\src\main目錄下,如下左圖。並更名為jniLibs,ru'x如下右圖。

                                        

 

我們搞一個bmp檔案,命名為a.bmp,扔到app\src\main\res\drawable目錄中來測試。

至此,打包安裝到手機吧,大功告成。

測試為使用OpenCV進行圖片的灰度化。測試結果如下

                      

 

 

程式碼

1. 佈局檔案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"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="16dp"
android:paddingBottom="16dp"
tools:context=".MainActivity">

<ImageView
    android:id="@+id/img_huaishi"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"/>

    <Button
        android:id="@+id/btn_gray_process"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/img_huaishi"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="206dp"
        android:text="灰度化" />
    </RelativeLayout>

 

2. MainActivity.java

package com.example.administrator.ocvtest01;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.android.Utils;
import org.opencv.core.Mat;
import org.opencv.imgproc.Imgproc;

//import com.example.lenovo.R;

public class MainActivity extends AppCompatActivity {
    Button btnProcess;
    Bitmap srcBitmap;
    Bitmap grayBitmap;
    ImageView imgHuaishi;
    private static boolean flag = true;
    //private static boolean isFirst = true;
    private static final String TAG = "MainActivity";

    //OpenCV庫載入並初始化成功後的回撥函式
    private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {

        @Override
        public void onManagerConnected(int status) {
            // TODO Auto-generated method stub
            switch (status){
                case BaseLoaderCallback.SUCCESS:
                    Log.i(TAG, "成功載入");
                    break;
                default:
                    super.onManagerConnected(status);
                    Log.i(TAG, "載入失敗");
                    break;
            }

        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initUI();
        btnProcess.setOnClickListener(new ProcessClickListener());
    }
    public void initUI(){
        btnProcess = (Button)findViewById(R.id.btn_gray_process);
        imgHuaishi = (ImageView)findViewById(R.id.img_huaishi);
        Log.i(TAG, "initUI sucess...");

    }

    public void procSrc2Gray(){
        Mat rgbMat = new Mat();
        Mat grayMat = new Mat();
        srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.a);
        grayBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), Bitmap.Config.RGB_565);
        Utils.bitmapToMat(srcBitmap, rgbMat);//convert original bitmap to Mat, R G B.
        Imgproc.cvtColor(rgbMat, grayMat, Imgproc.COLOR_RGB2GRAY);//rgbMat to gray grayMat
        Utils.matToBitmap(grayMat, grayBitmap); //convert mat to bitmap
        Log.i(TAG, "procSrc2Gray sucess...");
    }

    private class ProcessClickListener implements View.OnClickListener {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
//            if(isFirst)
//            {
            procSrc2Gray();
//                isFirst = false;
//            }
            if(flag){
                imgHuaishi.setImageBitmap(grayBitmap);
                btnProcess.setText("檢視原圖");
                flag = false;
            }
            else{
                imgHuaishi.setImageBitmap(srcBitmap);
                btnProcess.setText("灰度化");
                flag = true;
            }
        }

    }

    @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);
        }
    }
}

 

祝大家愉快!

 

總結:與常見的文獻不同

1. 不需要ndk

2. 直接將 OpenCV sdk下native下的libs資料夾複製,貼上到app\src\main目錄下,並更名為jniLibs即可。不需要為此更改build.gradle檔案!!!!切記!!不用更改。改了肯定出錯。

 

引用稍後奉上,我去做飯先