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

猜你喜欢

转载自blog.csdn.net/gwplovekimi/article/details/106333175