36. Android configuration opencv4.4 and additional module (java/c++) darkenetyolo4.0 model checking that calls opencv4.4

Basic idea: Due to project needs, you need to test the recognition effect of the latest darknet yolo4 on Android Studio; here, record the configuration environment and development process; at the end of the blog, two Baidu links are provided, which are pure android use. Java calls the yolo4 model of opencv DNN and android uses C++ to call the yolo4 model of opencv DNN;

1. Create a usable Android Studio project, its configuration is basically as follows;

 

Then configure the environment compilation tool, my environment tool configuration tool is as follows:

Displayed on Android phone as: (other problems encountered during the period, please solve by yourself)

 2. Go to the opencv official website to download the Android code corresponding to opencv

axel -n 100 https://jaist.dl.sourceforge.net/project/opencvlibrary/4.4.0/opencv-4.4.0-android-sdk.zip

The unzipped directory structure is:

ubuntu@ubuntu:OpenCV-android-sdk$ tree -L 2
.
├── LICENSE
├── README.android
├── samples
│   ├── 15-puzzle
│   ├── build.gradle
│   ├── camera-calibration
│   ├── color-blob-detection
│   ├── face-detection
│   ├── gradle
│   ├── gradle.properties
│   ├── gradlew
│   ├── gradlew.bat
│   ├── image-manipulations
│   ├── settings.gradle
│   ├── tutorial-1-camerapreview
│   ├── tutorial-2-mixedprocessing
│   └── tutorial-3-cameracontrol
└── sdk
    ├── build.gradle
    ├── etc
    ├── java
    ├── libcxx_helper
    └── native

15 directories, 8 files

Then start importing the opencv4.4.0 module in Android Studio --->file--->new--->import Module

Then set the corresponding project corresponding package;

The download address of the configuration file for calling yolo4 by opencv4.4 in Android Studio is: https://github.com/opencv/opencv_extra/blob/4.4.0/testdata/dnn

Go to the yolo official website to download the model;

The code file of Android Sudio is: \app\src\main\java\com\example\testyolo4\MainActivity.java

package com.example.androidyolo;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.dnn.Dnn;
import org.opencv.dnn.Net;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import java.io.File;

public class MainActivity extends AppCompatActivity {

    static {
        System.loadLibrary("opencv_java4");
    }
    private String sdPath = Environment.getExternalStorageDirectory().getAbsolutePath();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        boolean load = OpenCVLoader.initDebug();
        if (load) {
            Log.i("MainActivity", "Open CV Libraries loaded...");
        } else {
            Log.i("MainActivity", "Open CV Libraries not loaded...");
        }
//
        String image_file = sdPath + File.separator + "1.png";//IMG_9452.JPG
        Mat im = Imgcodecs.imread(image_file, Imgcodecs.IMREAD_COLOR);
        // get a new Frame
        // Mat im = inputFrame.rgba();
        String[] names = new String[]{
                "aeroplane","bicycle","bird","boat","bottle",
                "bus","car","cat","chair","cow",
                "diningtable","dog","horse","motorbike","person",
                "pottedplant","sheep","sofa","train","tvmonitor"
        };
           ///\\storage\\sdcard0\\360\\yolov4-tiny.cfg
        String cfg_path= sdPath + File.separator + "yolov4.cfg";
        String model_path= sdPath + File.separator + "yolov4.weights";
        Net net = Dnn.readNetFromDarknet(cfg_path, model_path);
        if ( net.empty() ) {
            System.out.println("Reading Net error");
        }

        if( im.empty() ) {
            System.out.println("Reading Image error");
        }

        Mat frame = new Mat();
        Size sz1 = new Size(im.cols(),im.rows());
        Imgproc.resize(im, frame, sz1);
        Mat resized = new Mat();
        Size sz = new Size(416,416);
        Imgproc.resize(im, resized, sz);
        float scale = 1.0F / 255.0F;
        Mat inputBlob = Dnn.blobFromImage(im, scale, sz, new Scalar(0), false, false);
        net.setInput(inputBlob, "data");//
        Mat detectionMat = net.forward();//Mat detectionMat = net.forward("detection_out");
        if( detectionMat.empty() ) {
            System.out.println("No result");
        }

        for (int i = 0; i < detectionMat.rows(); i++)
        {
            int probability_index = 5;
            int size = (int) (detectionMat.cols() * detectionMat.channels());
            float[] data = new float[size];
            detectionMat.get(i, 0, data);
            float confidence = -1;
            int objectClass = -1;
            for (int j=0; j < detectionMat.cols();j++)
            {
                if (j>=probability_index && confidence<data[j])
                {
                    confidence = data[j];
                    objectClass = j-probability_index;
                }
            }

            if (confidence > 0.3)
            {
                System.out.println("Result Object: "+i);
                for (int j=0; j < detectionMat.cols();j++)
                    System.out.print(" "+j+":"+ data[j]);
                System.out.println("");
                float x = data[0];
                float y = data[1];
                float width = data[2];
                float height = data[3];
                float xLeftBottom = (x - width / 2) * frame.cols();
                float yLeftBottom = (y - height / 2) * frame.rows();
                float xRightTop = (x + width / 2) * frame.cols();
                float yRightTop = (y + height / 2) * frame.rows();
                System.out.println("Class: "+ names[objectClass]);
                System.out.println("Confidence: "+confidence);
                System.out.println("ROI: "+xLeftBottom+" "+yLeftBottom+" "+xRightTop+" "+yRightTop+"\n");

                Imgproc.rectangle(frame, new Point(xLeftBottom, yLeftBottom),
                        new Point(xRightTop,yRightTop),new Scalar(0, 255, 0),3);
            }
        }

        Imgcodecs.imwrite(sdPath + File.separator +"out.jpg", frame );

        ///

    }
}

Output picture

Provide a packaged Android Studio & Opencv4.4.0 project

Link: https://pan.baidu.com/s/1iEvY9yYJzXn3ZcBFD4n40A 
Extraction code: uyx1

Supplement: If you want to use opencv4.4.0 in the c++ module of Android, you only need to complete the following steps. It is not necessary to import the entire SDK of opencv4.4.0, just import the libs package and the corresponding include header file. (Note also Need to configure the corresponding Android cmakefile.txt and corresponding gradle):

Copy the corresponding file to the corresponding directory. If there is no folder, please create it yourself;

The corresponding other file modification and configuration are:

The modified content of the CMakefile.txt file is:

# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html

# Sets the minimum version of CMake required to build the native library.

cmake_minimum_required(VERSION 3.4.1)

# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.

# 添加opencv的头文件目录
include_directories(${CMAKE_SOURCE_DIR}/include)

# 导入opencv的so
add_library(libopencv_java4 SHARED IMPORTED)
set_target_properties(libopencv_java4 PROPERTIES IMPORTED_LOCATION
        ${CMAKE_SOURCE_DIR}/../jniLibs/libs/${ANDROID_ABI}/libopencv_java4.so)

add_library( # Sets the name of the library.
             native-lib

             # Sets the library as a shared library.
             SHARED

             # Provides a relative path to your source file(s).
             native-lib.cpp )

# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.

find_library( # Sets the name of the path variable.
              log-lib

              # Specifies the name of the NDK library that
              # you want CMake to locate.
              log )

# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.

target_link_libraries( # Specifies the target library.
                       native-lib
                        jnigraphics
                        libopencv_java4 # 链接opencv的so
                       # Links the target library to the log library
                       # included in the NDK.
                       ${log-lib} )

Corresponding gradle file modification;

        externalNativeBuild {
            cmake {
                cppFlags "-std=c++11"
                arguments '-DANDROID=c++_shared'
                abiFilters 'armeabi-v7a','arm64-v8a','x86','x86_64'

            }
        }
    }
    sourceSets{
        main{
            jniLibs.srcDirs=["src/main/jniLibs/libs"]
        }
    }

Then you can call opencv in the Android C++ model;

Here is an example of android using opencv4.4.0 to call C++ yolo4: (The code provides the use of the list data structure in C++ to encapsulate the code logic in the list structure passed to Android, you can refer to it~~)

Link: https://pan.baidu.com/s/1PDHyaCGTwq-LE95vv4yAxg 
Extraction code: k2yn

Guess you like

Origin blog.csdn.net/sxj731533730/article/details/108380540