(二)ncnn | Windows10 + Android Studio环境配置


1. ncnn简介

n c n n {\rm ncnn} ncnn是一个为手机端极致优化的高性能神经网络前向计算框架,开源地址为ncnn。本文将介绍 n c n n {\rm ncnn} ncnn W i n d o w s 10 {\rm Windows10} Windows10下的编译,并使用 A n d r o i d   S t u d i o {\rm Android\ Studio} Android Studio测试。最后,使用该仓库 Y O L O v 5 {\rm YOLOv5} YOLOv5模型进行测试。


2. 相关依赖及软件安装

2.1 Android Studio

官网下载 A n d r o i d   S t u d i o {\rm Android\ Studio} Android Studio并安装。

2.2 安卓NDK

网址下载相应版本安卓 N D K {\rm NDK} NDK并解压文件。在此电脑=>高级系统设置=>环境变量的系统变量部分的Path添加 N D K {\rm NDK} NDK的根目录。使用命令行窗口测试是否安装成功:

在这里插入图片描述

2.3 CMake 3.18.0

官网下载相应版本,安装完成后需要配置环境变量。在此电脑=>高级系统设置=>环境变量的系统变量部分的Path添加 C m a k e {\rm Cmake} Cmake b i n {\rm bin} bin目录。使用命令行窗口测试是否安装成功:

在这里插入图片描述

2.4 VulkanSDK 1.2.154.1

官网下载相应版本,安装安装完成后需要配置环境变量。在此电脑=>高级系统设置=>环境变量的系统变量部分的Path添加 V u l k a n {\rm Vulkan} Vulkan b i n {\rm bin} bin目录。使用命令行窗口测试是否安装成功:

在这里插入图片描述

2.5 OpenCV 3.4.10

首先在该地址下载 o p e n c v   3.4.10 {\rm opencv\ 3.4.10} opencv 3.4.10,下载完成后安装即可。

2.6 逍遥安卓

本文使用逍遥安卓充当模拟器,官网下载。


3. 项目配置

3.1 ncnn编译

输入cmd打开命令行窗口,并使用如下命令编译armv7

cd <ncnn-root-dir>
mkdir build-android-armv7
cd build-android-armv7
cmake -DCMAKE_TOOLCHAIN_FILE="<android-ndk-root-dir>/android-ndk-r21b/build/cmake/android.toolchain.cmake" 
      -DANDROID_ABI="armeabi-v7a" 
      -DANDROID_ARM_NEON=ON 
      -DANDROID_PLATFORM=android-14 .. 
      -G "Unix Makefiles" 
      -DCMAKE_MAKE_PROGRAM="<android-ndk-root-dir>/android-ndk-r21b/prebuilt/windows-x86_64/bin/make.exe"
cmake -DCMAKE_TOOLCHAIN_FILE="<android-ndk-root-dir>/android-ndk-r21b/build/cmake/android.toolchain.cmake" 
      -DANDROID_ABI="armeabi-v7a" 
      -DANDROID_ARM_NEON=ON 
      -DANDROID_PLATFORM=android-24 
      -DNCNN_VULKAN=ON..
cmake --build .
cmake --build . --target install

使用如下命令编译aarch64

cd <ncnn-root-dir>
mkdir build-android-aarch64
cd build-android-aarch64
cmake -DCMAKE_TOOLCHAIN_FILE="<android-ndk-root-dir>/android-ndk-r21b/build/cmake/android.toolchain.cmake" 
      -DANDROID_ABI="arm64-v8a" 
      -DANDROID_PLATFORM=android-21 .. 
      -G "Unix Makefiles" 
      -DCMAKE_MAKE_PROGRAM="<android-ndk-root-dir>/android-ndk-r21b/prebuilt/windows-x86_64/bin/make.exe"
cmake -DCMAKE_TOOLCHAIN_FILE="<android-ndk-root-dir>/android-ndk-r21b/build/cmake/android.toolchain.cmake" 
      -DANDROID_ABI="arm64-v8a" 
      -DANDROID_PLATFORM=android-24 
      -DNCNN_VULKAN=ON ..
cmake --build .
cmake --build . --target install

一路成功!这里的<android-ndk-root-dir> N D K {\rm NDK} NDK安装的根目录。

3.2 新建安卓项目

打开 A n d r o i d   S t u d i o {\rm Android\ Studio} Android Studio新建安卓项目:Create New Project => Native C++ => (Name: ncnnYOLOv5, Minimum SDK: API24 Android7.0) => Finish,建立成功后的项目结构如下:

在这里插入图片描述

3.3 Android Studio连接逍遥安卓

首先打开逍遥安卓,然后命令行窗口然后切换到<root-dir>/MEmu目录,输入以下命令启动:

adb connect 127.0.0.1:21503

其他模拟器的连接方式如下:

夜神模拟器:adb connect 127.0.0.1:62001
天天模拟器:adb connect 127.0.0.1:6555 
海马玩模拟器:adb connect 127.0.0.1:53001
网易MUMU模拟器:adb connect 127.0.0.1:7555

连接成功:
在这里插入图片描述

3.4 完成整体项目

首先在res/layout/activity_main.xml中完成主界面的布局:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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">

    <Button
        android:id="@+id/button_detect_cpu"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="1dp"
        android:layout_marginTop="24dp"
        android:layout_marginBottom="44dp"
        android:text="DETECT-CPU"
        app:layout_constraintBottom_toTopOf="@+id/imageView"
        app:layout_constraintEnd_toStartOf="@+id/select"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/button_detect_gpu"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:layout_marginBottom="44dp"
        android:text="DETECT-GPU"
        app:layout_constraintBottom_toTopOf="@+id/imageView"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/select"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/select"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="5dp"
        android:text="SELECT"
        app:layout_constraintBaseline_toBaselineOf="@+id/button_detect_cpu"
        app:layout_constraintEnd_toStartOf="@+id/button_detect_gpu"
        app:layout_constraintStart_toEndOf="@+id/button_detect_cpu" />

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginStart="46dp"
        android:layout_marginEnd="46dp"
        android:layout_marginBottom="44dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button_detect_cpu" />
</androidx.constraintlayout.widget.ConstraintLayout>

完成之后效果如下:

在这里插入图片描述
java/com.example.ncnnyolov5目录下新建YOLOv5.java,内容不贴了代码有点多,链接

右键项目New => Folder => Assets Folder,将yolov5.paramyolov5.bin(来自参考部分的仓库)放入其中。

cpp目录下新建文件夹ncnn-lib,然后在ncnn-lib文件夹下新建三个文件夹分别用于存放前面编译产生的文件,aarch64文件存放对应install下的.a文件;armv7文件存放对应install下的.a文件;include文件夹存放armv7文件内include文件夹的内容。接着将x86x86_64文件夹(来自参考部分的仓库)放到该目录,并将使用到的头文件复制到cpp目录下,最终的目录结构 如下:

在这里插入图片描述

完成cpp/native-lib.cpp文件,内容不贴了代码有点多,链接

完成cpp/CMakeLists.txt文件:

# 设置项目名称
project(ncnnyolov5)
# 确定所需的最低CMake版本
cmake_minimum_required(VERSION 3.4.1)
# import ncnn library
# 导入ncnn,并将其设置为静态目录,即生成libncnn.a
add_library(ncnn STATIC IMPORTED)
# 导入编译后的静态库
set_target_properties(ncnn PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/ncnn-lib/${ANDROID_ABI}/libncnn.a)
include_directories(${CMAKE_SOURCE_DIR}/ncnn-lib/include/ncnn)
# 导入其他第三方库以及编译后的静态库
add_library(glslang STATIC IMPORTED)
add_library(OGLCompiler STATIC IMPORTED)
add_library(OSDependent STATIC IMPORTED)
add_library(SPIRV STATIC IMPORTED)
set_target_properties(glslang PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/ncnn-lib/${ANDROID_ABI}/libglslang.a)
set_target_properties(OGLCompiler PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/ncnn-lib/${ANDROID_ABI}/libOGLCompiler.a)
set_target_properties(OSDependent PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/ncnn-lib/${ANDROID_ABI}/libOSDependent.a)
set_target_properties(SPIRV PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/ncnn-lib/${ANDROID_ABI}/libSPIRV.a)
# openmp
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fopenmp")

if(DEFINED ANDROID_NDK_MAJOR AND ${ANDROID_NDK_MAJOR} GREATER 20)
    set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-openmp")
endif()

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fomit-frame-pointer -fstrict-aliasing -ffast-math")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fomit-frame-pointer -fstrict-aliasing -ffast-math")

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -fvisibility-inlines-hidden")

# disable rtti and exceptions
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -fno-exceptions")

add_library(ncnnyolov5 SHARED native-lib.cpp)

target_link_libraries(ncnnyolov5
        ncnn

        glslang SPIRV OGLCompiler OSDependent

        android
        z
        log
        jnigraphics
        vulkan
)

运行程序,点击SELECT选择待检测图片,然后点击DETECT-CPU得到如下结果(这里的GPU调用有点问题,有知道具体原因的兄弟,谢谢指出,报错是set_vulkan_compute failed, network use_vulkan_compute disabled):
在这里插入图片描述


4. 总结

相比于上一篇配置的博客,在安卓端部署更复杂。本文主要是参考了参考部分的仓库的代码,具体的细节还没有理解。部署期间出现了其他什么问题,欢迎评论区交流。


参考

  1. https://github.com/Tencent/ncnn.
  2. https://github.com/nihui/ncnn-android-yolov5(模型及代码下载).


评论 22
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值