Window+NDK+Opencv编译+AS集成

下载opencv

https://github.com/opencv/opencv/releases

编译指令
cmake .. -G "Ninja" \
-DCMAKE_TOOLCHAIN_FILE="G:/SDK/ndk/26.0.10792818/build/cmake/android.toolchain.cmake" \
-DANDROID_NDK="G:/SDK/ndk/26.0.10792818" \
-DANDROID_ABI="arm64-v8a" \
-DANDROID_NATIVE_API_LEVEL=21 \
-DCMAKE_BUILD_TYPE=Release \
-DANDROID_STL=c++_shared \
-DBUILD_SHARED_LIBS=ON \
-DANDROID_TOOLCHAIN=clang \
-DANDROID_PLATFORM=android-21 \
-DCMAKE_VERBOSE_MAKEFILE=ON  \
-DBUILD_ANDROID_PROJECTS=OFF  \
-DBUILD_ANDROID_EXAMPLES=OFF  \
-DBUILD_JAVA=OFF


cmake .. -G "Ninja" -DCMAKE_TOOLCHAIN_FILE="G:/SDK/ndk/26.0.10792818/build/cmake/android.toolchain.cmake" \
-DANDROID_NDK="G:/SDK/ndk/26.0.10792818" \
-DANDROID_ABI="armeabi-v7a" \
-DANDROID_NATIVE_API_LEVEL=21 \
-DCMAKE_BUILD_TYPE=Release \
-DANDROID_STL=c++_shared \
-DBUILD_SHARED_LIBS=ON \
-DANDROID_TOOLCHAIN=clang \
-DANDROID_PLATFORM=android-21 \
-DCMAKE_BUILD_TYPE=Release  \
-DCMAKE_VERBOSE_MAKEFILE=ON \
-DBUILD_ANDROID_PROJECTS=OFF  \
-DBUILD_ANDROID_EXAMPLES=OFF  \
-DBUILD_JAVA=OFF  

ninja

报错 Android SDK Build Tools: directory doesn’t exist:

-- Performing Test HAVE_CXX_WNO_COMMA - Success
-- Update variable ANDROID_HOME from environment: G:/SDK/platform-tools
-- Android SDK: using location: G:/SDK/platform-tools
CMake Error at cmake/android/OpenCVDetectAndroidSDK.cmake:101 (message):
  Android SDK Build Tools: directory doesn't exist:
  G:/SDK/platform-tools/build-tools Use BUILD_ANDROID_PROJECTS=OFF to prepare
  Android project files without building them
Call Stack (most recent call first):
  cmake/android/OpenCVDetectAndroidSDK.cmake:173 (ocv_detect_android_sdk_build_tools)
  CMakeLists.txt:848 (include)

解决:修改ANDROID_HOME路径如下
在这里插入图片描述
在这里插入图片描述
注意:命令行需要重新打开

生成Makefile成功

--
-- General configuration for OpenCV 4.10.0 =====================================
--   Version control:               unknown
--
--   Platform:
--     Timestamp:                   2025-02-26T09:22:15Z
--     Host:                        Windows 10.0.19045 AMD64
--     Target:                      Android 1 aarch64
--     CMake:                       3.31.2
--     CMake generator:             Ninja
--     CMake build tool:            G:/MSYS2/mingw64/bin/ninja.exe
--     Configuration:               Release
--
--   CPU/HW features:
--     Baseline:                    NEON FP16
--     Dispatched code generation:  NEON_DOTPROD NEON_FP16 NEON_BF16
--       requested:                 NEON_FP16 NEON_BF16 NEON_DOTPROD
--       NEON_DOTPROD (1 files):    + NEON_DOTPROD
--       NEON_FP16 (2 files):       + NEON_FP16
--       NEON_BF16 (0 files):       + NEON_BF16
--
--   C/C++:
--     Built as dynamic libs?:      YES
--     C++ standard:                11
--     C++ Compiler:                G:/SDK/ndk/26.0.10792818/toolchains/llvm/prebuilt/windows-x86_64/bin/clang++.exe  (ver 17.0.2)
--     C++ flags (Release):         -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security     -fsigned-char -W -Wall -Wreturn-type -Wnon-virtual-dtor -Waddress -Wsequence-point -Wformat -Wformat-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wuninitialized -Winconsistent-missing-override -Wno-delete-non-virtual-dtor -Wno-unnamed-type-template-args -Wno-comment -Wno-deprecated-enum-enum-conversion -Wno-deprecated-anon-enum-enum-conversion -fdiagnostics-show-option -Qunused-arguments -ffunction-sections -fdata-sections    -fvisibility=hidden -fvisibility-inlines-hidden -O3 -DNDEBUG   -DNDEBUG
--     C++ flags (Debug):           -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security     -fsigned-char -W -Wall -Wreturn-type -Wnon-virtual-dtor -Waddress -Wsequence-point -Wformat -Wformat-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wuninitialized -Winconsistent-missing-override -Wno-delete-non-virtual-dtor -Wno-unnamed-type-template-args -Wno-comment -Wno-deprecated-enum-enum-conversion -Wno-deprecated-anon-enum-enum-conversion -fdiagnostics-show-option -Qunused-arguments -ffunction-sections -fdata-sections    -fvisibility=hidden -fvisibility-inlines-hidden -fno-limit-debug-info   -O0 -DDEBUG -D_DEBUG
--     C Compiler:                  G:/SDK/ndk/26.0.10792818/toolchains/llvm/prebuilt/windows-x86_64/bin/clang.exe
--     C flags (Release):           -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security    -fsigned-char -W -Wall -Wreturn-type -Wnon-virtual-dtor -Waddress -Wsequence-point -Wformat -Wformat-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wuninitialized -Winconsistent-missing-override -Wno-delete-non-virtual-dtor -Wno-unnamed-type-template-args -Wno-comment -Wno-deprecated-enum-enum-conversion -Wno-deprecated-anon-enum-enum-conversion -fdiagnostics-show-option -Qunused-arguments -ffunction-sections -fdata-sections    -fvisibility=hidden -fvisibility-inlines-hidden -O3 -DNDEBUG   -DNDEBUG
--     C flags (Debug):             -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security    -fsigned-char -W -Wall -Wreturn-type -Wnon-virtual-dtor -Waddress -Wsequence-point -Wformat -Wformat-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wuninitialized -Winconsistent-missing-override -Wno-delete-non-virtual-dtor -Wno-unnamed-type-template-args -Wno-comment -Wno-deprecated-enum-enum-conversion -Wno-deprecated-anon-enum-enum-conversion -fdiagnostics-show-option -Qunused-arguments -ffunction-sections -fdata-sections    -fvisibility=hidden -fvisibility-inlines-hidden -fno-limit-debug-info   -O0 -DDEBUG -D_DEBUG
--     Linker flags (Release):      -Wl,--build-id=sha1 -Wl,--no-rosegment -Wl,--no-undefined-version -Wl,--fatal-warnings -Wl,--no-undefined -Qunused-arguments   -Wl,--gc-sections -Wl,--as-needed -Wl,--no-undefined -Wl,--gc-sections
--     Linker flags (Debug):        -Wl,--build-id=sha1 -Wl,--no-rosegment -Wl,--no-undefined-version -Wl,--fatal-warnings -Wl,--no-undefined -Qunused-arguments   -Wl,--gc-sections -Wl,--as-needed -Wl,--no-undefined
--     ccache:                      NO
--     Precompiled headers:         NO
--     Extra dependencies:          dl m log
--     3rdparty dependencies:
--
--   OpenCV modules:
--     To be built:                 calib3d core dnn features2d flann gapi highgui imgcodecs imgproc ml objdetect photo stitching ts video videoio 
--     Disabled:                    world
--     Disabled by dependency:      -
--     Unavailable:                 java python2 python3
--     Applications:                tests perf_tests
--     Documentation:               NO
--     Non-free algorithms:         NO
--
--   Android NDK:                   G:/SDK/ndk/26.0.10792818 (ver 26.0.10792818)
--     Android ABI:                 arm64-v8a
--     NDK toolchain:               aarch64-linux-android-clang
--     STL type:                    c++_shared
--     Native API level:            21
--   Android SDK:                   not used, projects are not built
-- 
--   GUI:                           NONE
--
--   Media I/O:
--     ZLib:                        z (ver 1.2.13)
--     JPEG:                        build-libjpeg-turbo (ver 3.0.3-70)
--       SIMD Support Request:      YES
--       SIMD Support:              YES
--     WEBP:                        build (ver encoder: 0x020f)
--     PNG:                         build (ver 1.6.43)
--       SIMD Support Request:      YES
--       SIMD Support:              YES (Arm NEON)
--     TIFF:                        build (ver 42 - 4.6.0)
--     JPEG 2000:                   build (ver 2.5.0)
--     OpenEXR:                     build (ver 2.3.0)
--     HDR:                         YES
--     SUNRASTER:                   YES
--     PXM:                         YES
--     PFM:                         YES
--
--   Video I/O:
--    MEDIANDK:                     YES
--    NDK Camera:                   NO
--
--   Parallel framework:            pthreads
--
--   Trace:                         YES (with Intel ITT)
--
--   Other third-party libraries:
--     Custom HAL:                  YES (carotene (ver 0.0.1, Auto detected))
--     Protobuf:                    build (3.19.1)
--     Flatbuffers:                 builtin/3rdparty (23.5.9)
--
--   Python (for build):            G:/Python3.11/python.exe
--
--   Install to:                    G:/opencv-4.10.0_so/arm64-v8a_build/install
-- -----------------------------------------------------------------
--
-- Configuring done (56.9s)
-- Generating done (2.2s)
-- Build files have been written to: G:/opencv-4.10.0_so/arm64-v8a_build
安装

ninja install

安装目录 在这里插入图片描述

V7a同理

其他

指定输出目录
-DCMAKE_INSTALL_PREFIX=

集成到Android Studio

目录结构如下
在这里插入图片描述
build_gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion rootProject.ext.compileSdkVersion
    buildToolsVersion rootProject.ext.buildToolsVersion
    defaultConfig {
        applicationId "com.guide.opengllib"
        minSdkVersion rootProject.ext.minSdkVersion
        targetSdkVersion rootProject.ext.targetSdkVersion
        versionCode rootProject.ext.versionCode
        versionName rootProject.ext.versionName

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

        ndk {
            abiFilters /*"armeabi-v7a"*/"arm64-v8a"
        }

        externalNativeBuild {
            cmake {
                cppFlags ""
                // 检查是否有正确引入C++ 相关的库依赖,比如
                arguments "-DANDROID_STL=c++_shared"
            }
        }
    }
    lintOptions {
        abortOnError false
    }

    externalNativeBuild {
        cmake {
            path "CMakeLists.txt"
        }
    }
    sourceSets {
        main {
            jniLibs.srcDirs = ['src/main/cpp/libs']
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    implementation "androidx.appcompat:appcompat:$rootProject.ext.appcompatVersion"
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:runner:1.1.1'
    androidTestImplementation "androidx.test.espresso:espresso-core:3.2.0"
}

CmakeList.txt

 cmake_minimum_required(VERSION 3.4.1)
set(libname opencv_guidecore)

add_definitions("-D__STDC_CONSTANT_MACROS")

set(OpenCVHome ${CMAKE_SOURCE_DIR}/src/main/cpp)

include_directories(${OpenCVHome}/jni/include)

# 设置 STL 库
set(ANDROID_STL c++_shared)

# 设置 OpenCV 库路径
set(OpenCV_LIB_PATH ${OpenCVHome}/libs/${ANDROID_ABI})  # 根据实际路径设置

message(STATUS "OpenCV_LIB_PATH: ${OpenCV_LIB_PATH}")

add_library(opencv_imgproc
        SHARED
        IMPORTED)
set_target_properties(opencv_imgproc
        PROPERTIES IMPORTED_LOCATION
        ${OpenCV_LIB_PATH}/libopencv_imgproc.so)

add_library(opencv_core
        SHARED
        IMPORTED)
set_target_properties(opencv_core
        PROPERTIES IMPORTED_LOCATION
        ${OpenCV_LIB_PATH}/libopencv_core.so)

add_library(opencv_video
        SHARED
        IMPORTED)
set_target_properties(opencv_video
        PROPERTIES IMPORTED_LOCATION
        ${OpenCV_LIB_PATH}/libopencv_video.so)


add_library(opencv_imgcodecs
        SHARED
        IMPORTED)
set_target_properties(opencv_imgcodecs
        PROPERTIES IMPORTED_LOCATION
        ${OpenCV_LIB_PATH}/libopencv_imgcodecs.so)


file(GLOB SRC_FILES
        ${OpenCVHome}/*.cpp
        )

add_library( # Sets the name of the library.
        ${libname}
        SHARED
        ${SRC_FILES}
        )

find_library(log-lib log)

# 链接 OpenCV 的 .so 文件
target_link_libraries(
        ${libname}
        android
        ${log-lib}
        opencv_imgproc
        opencv_core
        opencv_video
        opencv_imgcodecs
)


JNI源码


#include <jni.h>
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc.hpp>  // 引入图像处理模块
#include <opencv2/core.hpp>     // 引入核心模块
#include "opencv_guidecore.h"
#include <android/log.h>

#define LOG_TAG "NativeLib"
#define LOGI(...)  __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)


extern "C"
JNIEXPORT void JNICALL
Java_com_guide_opengllib_MainGlActivity_processImage(JNIEnv *env, jobject thiz, jstring input_image_path, jstring output_image_path) {
    // 获取传递的图像路径字符串
    const char *input_path = env->GetStringUTFChars(input_image_path, nullptr);
    const char *output_path = env->GetStringUTFChars(output_image_path, nullptr);

    // 使用 OpenCV 读取图像
    cv::Mat image = cv::imread(input_path);
    if (image.empty()) {
        LOGI("Could not open or find the image!");
        return;
    }

    // 转换为灰度图像
    cv::Mat gray_image;
    cv::cvtColor(image, gray_image, cv::COLOR_BGR2GRAY);

    // 保存处理后的图像
    cv::imwrite(output_path, gray_image);

    // 释放资源
    env->ReleaseStringUTFChars(input_image_path, input_path);
    env->ReleaseStringUTFChars(output_image_path, output_path);

    LOGI("Image processed and saved to %s", output_path);
}


Activity中

static {
    System.loadLibrary("opencv_guidecore");  // 加载生成的 .so 库
}

// 声明本地方法
public native void processImage(String inputImagePath, String outputImagePath);

//实例3
findViewById(R.id.test3).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        processImage("", "");
    }
});
打印日志

在这里插入图片描述

集成第三方去噪点算法
https://github.com/Linwei-Chen/NL-means/blob/master/main.cpp

<think>嗯,用户之前问过关于使用Cygwin和NDK编译C文件生成动态库的问题,现在又问CMake和NDK编译C的流程。我需要先回顾之前的对话,确保这次回答能衔接上,同时补充新的信息。 首先,用户可能已经对NDK有一定的了解,但这次想转向CMake,因为CMake是官方推荐的方式。需要明确CMake相比Android.mk的优势,比如更简洁、跨平台、更好的IDE支持等。 接下来,我需要分步骤介绍环境配置、项目结构、CMakeLists.txt的编写、编译命令,以及常见问题。可能用户会遇到路径问题或者ABI配置的问题,需要提前给出解决方案。 还要注意用户可能在Windows环境下使用,所以路径的写法要正确,比如使用Cygwin或WSL的路径转换。另外,提到Android Studio的集成可能对用户有帮助,特别是如果他们使用AS进行开发的话。 需要检查是否需要解释一些基本概念,比如ABI、Clang编译器、CMake的基本语法,但考虑到用户之前接触过NDK,可能不需要太基础的内容,但简明扼要的解释还是必要的。 另外,用户可能会遇到的常见错误,比如找不到NDK路径、符号未定义、ABI不兼容等,需要给出具体的解决建议,比如检查环境变量、添加链接库、配置APP_ABI等。 最后,建议用户使用现代NDK版本,并提到兼容性和调试工具,比如ndk-stack,这样他们在遇到崩溃时可以有办法分析。同时,提醒他们CMake的灵活性和模块化优势,鼓励采用最佳实践。</think>以下是通过 **CMake + Android NDK** 编译 C 代码生成动态库/可执行文件的完整流程指南,分步骤说明关键操作和配置: ----- ### **1. 环境准备** #### 1.1 安装必要工具 - **Android NDK**:建议使用 **NDK r21+**(自带 Clang 编译器) - 通过 Android Studio 下载:`SDK Manager → NDK (Side by side)` - 或手动下载:[NDK 官网](https://developer.android.com/ndk/downloads) - **CMake**:最低 **3.10.2**(Android 官方要求) - 通过 Android Studio 自动安装,或独立安装最新版 #### 1.2 配置环境变量 ```bash # 在终端中设置(Windows 需添加到系统变量): export ANDROID_NDK_HOME=/path/to/android-ndk-r25c # NDK 路径 export PATH=$PATH:$ANDROID_NDK_HOME ``` ----- ### **2. 项目结构** ```bash project_root/ ├── app/ │ └── src/ │ └── main/ │ ├── cpp/ # C 源码目录 │ │ └── hello.c │ └── CMakeLists.txt # CMake 配置文件 ├── build/ # 编译输出目录(可手动创建) └── local.properties # 指定 NDK 路径(可选) ``` ----- ### **3. 编写 CMakeLists.txt** ```cmake # app/src/main/CMakeLists.txt cmake_minimum_required(VERSION 3.10) # 最低版本要求 # 定义项目名称和编译类型 project(hello_jni LANGUAGES C) set(CMAKE_BUILD_TYPE Release) # 或 Debug # 添加源代码(支持通配符 *.c) add_library( hello_jni # 输出库名:libhello_jni.so SHARED # 编译为动态库 cpp/hello.c # 源码路径 ) # 指定头文件搜索路径 target_include_directories(hello_jni PRIVATE ${CMAKE_SOURCE_DIR}/cpp) # 链接系统库(如 log、OpenSLES 等) target_link_libraries(hello_jni android # Android 基础库 log # 允许使用 __android_log_print ) ``` ----- ### **4. 编译命令** #### 4.1 使用 CMake 命令行编译 ```bash cd project_root/build # 生成编译配置(示例为 arm64-v8a) cmake -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake \ -DANDROID_ABI=arm64-v8a \ # 指定架构 -DANDROID_PLATFORM=android-24 \ # 最低 API 级别 ../app/src/main/ # 执行编译 cmake --build . ``` #### 4.2 输出结果 ``` build/ └── libhello_jni.so # 生成的动态库 ``` ----- ### **5. 关键配置选项** #### 5.1 **ABI 兼容性控制** 在 `CMakeLists.txt` 中添加: ```cmake # 指定多 ABI 编译 set(ANDROID_ABI "armeabi-v7a;arm64-v8a;x86_64") # 或通过命令行 -DANDROID_ABI=armeabi-v7a ``` #### 5.2 **优化与调试** ```cmake # 调试符号 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -Wall") # 优化级别 if(CMAKE_BUILD_TYPE STREQUAL Release) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2") endif() ``` ----- ### **6. 与 Android Studio 集成** 在 `app/build.gradle` 中配置: ```groovy android { defaultConfig { externalNativeBuild { cmake { arguments "-DANDROID_STL=c++_shared" # 指定 STL 库 abiFilters "armeabi-v7a", "arm64-v8a" # 过滤 ABI } } } externalNativeBuild { cmake { path "src/main/CMakeLists.txt" # CMake 文件路径 } } } ``` ----- ### **7. 常见问题解决** #### 7.1 **NDK 路径未找到** - **错误**:`Could not find NDK` - **解决**:确认 `local.properties` 中配置: ```properties ndk.dir=/path/to/android-ndk-r25c ``` #### 7.2 **符号未定义** - **错误**:`undefined reference to 'some_function'` - **解决**: ```cmake # 检查是否链接了正确的库 target_link_libraries(hello_jni other_lib # 添加缺失的库 ) ``` #### 7.3 **ABI 不兼容** - **错误**:`INSTALL_FAILED_NO_MATCHING_ABIS` - **解决**:确保 `abiFilters` 与设备架构匹配 ----- ### **8. 进阶技巧** 1. **交叉编译工具链选择**: - 使用 `clang` 替代 `gcc`(NDK r18+ 已移除 GCC) - 在 `CMakeLists.txt` 中指定: ```cmake set(CMAKE_C_COMPILER $ENV{ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang) ``` 2. **生成静态库**: ```cmake add_library(hello_static STATIC hello.c) # 输出 libhello_static.a ``` 3. **调试工具**: - 使用 `ndk-stack` 分析崩溃日志: ```bash ndk-stack -sym project_root/build/obj/local/arm64-v8a/ -dump crash.log ``` ----- ### **总结** CMake 提供了比传统 `Android.mk` **更简洁的语法**和**跨平台支持**,适合现代 NDK 开发。通过合理配置 `CMakeLists.txt`,可轻松实现多 ABI 编译、依赖管理和调试优化。如果遇到具体编译错误,可结合 `--verbose` 参数查看详细日志。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值