Android學習筆記之——opencv開發進一步探索

之前博文《Android學習筆記之——基於Android的opencv開發(Android studio3.6+opencv4.3.0開發環境搭建)》已經在Android studio中搭建了opencv的環境。本博文來進一步學習一下基於android的opencv開發

 

目錄

OpenCV Android SDK

將OpenCV打包jar包的方法

成功在手機上運行基於opencv的demo

參考資料


 

OpenCV Android SDK

OpenCV Android SDK 本質上是使用Java 語言接口通過JNI 技術調用OpenCV C++代碼完成的算法模塊。Open CV 4Android 本身並不是一個純Java 語言的計算機視覺庫,而是基於OpenCVC ++本地代碼、通過Java 語言接口定義,基於JNI 技術實現調
用C ++本地方法的SDK 開發包。所以當你下載好OpenCV Android SDK 之後,在它的SDK 目錄下可以看到如圖所示的目錄結構。

 OpenCV Android SDK 的功能與Open CV 對應發佈版本中的功能完全相同,唯一不同的是因爲Java 語言的關係, Java 層封裝的接口的參數傳遞和方法調用,與C++的接口相比有一些差異,這些都是爲了更適應Java 語言的特性而做出的改動,使得Android 開發者更加容易學習與使用Open CV 來解決問題。

 

將OpenCV打包jar包的方法

之前博文《Android學習筆記之——基於Android的opencv開發(Android studio3.6+opencv4.3.0開發環境搭建)》完成了開發環境搭建,但是每次都要這樣操作就非常麻煩了,此處將opencv打包爲jar包

首先點擊右邊的gradle,如圖所示:

依次選擇430,other,如圖所示

找到create full jar debug (或者release),如圖

雙擊任意一個運行,運行完成後,改爲project視圖,在opencv430-bulid-intermediates-full_jar-debug下找到full_jar文件,如圖所示

把full_jar複製到app項目的libs下,如圖所示:

右鍵full.jar,add as a library,如圖

點擊ok
然後你就可以使用opencv中的Java接口,不用每次都Import Module了,如圖

測試代碼

package com.example.androidopencvtest;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;


import org.opencv.android.OpenCVLoader;
import org.opencv.android.Utils;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.imgproc.Imgproc;
import org.opencv.android.CameraActivity;

import java.io.InputStream;

public class MainActivity extends AppCompatActivity {



    // Used to load the 'native-lib' library on application startup.
    static {
        if (!OpenCVLoader.initDebug()) {
//            System.loadLibrary("src/main/jniLibs");
            // Handle initialization error
        }
//        System.loadLibrary("native-lib");
//        System.loadLibrary("jniLibs");
//        System.loadLibrary("src/main/jniLibs");
//        System.loadLibrary("libs");
    }


    private double max_size = 1024;
    private int PICK_IMAGE_REQUEST = 1;
    private ImageView myImageView;
    private Bitmap selectbp;

    //權限
    private static String[] PERMISSIONS_STORAGE = {
//            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE,//寫權限
            Manifest.permission.CAMERA//照相權限
    };



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        staticLoadCVLibraries();
        myImageView = (ImageView)findViewById(R.id.imageView);
        myImageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
        Button selectImageBtn = (Button)findViewById(R.id.select_btn);
        selectImageBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // makeText(MainActivity.this.getApplicationContext(), "start to browser image", Toast.LENGTH_SHORT).show();
                selectImage();
            }

            private void selectImage() {
                Intent intent = new Intent();
                intent.setType("image/*");
                intent.setAction(Intent.ACTION_GET_CONTENT);
                startActivityForResult(Intent.createChooser(intent,"選擇圖像..."), PICK_IMAGE_REQUEST);
            }
        });

        //華爲手機攝像頭權限申請
        //用於判斷SDK版本是否大於23
        if (Build.VERSION.SDK_INT>= Build.VERSION_CODES.M){
            //檢查權限
            int i = ContextCompat.checkSelfPermission(this,PERMISSIONS_STORAGE[0]);
            //如果權限申請失敗,則重新申請權限
            if(i!= PackageManager.PERMISSION_GRANTED){
                //重新申請權限函數
                startRequestPermission();
                Log.e("這裏","權限請求成功");
            }
        }


        Button processBtn = (Button)findViewById(R.id.process_btn);
        processBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // makeText(MainActivity.this.getApplicationContext(), "hello, image process", Toast.LENGTH_SHORT).show();
                convertGray();
            }
        });

    }

    private void staticLoadCVLibraries() {
        boolean load = OpenCVLoader.initDebug();
        if(load) {
            Log.i("CV", "Open CV Libraries loaded...");
        }

    }

    private void convertGray() {
        Mat src = new Mat();
        Mat temp = new Mat();
        Mat dst = new Mat();
        Utils.bitmapToMat(selectbp, src);
        Imgproc.cvtColor(src, temp, Imgproc.COLOR_BGRA2BGR);
        Log.i("CV", "image type:" + (temp.type() == CvType.CV_8UC3));
        Imgproc.cvtColor(temp, dst, Imgproc.COLOR_BGR2GRAY);
        Utils.matToBitmap(dst, selectbp);
        myImageView.setImageBitmap(selectbp);
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) {
            Uri uri = data.getData();
            try {
                Log.d("image-tag", "start to decode selected image now...");
                InputStream input = getContentResolver().openInputStream(uri);
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inJustDecodeBounds = true;
                BitmapFactory.decodeStream(input, null, options);
                int raw_width = options.outWidth;
                int raw_height = options.outHeight;
                int max = Math.max(raw_width, raw_height);
                int newWidth = raw_width;
                int newHeight = raw_height;
                int inSampleSize = 1;
                if(max > max_size) {
                    newWidth = raw_width / 2;
                    newHeight = raw_height / 2;
                    while((newWidth/inSampleSize) > max_size || (newHeight/inSampleSize) > max_size) {
                        inSampleSize *=2;
                    }
                }

                options.inSampleSize = inSampleSize;
                options.inJustDecodeBounds = false;
                options.inPreferredConfig = Bitmap.Config.ARGB_8888;
                selectbp = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri), null, options);

                myImageView.setImageBitmap(selectbp);

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }


    private void startRequestPermission(){
        //321爲請求碼
        ActivityCompat.requestPermissions(this,PERMISSIONS_STORAGE,321);
    }

}

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_java"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:orientation="vertical"
    >

    <Button
        android:id="@+id/select_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="選擇圖片" />

    <Button
        android:id="@+id/process_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="處理" />

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

還是不行,應該就是沒有將opencv的庫編譯進去

成功在手機上運行基於opencv的demo

加入下面的代碼

    @Override            //免安裝Opencv manager
    protected void onResume() {
        super.onResume();
        if (!OpenCVLoader.initDebug()) {
            System.out.println("Internal OpenCV library not found. Using OpenCV Manager for initialization");
            OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_4_0, this, mLoaderCallback);
        } else {
            System.out.println("OpenCV library found inside package. Using it!");
            mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
        }
    }
    // OpenCV庫加載並初始化成功後的回調函數
    private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {

        @Override
        public void onManagerConnected(int status) {
            switch (status) {
                case LoaderCallbackInterface.SUCCESS: {
                    System.out.println("OpenCV loaded successfully");
                }
                break;
                default: {
                    super.onManagerConnected(status);
                }
                break;
            }
        }
    };

加上上邊這段代碼,下邊這兩個方法就是判斷是否已經存在OpenCv庫,存在就是用打包好的,不存在就下載。然後就ok啦~

接下來基本就可以將之前學過的opencv相關的開發移植到手機上了哈~

 

 

參考資料

https://blog.csdn.net/qq_39321542/article/details/106080136

https://blog.csdn.net/lhhnb/article/details/89705989

https://blog.csdn.net/lhhnb/article/details/94896434

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章