opencv源码导入Android studio编译

一、下载opencv源码(以4.2.0为例)
https://github.com/opencv/opencv/releases
https://github.com/opencv/opencv_contrib/tags
二、配置电脑环境
环境要求
java 1.8
Android SDK Tools 25.2.5
Android SDK Build Tools 21.1.2
Android SDK target(sdk platform) 26
Android NDK 18.1.5063045
Android Cmake 3.31.1
mingw64
apache-ant-1.10.15
配置环境变量(替换成自己的路径)
D:\software\mingw64\bin
D:\software\apache-ant-1.10.15\bin
D:\software\sdk_tools_25.2.5\cmake\3.31.1\bin
三、新建android studio项目
新建时选择NativeC++项目类型,将opencv源码都解压到根目录下
四、编译
在opencv-4.2.0文件夹里新建build文件夹并cd进去执行编译命令。
生成Ninja构建脚本:(替换成自己的路径,版本建议保持一致,cmake -LA可以检查哪些变量可用)

cmake ^
    -GNinja ^
    -H"D:/gitc/NLOpenCV/opencv-4.2.0" ^
    -DCMAKE_MAKE_PROGRAM="D:/software/sdk_tools_25.2.5/cmake/3.31.1/bin/ninja.exe" ^
    -DCMAKE_INSTALL_PREFIX="D:/gitc/NLOpenCV/OpenCV-android-sdk" ^
    -DANDROID_PROJECT_BUILD_TYPE="ANT" ^
    -DBUILD_ANDROID_PROJECTS=ON ^
    -DBUILD_EXAMPLES=OFF ^
    -DBUILD_TESTS=OFF ^
    -DBUILD_PERF_TESTS=OFF ^
    -DBUILD_JAVA=ON ^
    -DBUILD_opencv_java=ON ^
    -DBUILD_SHARED_LIBS=OFF ^
    -DBUILD_FAT_JAVA_LIB=ON ^
    -DBUILD_PYTHON=OFF ^
    -DINSTALL_ANDROID_EXAMPLES=OFF ^
    -DANDROID_EXAMPLES_WITH_LIBS=OFF ^
    -DBUILD_DOCS=OFF ^
    -DWITH_OPENCL=ON ^
    -DANDROID_NDK="D:/software/sdk_tools_25.2.5/ndk/18.1.5063045" ^
    -DANDROID_SDK="D:/software/sdk_tools_25.2.5" ^
    -DCMAKE_TOOLCHAIN_FILE="D:/software/sdk_tools_25.2.5/ndk/18.1.5063045/build/cmake/android.toolchain.cmake" ^
    -DOPENCV_EXTRA_MODULES_PATH="D:/gitc/NLOpenCV/opencv_contrib-4.2.0/modules" ^
    -DANDROID_TOOLCHAIN=clang ^
    -DANDROID_STL=c++_static ^
    -DANDROID_ARM_NEON=ON ^
    -DANDROID_ABI=arm64-v8a ^
    -DANDROID_NATIVE_API_LEVEL=21 ^
    -DBUILD_opencv_python3=OFF ^
    -DBUILD_opencv_python2=OFF ^
    -DOPENCV_ENABLE_NONFREE=ON
使用 Ninja 构建系统命令:
ninja -j16
安装构建后的二进制文件到指定目录(也就是上面配置的DCMAKE_INSTALL_PREFIX的文件夹OpenCV-android-sdk)
ninja install

五、集成到as项目

1.将OpenCV-android-sdk/sdk当module导入项目
2.将OpenCV-android-sdk/sdk/native/jni/include文件夹拷贝到你的项目中src/main/cpp下面
3.在app\src\main\cpp\CMakeLists.txt中修改

add_library(${CMAKE_PROJECT_NAME} SHARED
        # List C/C++ source files with relative paths to this CMakeLists.txt.
        native-lib.cpp)
#opencv
set(OPENCV_LIBS_DIR ${CMAKE_SOURCE_DIR}/../cpp/include)
set(OPENCV_LIBS ${CMAKE_SOURCE_DIR}/../jniLibs)
add_library(libopencv_java4
        SHARED
        IMPORTED )
set_target_properties(libopencv_java4
        PROPERTIES IMPORTED_LOCATION
        ${OPENCV_LIBS}/${ANDROID_ABI}/libopencv_java4.so )
#指定引入头文件目录
include_directories(${OPENCV_LIBS_DIR})
find_library( # Sets the name of the path variable.
        log-lib
        log)
target_link_libraries( # Specifies the target library.
        ${CMAKE_PROJECT_NAME}
        libopencv_java4
        jnigraphics #JNI层,添加bitmap支持
        ${log-lib})

4.将OpenCV-android-sdk/sdk/native/libs里的文件拷贝到你的项目中src/main/jniLibs下面。并修改名字为jniLibs。
5.build.gradle(:app)的Android下添加
sourceSets{
main{
jniLibs.srcDirs = ['src/main/jniLibs']
}
}
6.将build.gradle的compileSdk、minSdkVersion、targetSdk修改跟app的一致
7.build.gradle(:OpenCV)的Android下添加
namespace 'org.opencv'
8.拷贝OpenCV-android-sdk\sdk\java\src\org\opencv\engine\OpenCVEngineInterface.aidlapp/src/aidl/org/opencv/engine/OpenCVEngineInterface.aidl
9.build.gradle(:OpenCV)的Android下添加
buildFeatures {
aidl true
}
10.gradle.properties中添加android.defaults.buildfeatures.buildconfig=true
11.注释掉androidManifest.xml(:OpenCV)的<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="21" />
12.删除androidManifest.xml(:OpenCV)的package="org.opencv"
13.build.gradle(:OpenCV)中修改
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
最终目录结构如下图


1736661823987.jpg

六、jni调用opencv函数实现高斯模糊
native-lib.cpp

#include <jni.h>
#include <string>
#include <android/bitmap.h>
#include <opencv2/opencv.hpp>
using namespace cv;
extern "C"
JNIEXPORT void JNICALL
Java_com_newlink_nlopencv_MainActivity_opencvTest(
        JNIEnv *env,jclass clazz,
        jobject bitmap) {
    AndroidBitmapInfo info;
    void *pixels;
    CV_Assert(AndroidBitmap_getInfo(env, bitmap, &info) >= 0);
    //判断图片是位图格式有RGB_565 、RGBA_8888
    CV_Assert(info.format == ANDROID_BITMAP_FORMAT_RGBA_8888 ||
              info.format == ANDROID_BITMAP_FORMAT_RGB_565);
    CV_Assert(AndroidBitmap_lockPixels(env, bitmap, &pixels) >= 0);
    CV_Assert(pixels);
    //将bitmap转化为Mat类
    Mat image(info.height, info.width, CV_8UC4, pixels);
    // 调用opencv函数进行高斯模糊
    GaussianBlur(image, image, Size(101, 101), 0);
}

MainActivity.java

package com.newlink.nlopencv;

import androidx.appcompat.app.AppCompatActivity;

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 android.widget.TextView;

import com.newlink.nlopencv.databinding.ActivityMainBinding;

public class MainActivity extends AppCompatActivity {

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

    private ActivityMainBinding binding;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());
        Bitmap Original_bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.img);
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.img);
        ImageView Original_image=findViewById(R.id.Original_image);
        Original_image.setImageBitmap(Original_bitmap);
        Button button=findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                opencvTest(bitmap);
                ImageView Image=findViewById(R.id.Image);
                Image.setImageBitmap(bitmap);
            }
        });
    }
    public static native void opencvTest(Object bitmap);
}

activity_main.xml

<?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"
    tools:context=".MainActivity"
    android:orientation="vertical">
    <ImageView
        android:id="@+id/Original_image"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        />
    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="高斯模糊"/>
    <ImageView
        android:id="@+id/Image"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        />
</LinearLayout>

效果如下


de150490e91e7b9d05852a7845fcf2d.jpg
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容