AndroidStudio 3.4.2配置 Opencv 3.7

前言:

前段时间做项目,需要给AS配置Opencv环境,查了很多博客,遇到了很多坑,为了避免遗忘,在此记录,如有错误,请指教。

1、前期准备

  • 下载opencv androidSdk:https://opencv.org/releases/
    在这里插入图片描述
    这里网速太慢,我截个图示意一下,我之前下载的是3.7版本

2、 新建AS项目

这一步要注意,AS3.2版本的时候可以勾选include C++ Surpport,而AS3.4.2把 NativeC++单独拿了出来,需要下拉右侧滑动条选择 Native C++,我之前找这个找了半天?
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3、配置NDK

NDK需要手动配置,在刚刚新建好的项目中,选择 file —>setting—>Android SDK —> SDK tools 勾选NDK和cmake
在这里插入图片描述

4、复制opencv的相关文件

  • include文件
    将下载好的opencv安装包解压后在路径*\OpenCV-android-sdk\sdk\native\jni下有一个include文件夹,复制该文件夹到我们项目中的src/main/cpp
  • jni 文件
    在项目的main文件夹下新建一个名为jniLibs的文件夹,然后在路径*\OpenCV-android-sdk\sdk\native下有一个libs文件夹,将此文件夹复制到刚刚新建的jniLibs文件夹下。项目结构如下图所示在这里插入图片描述

5、配置build-gradle

app下的build-gradle中的android节点下添加以下代码

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

此代码的作用就是设置动态链接库的地址,android节点是下图圈出的部分
在这里插入图片描述
然后在Android.defaultConfig.externalNativeBuild 的节点内增加过滤器,如下:

abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a', 'arm64-v8a', 'mips', 'mips64'

其中'x86', 'x86_64', 'armeabi', 'armeabi-v7a', 'arm64-v8a', 'mips', 'mips64',选择一个就行,如果是在模拟器上开发就选择X86,如果在手机上选择armeabi-v7a,这一步要注意的是过滤器添加的位置不要弄错了,是添加在下图中上第一个圈出来的节点。在这里插入图片描述
完整的build-gradle文件,如下

apply plugin: 'com.android.application'

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.1"
    defaultConfig {
        applicationId "com.example.opencvdemo"
        minSdkVersion 23
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        externalNativeBuild {
            cmake {
                cppFlags "-std=c++11"
                abiFilters 'armeabi-v7a'
            }
            ndk {
                abiFilters 'armeabi-v7a'
            }
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    externalNativeBuild {
        cmake {
            path "src/main/cpp/CMakeLists.txt"
            version "3.10.2"
        }
    }
    sourceSets {
        main {
            jniLibs.srcDirs = ['src/main/jniLibs/libs']
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:runner:1.2.0'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}

配置完后,Sysn Now一下

6、配置Cmake

还记得之前项目结构中的CMakeList.txt文件吗?这里我们需要先把该文件移动到app文件夹下,这样方便之后配置include文件夹路径和动态链接库的路径,与此同时需要将app下build-gradle文件中android.externalNativeBuild节点下cmake的路径修改为"CMakeLists.txt",即第二张图中 的path改为path "CMakeLists.txt"
在这里插入图片描述
在这里插入图片描述
CMakeLists.txt文件中添加如下代码。

# 设置include文件夹的地址
include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp/include)

# 设置opencv的动态库
add_library(libopencv_java3 SHARED IMPORTED)
set_target_properties(libopencv_java3 PROPERTIES IMPORTED_LOCATION
        ${CMAKE_SOURCE_DIR}/src/main/jniLibs/libs/${ANDROID_ABI}/libopencv_java3.so)
target_link_libraries( # Specifies the target library.
                       native-lib libopencv_java3

                       # Links the target library to the log library
                       # included in the NDK.
                       ${log-lib} )

include_directories 函数设置了include文件夹的路径
add_library 函数设置库名和类型,其中libopencv_java3 是用户自定义的变量名,前后保持一致即可,SHARE 表示引入的库是动态链接库
set_target_properties 设置了OpenCV的动态链接库的路径
target_link_libraries 具有依赖关系的动态库链接到指定目标上,链接顺序需符合gcc链接规则,这里我们把libopencv_java3log链接到了native-lib上。

7、测试

经过上面一些列配置,opencv环境已经配置完成,可以编写代码进行测试.

  • native-lib
#include <jni.h>
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;

extern "C" JNIEXPORT jintArray

JNICALL
Java_com_example_opencvdemo_MainActivity_Bitmap2Grey(
        JNIEnv *env,
        jobject /* this */,jintArray buf,jint w,jint h) {
    jint *cbuf;
    jboolean ptfalse = false;
    cbuf = env->GetIntArrayElements(buf, &ptfalse);
    if(cbuf == NULL){
        return 0;
    }

    Mat imgData(h, w, CV_8UC4, (unsigned char*)cbuf);
    // 注意,Android的Bitmap是ARGB四通道,而不是RGB三通道
    cvtColor(imgData,imgData,CV_BGRA2GRAY);
    cvtColor(imgData,imgData,CV_GRAY2BGRA);

    int size=w * h;
    jintArray result = env->NewIntArray(size);
    env->SetIntArrayRegion(result, 0, size, (jint*)imgData.data);
    env->ReleaseIntArrayElements(buf, cbuf, 0);
    return result;
}
  • MainActivity
package com.example.opencvdemo;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

import androidx.appcompat.app.AppCompatActivity;


public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("native-lib");
    }

    private Button btn_1;
    private Button btn_2;
    private ImageView imageView;
    private Bitmap bitmap;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn_1 = (Button)findViewById(R.id.button_1);
        imageView = (ImageView)findViewById(R.id.image);
        bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.flower);
        imageView.setImageBitmap(bitmap);
        btn_1.setOnClickListener(this);

        btn_2 = (Button)findViewById(R.id.button_2);
        btn_2.setOnClickListener(this);
    }
    public void showImage(){
        bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.flower);
        imageView.setImageBitmap(bitmap);
    }

    public void gray(){
        int w = bitmap.getWidth();
        int h = bitmap.getHeight();
        int[] piexls = new int[w*h];
        bitmap.getPixels(piexls,0,w,0,0,w,h);
        int[] resultData =Bitmap2Grey(piexls,w,h);
        Bitmap resultImage = Bitmap.createBitmap(w,h, Bitmap.Config.ARGB_8888);
        resultImage.setPixels(resultData,0,w,0,0,w,h);
        imageView.setImageBitmap(resultImage);
    }

    @Override
    public void onClick(View view){
        switch(view.getId()){
            case R.id.button_1:showImage();break;
            case R.id.button_2:gray();break;
        }
    }

    /**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */
    public native int[] Bitmap2Grey(int[] pixels,int w,int h);

    @Override
    public void onResume(){
        super.onResume();
    }
}
  • activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="vertical">

        <ImageView
            android:id="@+id/image"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:src="@drawable/flower" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:id="@+id/button_2"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="灰度图" />

        <Button
            android:id="@+id/button_1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="色图" />
    </LinearLayout>

</LinearLayout>
  • 效果
    在这里插入图片描述

8 参考链接

[1].Android NDK学习笔记:Android Studio3.1+CMAKE+OpenCV3.4配置
[2].AndroidStudio NDK之使用OpenCV
[3].Android Studio配置及使用OpenCV
[4].Android Studio中配置OpenCV

posted @ 2019-10-30 21:31  消灭猕猴桃  阅读(144)  评论(0编辑  收藏  举报