In-depth OpenCV Android application development

Preface

OpenCV is the abbreviation of Open Source Computer Vision library (open source computer vision library). It is the most widely used computer vision library. Opencv is a collection of commonly used operating functions in the field of computer vision. It is written in C/C++ and also provides encapsulation of Python, Java and any JVM language. Considering that most Android applications are written in C++/Java, OpenCV has also been ported as an SDK for developers to enable the applications they develop to support machine vision.

1. Deploying OpenCV on Android platform

1.Download address:

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

Click opencv-3.4.3-android-sdk.zip to download

2. Unzip the opencv-3.4.3-android-sdk.zip file

3. Create an Android project named FirstOpenCVApp

4. Find the folder where opencv was decompressed

The project.properties file in the java folder under opencv-3.4.3-android-sdk

For example, extract the compressed file to the desktop: C:\Users\SW\Desktop\opencv-3.4.3-android-sdk\OpenCV-android-sdk\sdk\java\project.properties

Open it with Notepad and delete the two lines of code as shown below

After deletion, it is as shown below:

Because AndroidStudio version is 4.1, it cannot be compiled without deletion. .

5.Android project imports opencv module

Click File->New->Import Module…

Select Source directory: Select the decompressed directory C:\Users\SW\Desktop\opencv-3.4.3-android-sdk\OpenCV-android-sdk\sdk\java and click OK

Wait for the editing to be completed, modify the manifest file under the module openCVLibrary343, and remove android:minSdkVersion=”8″

The manifest file after deletion is as shown below:

Modify the build.gradle file under the module openCVLibrary343 as shown below:

Use the build.gradle under src under the Android project FirstOneOpencvApp as a reference and try to keep it consistent.

The build.gradle under src under FirstOneOpencvApp is as shown below:

Click Sync and wait for the project synchronization to complete.

Click on the Android project FirstOneOpencvApp File->Project Structure app to add Module dependency and select openCVLibrary343

Check the build.gradle dependencies under the app under the Android project FirstOneOpencvApp as shown below:

Check settings.gradle as shown below:

Wait for project compilation to complete

6. Create new HomeActivity in Android project

File->New->Activity->Empty Activity

Activity Name is HomeActivity

The content of the layout file activity_home is shown in the figure below

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".HomeActivity">
    <Button

        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        android:id="@ + id/bMean"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Mean Blur"></Button>
</androidx.constraintlayout.widget.ConstraintLayout>

HomeActivity content is as follows:

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. Modify MainActivity

The layout activity_main content is as shown below:

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


</LinearLayout>

Add menu under resource file

The content of menu_main is as shown below:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@ + id/action_load_image"
    android:title="Loading pictures"
    android:orderInCategory="1"
    app:showAsAction="ifRoom"></item>
</menu>

The content of MainActivity is shown below:

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:
                   //Done here
                   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{
                        //Load the image as a bitmap and convert it to Mat for processing code
                        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;

                        }
                        //Convert Mat to bitmap for display in 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. Check the CPU architecture of the mobile device

AndroidStudio connects to mobile phone

Run cmd.exe and enter the command: adb shell getprop ro.product.cpu.abi and click Enter

arm64-v8a is the cpu architecture connected to mobile phones

Find the opencv decompression file C:\Users\SW\Desktop\opencv-3.4.3-android-sdk\OpenCV-android-sdk\apk\OpenCV_3.4.3_Manager_3.43_arm64-v8a.apk

Enter the command in 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

Click Enter

The mobile phone installed this apk successfully. After the OpenCV Manager is installed successfully, run this project. If FirstOneOpencvApp is killed by the process or the App exits completely, you need to re-run the OpenCV Manager project, otherwise the FirstOneOpencvApp project cannot use the functions provided by OpenCV to implement functions.

Use Notepad to open the readme.txt under C:\Users\SW\Desktop\opencv-3.4.3-android-sdk\OpenCV-android-sdk\apk to view the details. Which apk to install depends on the CPU architecture of the phone. to select installation.

9.Android project list

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.suoer.comeonhealth.firstoneopencvapp">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.FirstOneOpencvApp">
        <activity android:name=".HomeActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".MainActivity">

        </activity>
    </application>

</manifest>

10. Run Android projects on mobile phones

Click the MEAN BLUR button to enter the MainActivity interface, click the menu button in the upper right corner to load the image, select the image, and the interface displays the original image and the image after the mean value is blurred.

The knowledge points of the article match the official knowledge files, and you can further learn related knowledge. OpenCV skill tree Home page Overview 24002 people are learning the system