[Android|深度学习移植]--基于ncnn的RK3399上的mtcnn人脸检测的实现

参考文章:

1.在Android手机上使用腾讯的ncnn实现图像分类: https://blog.csdn.net/qq_33200967/article/details/82421089
2. Ubuntu 16.04安装NVIDIA驱动:https://blog.csdn.net/u014797226/article/details/79626693
3.Ubuntu16.04 Caffe 安装步骤记录(超详尽): https://blog.csdn.net/yhaolpz/article/details/71375762
4.NanoPC-T4 / ZH友善之臂:http://wiki.friendlyarm.com/wiki/index.php/NanoPC-T4/zh#.E4.B8.B2.E5.8F.A3.E8.B0.83.E8.AF.95
5迄今最全人脸识别开源: http://itindex.net/detail/58933-人脸识别-开源-qq
6.https://github.com/moli232777144/mtcnn_ncnn

1.在RK3399上烧录安卓系统(Android 7.1.2)

  • 烧写步骤及下载工具:
    http://wiki.friendlyarm.com/wiki/index.php/NanoPC-T4/zh#.E4.B8.B2.E5.8F.A3.E8.B0.83.E8.AF.95

博主使用SD卡脱机烧写:
访问此处的下载地址下载SD卡脱机烧写所需的文件及工具:
[Android|深度学习移植]--基于ncnn的RK3399上的mtcnn人脸检测的实现_第1张图片
详细操作步骤如下:

  • 准备一张8G或以上容量的SDHC卡;

  • 下载并解压固件文件rk3399-eflasher-OSNAME-YYYYMMDD.img.zip和工具win32diskimager;(osname是你要烧录的系统镜像名称)

  • 在Windows下以管理员身份运行win32diskimager,在界面上选择你的SD卡盘符,选择- 解压后的EFlasher固件,点击写按钮烧写到SD卡; 或者在Linux下使用dd命令将rk3399-eflasher-OSNAME -YYYYMMDD.img写入SD卡;

  • 将SD卡从电脑端弹出,插入NanoPC-T4的的microSD卡槽;

  • 长按NanoPC-T4上的Power键直到板上的PWR灯亮,系统会从SD卡启动,并自动启动EFlasher烧写工具,你有多种途径可以操作EFlasher:

方法1:连接LCD或HDMI显示屏,在图形界面上操作EFlasher,如果屏幕不支持触摸,则需要使用USB鼠标来操作; (博主采用这个方法)

方法2:将开发板通过网线接入局域网,通过ssh登录开发板,然后输入命令eflasher,根据命令行的提示进行操作;(注:ssh登录的用户是root,密码为fa,开发板IP可查看路由器后台获得)

方法3:通过调试串口登录到串口终端,在终端上输入命令eflasher来操作;

方法4:连接一个lcd2usb配件到NanoPC-T4上,按配件上面的K1键可以选择要烧写的系统,然后按K2键确定烧写,烧写进度会在lcd2usb上显示;

烧写完成后,轻按电源键关机,从NanoPC-T4端弹出SD卡;(不拔出会进不了烧好的系统

长按电源开机,会从eMMC的启动你刚刚烧写的系统;
[Android|深度学习移植]--基于ncnn的RK3399上的mtcnn人脸检测的实现_第2张图片

2. 搭建开发环境

2.1英伟达官网下载驱动程序(http://www.nvidia.cn/Download/index.aspx?lang=cn)

[Android|深度学习移植]--基于ncnn的RK3399上的mtcnn人脸检测的实现_第3张图片

2.1.1禁用nouveau第三方驱动

打开编辑配置文件: sudo gedit /etc/modprobe.d/blacklist.conf

在最后一行添加:blacklist nouveau

改好后执行命令:sudo update-initramfs -u

重启使之生效:reboot

2.1.2安装驱动

重启后按Ctrl+Alt+F1 进入命令行界面

 执行命令:lsmod | grep nouveau

禁用X服务:sudo /etc/init.d/lightdm stop (或者:sudo service lightdm stop)

给驱动run文件赋予可执行权限:sudo chmod a+x NVIDIA-Linux-x86_64-390.25.run     (下载的驱动文件名)

安装:sudo ./NVIDIA-Linux-x86_64-390.25.run -no-opengl-files

开启X服务:sudo /etc/init.d/lightdm start (或者:sudo service lightdm start)

–no-opengl-files 只安装驱动文件,不安装OpenGL文件。这个参数最重要
–no-x-check 安装驱动时不检查X服务
–no-nouveau-check 安装驱动时不检查nouveau 
后面两个参数可不加。

重启,没有问题,输入命令:nvidia-smi

如果出现了驱动版本就表示安装成功了。

2.2cuda安装

参考:https://blog.csdn.net/yhaolpz/article/details/71375762
这篇文章写的非常详细,但是因为个人环境不同,还是出现了很多大小不同的错误,如果遇到了错误可以继续遇到此文

  1. 如果按照这篇文章遇到了安装cuda的问题可以参考我的做法:
    - 这篇文章到了第五步请注意:我之前上一步已经装了驱动,所以第五步这里选择 n
    - 此处是因为直接安装cuda的时候总是失败,所以选择分开安装驱动cuda**(cuda本身是含有驱动的)**

[Android|深度学习移植]--基于ncnn的RK3399上的mtcnn人脸检测的实现_第4张图片

2.3cudnn安装

2.4安装 opencv3.1

2.5编译caffe##安装 pycaffe notebook 接口环境

如果出错 确保安装好需要的工具cmake、编译caffe的工具(参考caffe github的安装教程)

  • 以及对应报错所缺少的文件,一般是环境变量,文件没有复制好等问题,自行谷歌一般能解决这些疑难杂症,博主在参考上面的文章也遇到了很多错误,但是没有及时记下来…
  • 比如python,上一步的链接库复制等
  • 安装pycaffe导入的时候需要注意编码问题
  • 安装或新建文件时需要使用sudo命令等(很多是没有权限)

3.NCNN编译及模型转换

参考:https://blog.csdn.net/qq_33200967/article/details/82421089

使用Ubuntu编译ncnn库

3.1首先要下载和解压NDK。

wget https://dl.google.com/android/repository/android-ndk-r17b-linux-x86_64.zip
unzip android-ndk-r17b-linux-x86_64.zip

3.2设置NDK环境变量,目录是NDK的解压目录。

export ANDROID_NDK="/home/test/paddlepaddle/android-ndk-r17b"

设置好之后,可以使用以下的命令查看配置情况。

root@test:/home/test/paddlepaddle# echo $NDK_ROOT
/home/test/paddlepaddle/android-ndk-r17b

3.3 安装cmake,需要安装较高版本的,笔者的cmake版本是3.11.2。

下载cmake源码

     wget https://cmake.org/files/v3.11/cmake-3.11.2.tar.gz

解压cmake源码

tar -zxvf cmake-3.11.2.tar.gz

进入到cmake源码根目录,并执行bootstrap。

cd cmake-3.11.2
./bootstrap

最后执行以下两条命令开始安装cmake。

make
make install

安装完成之后,可以使用cmake --version是否安装成功。

root@test:/home/test/paddlepaddle# cmake --version
cmake version 3.11.2

CMake suite maintained and supported by Kitware (kitware.com/cmake).

3.4克隆ncnn源码。

git clone https://github.com/Tencent/ncnn.git

3.5编译源码。

进入到ncnn源码根目录下

   cd ncnn

创建一个新的文件夹
    mkdir -p build-android-armv7

进入到该文件夹中

    cd build-android-armv7

执行编译命令

cmake -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \
    -DANDROID_ABI="armeabi-v7a" -DANDROID_ARM_NEON=ON \
    -DANDROID_PLATFORM=android-14 ..

这里使用4个行程并行编译

make -j4
make install

3.6编译完成,会在build-android-armv7目录下生成一个install目录,我们编译得到的文件都在该文件夹下:

include 调用ncnn所需的头文件,该文件夹会存放在Android项目的src/main/cpp目录下;
lib 编译得到的ncnn库libncnn.a,之后会存放在Android项目的src/main/jniLibs/armeabi-v7a/libncnn.a

转换预测模型

3.6.1. 克隆Caffe源码。
git clone https://github.com/BVLC/caffe.git
3.6.2. 编译Caffe源码。

之前安装caffe时已经编译好

3.6.3. 升级Caffe模型。

把需要转换的模型复制到caffe/tools,并切入到该目录

cd tools

升级Caffe模型
./upgrade_net_proto_text mobilenet_v2_deploy.prototxt mobilenet_v2_deploy_new.prototxt

./upgrade_net_proto_binary mobilenet_v2.caffemodel mobilenet_v2_new.caffemodel
3.6.4.检查模型配置文件,因为只能一张一张图片预测,所以输入要设置为dim: 1。
name: "MOBILENET_V2"
layer {
  name: "input"
  type: "Input"
  top: "data"
  input_param {
    shape {
      dim: 1
      dim: 3
      dim: 224
      dim: 224
    }
  }
}
3.6.5. 切换到ncnn的根目录,就是我们上一部分克隆的ncnn源码。
cd ncnn/
3.6.6. 在根目录下编译ncnn源码。
    mkdir -p build
    cd build
    cmake ..
    make -j4
    make install

3.7. 把新的Caffe模型转换成NCNN模型。

经过上一步,会生产一个tools,我们进入到以下目录

cd tools/caffe/

把已经升级的网络定义文件和权重文件复制到当目录,并执行以下命令

./caffe2ncnn mobilenet_v2_deploy_new.prototxt mobilenet_v2_new.caffemodel mobilenet_v2.param mobilenet_v2.bin

3.8. 对象模型参数进行加密,这样就算别人反编译我们的apk也用不了我们的模型文件。把上一步获得的mobilenet_v2.param、mobilenet_v2.bin复制到该目录的上一个目录,也就是tools目录。

切换到上一个目录

cd ../

执行命令之后会生成mobilenet_v2.param、mobilenet_v2.id.h、mobilenet_v2.mem.h

./ncnn2mem mobilenet_v2.param mobilenet_v2.bin mobilenet_v2.id.h mobilenet_v2.mem.h

经过上面的步骤,得到的文件中,以下文件时需要的:

mobilenet_v2.param.bin 网络的模型参数;
mobilenet_v2.bin 网络的权重;
mobilenet_v2.id.h 在预测图片的时候使用到。

4.开发Android项目

我们在Android Studio上创建一个NCNN1的项目,别忘了选择C++支持
(Android Studio3.0之后的新建项目时下滑可以找到c++支持的模板)
[Android|深度学习移植]--基于ncnn的RK3399上的mtcnn人脸检测的实现_第5张图片
其他的可以直接默认就可以了,在这里要注意选择C++11支持。(选其他的会出错)
[Android|深度学习移植]--基于ncnn的RK3399上的mtcnn人脸检测的实现_第6张图片
之后的项目搭建的步骤请参考
https://blog.csdn.net/qq_33200967/article/details/82421089

下图是mtcnn_As的项目结构
github源码地址:https://github.com/moli232777144/mtcnn_ncnn

[Android|深度学习移植]--基于ncnn的RK3399上的mtcnn人脸检测的实现_第7张图片
编译不通过的解决办法
[Android|深度学习移植]--基于ncnn的RK3399上的mtcnn人脸检测的实现_第8张图片

  • ndk版本<=16.(下载ndk16版本,修改ndk路径)
    NDK旧版本下载地址: https://developer.android.com/ndk/downloads/older_releases.html?hl=zh-cn
  • 按照Android Studio移除报错地方,一直点点do refactor,警告也可以通过修改成最新的语法解决
    比如build.gradle(该项目的build.gradle)里的 ‘compile’—>‘implementation’
  • build.gradle(全局)里添加 google()
  • 确保需要的sdk版本已经下载

虽然成功安装运行,但是没有检测到人脸,初步猜测是动态申请读取外部存储问题
[Android|深度学习移植]--基于ncnn的RK3399上的mtcnn人脸检测的实现_第9张图片

[Android|深度学习移植]--基于ncnn的RK3399上的mtcnn人脸检测的实现_第10张图片
2019.5.23 15点23分更新:后来我又检测成功了。。。。
对安卓深度学习移植感应趣的同学请移步我的另外一篇文章:https://blog.csdn.net/liaopiankun0618/article/details/90481231

你可能感兴趣的:(程序开发,深度学习,Android,图像处理)