Android安卓中同时使用opencv_android_sdk和jni

前面两篇文章Android安卓java中使用opencv-android-sdk 和Android安卓java中jni使用opencv native
介绍了如何在安卓中使用 opencv的android sdk, 如何在jni中使用opencv库, 以及如何生成 c++类库。

1、介绍
这里我们将在安卓项目中,使用opencv java sdk, 以及通过jni 调用基于opencv c++自定义的类。流程如下:

(1)创建项目,并导入opencv module并配置环境
(2)添加opencv native库、ObjectDetection库
(3)编写jni测试代码

基本操作步骤
第一步,在前面的博客中已经详细介绍。
第二步,将opencv的include添加到项目中,并复制opencv和objector_detcetion的库到jniLibs下。
Android安卓中同时使用opencv_android_sdk和jni_第1张图片 Android安卓中同时使用opencv_android_sdk和jni_第2张图片
2、java 代码部分
创建了Native C++项目TestJniLib,包名com.example.testjnilib
(1)增加一个native方法 public native boolean testObjDec(String modelPath , long pImage);
(2)增加调用native的代码
(3)加载库
MainActivity.java完整代码如下

package com.example.testjnilib;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.TextView;

import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Scalar;

public class MainActivity extends AppCompatActivity {

    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("native-lib");
		/// 3、加载需要的库
        System.loadLibrary("opencv_java4");
        System.loadLibrary("object_detection");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Example of a call to a native method
        TextView tv = findViewById(R.id.sample_text);
        tv.setText(stringFromJNI());
        
        /// 2、简单的调用native方法
        new Thread(new Runnable() {
            @Override
            public void run() {
                Mat img = new Mat(500,500, CvType.CV_8SC3, new Scalar(0,0,0));
                testObjDec("path",  img.nativeObj);
            }
        }).start();
    }

    /**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */
    public native String stringFromJNI();

    /**  1、增加的native函数, 调用ObjectDetection类
     * 
     * @param modelPath  路径
     * @param pImage     Mat的指针
     * @return
     */
    public native boolean testObjDec(String modelPath , long pImage);
}

3、jni 代码部分
完整代码如下

#include 
#include 

#include "ObjectDetection.h"

#include "opencv2/opencv.hpp"

extern "C" JNIEXPORT jstring JNICALL
Java_com_example_testjnilib_MainActivity_stringFromJNI( JNIEnv* env, jobject /* this */) 
{
	cv::Mat mat(100,100,CV_8UC3,cv::Scalar(1,2,4));   // test opencv c++
    std::string hello = "Hello from C++");
    return env->NewStringUTF(hello.c_str());
}


extern "C" JNIEXPORT jboolean JNICALL
Java_com_example_testjnilib_MainActivity_testObjDec( JNIEnv* env, jobject /* this */,
        jstring modelPath,
        jlong pImage)
{
    try {
        std::string path = env->GetStringUTFChars(modelPath, NULL); // jstring -> std::string

        std::string weightsPath = path + "/yolov3_tiny_10000.weights";
        std::string configPath = path + "/yolov3_tiny.cfg";

        ObjectDetection model;
        if (model.loadModel(weightsPath, configPath)) {
            // 加载失败
        }

        model.setParameters(0.00392, cv::Size(412, 412));

        std::vector<int> classIds;
        std::vector<float> confidences;
        std::vector<cv::Rect> boxes;
        model.process(*((cv::Mat *) pImage), classIds, confidences, boxes);
		
		// log 结果输出... 添加 #include

        return static_cast<jboolean>(true);
    }
    catch(std::exception& e){
        return static_cast<jboolean>(false);
    }
}

你可能感兴趣的:(android)