深入OpenCV Android应用开发

前言

OpenCV是Open Source Computer Vision library(开源的计算机视觉库)的缩写。它是使用最广泛的计算机视觉库。Opencv是计算机视觉领域常用的操作函数的集合,其自身由C/C++编写而成,同时也提供了对Python、Java以及任意JVM语言的封装。考虑到大部分Android应用是用C++/Java编写的,OpenCV也被移植为供开发者使用的SDK,以使他们开发的应用支持机器视觉。

一.Android平台部署OpenCV

1.下载地址:

OpenCV - Browse /opencv-android at SourceForge.netOpenCV - Browse /opencv-android/3.4.3 at SourceForge.net

 点击opencv-3.4.3-android-sdk.zip下载

 深入OpenCV Android应用开发_第1张图片

2.解压opencv-3.4.3-android-sdk.zip文件

3.创建Android项目命名为FirstOpenCVApp

4.找到opencv解压的文件夹

opencv-3.4.3-android-sdk下的java文件夹下的project.properties文件

例如压缩文件解压到桌面:C:\Users\SW\Desktop\opencv-3.4.3-android-sdk\OpenCV-android-sdk\sdk\java\project.properties

深入OpenCV Android应用开发_第2张图片

利用记事本打开,删除两行代码如下所示

深入OpenCV Android应用开发_第3张图片删除后如下图所示:

深入OpenCV Android应用开发_第4张图片由于AndroidStudio版本为4.1不删除无法编译通过。

5.Android项目导入opencv模块

点击File->New->Import Module...

深入OpenCV Android应用开发_第5张图片

选择Source directory:选择解压之后的目录C:\Users\SW\Desktop\opencv-3.4.3-android-sdk\OpenCV-android-sdk\sdk\java,点击OK

深入OpenCV Android应用开发_第6张图片

等待编辑完成,修改模块openCVLibrary343下的清单文件,去掉android:minSdkVersion="8"

删除之后的清单文件如下图所示:

深入OpenCV Android应用开发_第7张图片

修改模块openCVLibrary343下的build.gradle文件如下图所示:

深入OpenCV Android应用开发_第8张图片

以Android项目FirstOneOpencvApp下的src下的build.gradle为参考,尽量保持一致

FirstOneOpencvApp下的src下的build.gradle如下图所示:

深入OpenCV Android应用开发_第9张图片

点击同步,等待项目同步完成。

点击Android项目FirstOneOpencvApp File->Project Structure app添加Module依赖选择openCVLibrary343

深入OpenCV Android应用开发_第10张图片

检查Android项目FirstOneOpencvApp下的app下的build.gradle dependencies如下图所示:

深入OpenCV Android应用开发_第11张图片

检查settings.gradle如下图所示:

深入OpenCV Android应用开发_第12张图片

等待项目编译完成

6.Android项目新建HomeActivity

File->New->Activity->Empty Activity

Activity Name为HomeActivity

深入OpenCV Android应用开发_第13张图片

布局文件activity_home内容如下图所示



    

HomeActivity内容如下所示:

package com.suoer.comeonhealth.firstoneopencvapp;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import androidx.appcompat.app.AppCompatActivity;

public class HomeActivity extends AppCompatActivity {
    public static final int MEAN_BLUR=1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);
        Button bMean=findViewById(R.id.bMean);
        bMean.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i=new Intent(getApplicationContext(),MainActivity.class);
                i.putExtra("ACTION_MODE",MEAN_BLUR);
                startActivity(i);
            }
        });
    }
}

7.修改MainActivity

布局activity_main内容如下图所示:



    
    


资源文件下添加菜单

深入OpenCV Android应用开发_第14张图片

menu_main内容如下图所示:




MainActivity内容如下图所示:

package com.suoer.comeonhealth.firstoneopencvapp;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ImageView;

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

import java.io.FileNotFoundException;
import java.io.InputStream;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {
    private final int SELECT_PHOTO=1;
    private ImageView ivImage,ivImageProcessed;
    Mat src;
    static int ACTION_MODE=0;
    private BaseLoaderCallback mOpenCVCallBack=new BaseLoaderCallback(this) {
        @Override
        public void onManagerConnected(int status) {
           switch (status){
               case SUCCESS:
                   //在这里完成
                   break;
               default:
                   super.onManagerConnected(status);
                   break;
           }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ivImage=findViewById(R.id.ivImage);
        ivImageProcessed=findViewById(R.id.ivImageProcessed);
        Intent intent=getIntent();
        if(intent.hasExtra("ACTION_MODE")){
            ACTION_MODE=intent.getIntExtra("ACTION_MODE",0);
        }

    }

    @Override
    protected void onResume() {
        super.onResume();
        OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION,this,mOpenCVCallBack);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main,menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        int id=item.getItemId();
        if(id==R.id.action_load_image){
            Intent photoPickerIntent=new Intent(Intent.ACTION_PICK);
            photoPickerIntent.setType("image/*");
            startActivityForResult(photoPickerIntent,SELECT_PHOTO);
            return true;

        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case SELECT_PHOTO:
                if(resultCode==RESULT_OK){
                    try{
                        //以位图载入图像,并将其转换为Mat以供处理的代码
                        final Uri imageUri=data.getData();
                        final InputStream imageStream=getContentResolver().openInputStream(imageUri);
                        final Bitmap selectedImage= BitmapFactory.decodeStream(imageStream);
                        src=new Mat(selectedImage.getHeight(),selectedImage.getWidth(), CvType.CV_8UC4);
                        Utils.bitmapToMat(selectedImage,src);
                        switch (ACTION_MODE){
                            case  HomeActivity.MEAN_BLUR:
                                Imgproc.blur(src,src,new Size(3,3));
                                break;

                        }
                        //将Mat转换为位图,以便在ImageView中显示
                        Bitmap processedImage=Bitmap.createBitmap(src.cols(),src.rows(),Bitmap.Config.ARGB_8888);
                        Utils.matToBitmap(src,processedImage);
                        ivImage.setImageBitmap(selectedImage);
                        ivImageProcessed.setImageBitmap(processedImage);
                    }catch (FileNotFoundException e){
                        e.printStackTrace();
                    }
                }
                break;


        }
    }

}

8.查看手机设备的cpu架构

AndroidStudio连接手机

运行cmd.exe 输入命令:adb shell getprop ro.product.cpu.abi点击回车

arm64-v8a就是连接手机的cpu架构

找到opencv解压文件C:\Users\SW\Desktop\opencv-3.4.3-android-sdk\OpenCV-android-sdk\apk\OpenCV_3.4.3_Manager_3.43_arm64-v8a.apk

深入OpenCV Android应用开发_第15张图片

在cmd.exe中输入命令:adb install C:\Users\SW\Desktop\opencv-3.4.3-android-sdk\OpenCV-android-sdk\apk\OpenCV_3.4.3_Manager_3.43_arm64-v8a.apk

点击回车

深入OpenCV Android应用开发_第16张图片

手机安装此apk成功。安装成功以后,运行此项目。必须此项目在运行状态,进程不可以杀掉此项目,否则无法使用OpenCV提供的函数实现功能。

利用记事本打开C:\Users\SW\Desktop\opencv-3.4.3-android-sdk\OpenCV-android-sdk\apk下的readme.txt查看里面详细内容,安装哪一个apk需根据手机的cpu架构来选择安装。

深入OpenCV Android应用开发_第17张图片

9.Android项目清单




    
        
            
                

                
            
        
        

        
    

10.运行Android项目至手机

点击MEAN BLUR按钮进入MainActivity界面,点击右上角菜单按钮加载图片,选择图片,界面显示原使图像和均值模糊后的图像。

你可能感兴趣的:(opencv,opencv,人工智能,计算机视觉,android)