Sobel filter using OpenCV on Android (Java)

Introduction

I implemented a Sobel filter on Android using OpenCV 3.2. Note that there were some parts that Java's OpenCV couldn't do as expected.

Execution environment, etc.

software

Windows 10 Home 64bit Android Studio 2.2.3 OpenCV 3.2

Debug terminal

Nexus 5x (Android 7.1.1)

OpenCV preparation

See below Note on introducing OpenCV for Android to Android Studio

point

Since it is boring if it is just a one-way Sobel filter, after converting it to grayscale, it is intentionally divided into RGB components and filtered in the X and y directions for each color to obtain the root mean square. After that, the maximum value among the values of the three components was used as the final pixel value.

Note

With C ++ OpenCV

matC = matA +matB;

You can write like this, but you can't do it with Java's OpenCV

code

    private Bitmap sobel(Bitmap bitmap) {
        bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
        Mat mat = new Mat();
        Mat matR = new Mat();
        Mat matG = new Mat();
        Mat matB = new Mat();
        Utils.bitmapToMat(bitmap, mat);

        Core.extractChannel(mat, matR, 0);
        myFiltering(matR);

        Core.extractChannel(mat, matG, 1);
        myFiltering(matG);

        Core.extractChannel(mat, matB, 2);
        myFiltering(matB);

        matMax3(matB, matG, matR, matB);

        Utils.matToBitmap(matB, bitmap);
        return bitmap;
    }

    private void myFiltering(Mat src){
        Mat matX = new Mat();
        Mat matY = new Mat();

        Imgproc.GaussianBlur(src, src, new Size(3, 3), 0, 0);
        Imgproc.Sobel(src, matX, src.depth(), 0, 1);
        Imgproc.Sobel(src, matY, src.depth(), 1, 0);
        matRMS(matX, matY, src);
    }

    private void matRMS(Mat src1, Mat src2, Mat dst) {

        int size = (int) (src1.total() * src1.channels());
        byte[] temp1 = new byte[size];
        byte[] temp2 = new byte[size];
        byte[] temp3 = new byte[size];
        src1.get(0, 0, temp1);
        src2.get(0, 0, temp2);

        for (int i = 0; i < size; i++) {
            temp3[i] = (byte)Math.sqrt((temp1[i] * temp1[i] + temp2[i] * temp2[i]) / 2);
        }

        dst.put(0, 0, temp3);
    }

    private void matMax3(Mat src1, Mat src2, Mat src3, Mat dst) {

        int size = (int) (src1.total() * src1.channels());
        byte[] temp1 = new byte[size];
        byte[] temp2 = new byte[size];
        byte[] temp3 = new byte[size];
        byte[] temp4 = new byte[size];
        src1.get(0, 0, temp1);
        src2.get(0, 0, temp2);
        src3.get(0, 0, temp3);

        for (int i = 0; i < size; i++) {
            temp4[i] = chooseBig(chooseBig(temp1[i], temp2[i]), temp3[i]);
        }

        dst.put(0, 0, temp4);
    }

    private byte chooseBig(byte a, byte b) {
        if(b > a) {
            return b;
        }else {
            return a;
        }
    }

Execution result on the actual machine

Screenshot_20170216-223854-1.jpg

GitHub link

Implemented using AsyncTask for GUI convenience. Here

apk Link of built apk Here

reference

Image processing and recognition by OpenCV and Visual C ++ (7) ----- Use various edge detection filters -----

Recommended Posts

Sobel filter using OpenCV on Android (Java)
Desktop: OpenCV Sobel Filter2
Desktop: OpenCV Sobel Filter
Try using Firebase Cloud Functions on Android (Java)
Try communication using gRPC on Android + Java server
Try image classification using TensorFlow Lite on Android (JAVA)
Using Java on OSX 10.15 (Catalina) β
Save ArrayList using GSON on Android
Notes on Android (java) thread processing
Try using the service on Android Oreo
Using JupyterLab + Java with WSL on Windows 10
Calling java from C ++ on Android NDK
Notes on operators using Java ~ String type ~
I tried using OpenCV with Java + Tomcat
Build OpenCV with Java Wrapper on Ubuntu 18.04
[Java] Servlet filter
Install java and android-sdk on Mac using homebrew
[Android] [Java] Download images on GCS (Google Cloud Storage) with Stream using Glide
Android application development using Unity + ARCore on Ubuntu
Translator using Microsoft Translator Text API on Android ~ Implementation ~
[Java] 4 steps to implement splash screen on Android
Story of test automation using Appium [Android / java]
Using Java 8 with Bluemix (on Liberty Runtime & DevOps Service)
Create a Java development environment using jenv on Mac
Install java and maven using brew on new mac
Run the Android emulator on Docker using Android Emulator Container Scripts
I tried using Log4j2 on a Java EE server
Desktop: OpenCV Kirsch Filter
Desktop: OpenCV Laplacian Filter 2
Sorting using java comparator
[Java] Filter stack traces
Install Java on Mac
Desktop: OpenCV Freichennel Filter
[Java] Create a filter
Desktop: OpenCV Mean Filter
[Android] Notes on xml
Desktop: OpenCV Java Repository
Run PostgreSQL on Java
Using JDBC on Linux
Scraping practice using Java ②
Desktop: OpenCV pyrMeanShift Filter
Desktop: OpenCV Scharr Filter
Use OpenCV in Java
Desktop: OpenCV Laplacian Filter
Desktop: OpenCV Robinson Filter
Scraping practice using Java ①
Desktop: OpenCV SqrBox Filter
Desktop: OpenCV Prewitt Filter
Desktop: OpenCV Customized Filter
How to use OpenCV 4 on Android and view camera live view
Using multiple versions of Java with Brew on Mac + jEnv
[Beginner] android app that rolls a ball using a sensor [Java]
You are currently using Java 6. Solution in Android Studio Gradle
Try Hello World using plain Java on a Docker container
I tried using the CameraX library with Android Java Fragment
Use serial communication on Android
Try communication using gRPC on Android + Java server
[Android] Notes on xml