参考链接
http://681314.com/A/Clzr6Q2OBO
https://blog.csdn.net/xs1997/article/details/131747372
一、文章背景:公司再进行一个项目时,使用PyTorch框架,python语言及opencv工具进行神经网络深度学习算法进行训练。生成ONNX模型,但是该模型不能直接用在android平台,只能将该模型先转化为NCNN或TNN或MNN,再部署到AS中,运行在android系统。本文记录AS部署NCNN的方法。首先下载下面几个案例,将这些案例跑起来再对本公司的输出模型进行部署。
案例链接:
https://github.com/nihui/ncnn-android-squeezenet
https://github.com/nihui/ncnn-android-styletransfer
https://github.com/nihui/ncnn-android-mobilenetssd
https://github.com/moli232777144/mtcnn_ncnn
https://github.com/nihui/ncnn-android-yolov5
https://github.com/xiang-wuu/ncnn-android-yolov7
https://github.com/shaoshengsong/qt_android_ncnn_lib_encrypt_example
二、部署流程
注意:首先你的AS具有NDK开发环境。
1、下载ncnn包
下载网址:https://github.com/Tencent/ncnn/releases
我下载的是Andrid平台,可以GPU加速版本,给的7个案例中涉及的代码也是需要加速版本。
2、解压缩将ncnn部署到AS
1) 新建一个工程,并添加NDK环境;
2) 在/scr/main/cpp下新建文件夹jni,并将解压好的ncnn文件包放到jni文件夹下。
3)修改CMakeList.txt文件
4) 编译报错
CMake Error at D:/install/android-sdk/cmake/3.18.1/share/cmake-3.18/Modules/FindPackageHandleStandardArgs.cmake:165 (message):
Could NOT find Vulkan (missing: Vulkan_LIBRARY)
检查app的build.gradle文件,最低sdk版本不能小于24,把minSDK 改成24解决问题。
以上ncnn部署完成。
三、运行demo工程-ncnn-android-yolov5-master
因为AS版本不同,直接在AS中添加工程会有很多问题,所以我习惯新建工程,然后将demo中的代码复制到工程对应的文件中。
1、加载opencv
因为ncnn文件是由onnx转换的,onnx文件是神经网络+opencv+python训练生成的模型。所以工程中使用ncnn需要加载opencv。
2、将相关代码复制到工程
注意,assets文件夹下面的yolov5s.bin yolov5s.param,是ncnn文件。
3、修改CMakeList.txt文件
添加.h文件 .cpp文件
4、编译工程运行
编译不会报错,运行程序报错:
dlopen failed: library “libc++_shared.so” not found : externalNativeBuild { cmake { arguments “-DANDROID_STL=c++_shared” } }
解决方法:修改app build.gradle文件。
运行,可以识别到图片中物体:
四、运行demo工程-ncnn-android-yolov7-master
1、opencv及ncnn部署都一样,只是添加该demo文件修改CMakeList.txt文件即可。
2、CMakeList.txt文件
因为该工程需要ndkcamera及ndkmedia接口,所以添加这两个模块。
3、运行结果
最后,附上两个demo完整CMakeList.txt文件
# CMakeList.txt
cmake_minimum_required(VERSION 3.18.1)
project("onnxtest" CXX)
include_directories(${CMAKE_SOURCE_DIR}/include/yolov7 ${CMAKE_SOURCE_DIR}/include/yolov5s )
# 加载opencv
find_package(OpenCV 4.8.0 REQUIRED java)
# 设置ncnn
set(ncnn_DIR ${CMAKE_SOURCE_DIR}/jni/ncnn-20230816-android-vulkan/${ANDROID_ABI}/lib/cmake/ncnn)
find_package(ncnn REQUIRED)
file(GLOB CPP_FILES ${CMAKE_SOURCE_DIR}/source_yolov5s/onnxtest.cpp ${CMAKE_SOURCE_DIR}/source_yolov7/*.cpp )
add_library(
onnxtest
SHARED
${CPP_FILES}
)
find_library(
log-lib
log )
target_link_libraries( # Specifies the target library.
onnxtest
${log-lib}
${OpenCV_LIBRARIES}
ncnn
camera2ndk
mediandk)
// build.gradle
plugins {
id 'com.android.application'
}
android {
compileSdk 31
defaultConfig {
applicationId "com.htkj.onnxtest"
minSdk 24
targetSdk 31
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
cmake {
cppFlags "-std=c++11 -frtti -fexceptions"
arguments "-DOpenCV_DIR=" + "E:/work/xinchi/testProject/sdk/native/jni" ,"-DANDROID_STL=c++_shared"// , "-DANDROID_ARM_NEON=TRUE"
}
}
}
splits {
abi {
enable true
universalApk false
reset()
include 'armeabi-v7a' // , 'x86', 'x86_64', 'arm64-v8a'
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
externalNativeBuild {
cmake {
path file('src/main/cpp/CMakeLists.txt')
version '3.18.1'
}
}
signingConfigs {
release {
storeFile file("../platform.jks")
storePassword '123456'
keyAlias 'platform'
keyPassword '123456'
}
debug {
storeFile file("../platform.jks")
storePassword '123456'
keyAlias 'platform'
keyPassword '123456'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'com.google.android.material:material:1.4.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}