【手把手AI项目】八、MobileNetSSD通过Ncnn前向推理框架在Android端的使用--Cmake编译(目标检测 objection detection)手机硬件测试「【手把手AI项目】八、MobileNetSSD通过Ncnn前向推理框架在Android端的使用--Cmake编译(目标检测 objection detection)」
- 安装win10+linux-Ubuntu16.04的双系统(超细致)
- ubuntu16.04+caffe+CUDA10.0+cudnn7.4+opencv2.4.9.1+python2.7 (超超细致)
- Caffe_ssd安装以及利用VOC2012,VOC2007数据集测试VGG_SSD网络
- Caffe实现MobileNetSSD以及各个文件的具体解释,利用自己的数据集dataset训练MobileNetSSD建立模型
推荐看这篇之前把下面这篇先看一下,因为这篇中一些运用的前提在下面PC篇,如转换模型。
- MobileNetSSD通过Ncnn前向推理框架在PC端的使用(目标检测 objection detection)
因为我本来本科大二的时候玩过android, 所以接触这个项目移植这部分我主要负责,早想把自己弄得清晰思路分享大家了。
1.下载AS安装包
进入下面这个网站,找到Android Studio板块之后点进去,自动就会显示你当前系统版本和配置的下载包,下载即可,傻瓜操作,不赘述了
https://developer.android.google.cn
2.解压
解压到/usr/local文件中
3.打开使用
/usr/local/android-studio/bin/中有个studio.sh 启动即可 之后点安卓图标右键锁定到启动器,以后直接点击桌面左面图标即可
第一次打开会有一些配置选项,问题不大,最主要是会有一个自动的android sdk的安装最好网络好一些,要不会很卡(自动下载还是很方便的,像以前我用eclipse开发android的时候,还需要自己配置sdk,很麻烦)下载之后也会发现自己的home里多了一个Android文件夹
下载完成,你可以随便开始一个project。
这边移植的话主要按下面步骤来
NDKbuild 当时做项目的时候研究了几天发现代码没错,就是编译不成功,又挺了几天果断换成Cmake进行编译
1.下载需要的包
首先新建一个空的工程
这里是demo,之后一直next即可
点击File->Settings->Appearance&Behavior->System Settings->Android SDK下载一些必要的包如图所示
如果要是之前自动下载了NDK那目前的步骤只需要下载LLDB,NDK,CMAKE,因为其他的都自动下载完了。
2.添加环境变量
这里不多讲了我之前的博客也有说过或者百度bashrc 和vim使用即可
进行buld ncnn(android)
一般都会出现错误,这里需要把cmake升级下(要求3.6.0及以上)
首先在http://www.cmake.org/files找到自己想下的版本,我在这里下载3.6.2
安装完可以用以下命令查看Cmake版本
搞定
重新进行进行buld ncnn(android)那步骤
依然可能出现问题
CMake Error at examples/CMakeLists.txt:4 (find_package):
By not providing “FindOpenCV.cmake” in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by “OpenCV”, but
CMake did not find one.
Could not find a package configuration file provided by “OpenCV” with any
of the following names:
Add the installation prefix of “OpenCV” to CMAKE_PREFIX_PATH or set
“OpenCV_DIR” to a directory containing one of the above files. If “OpenCV”
provides a separate development package or SDK, be sure it has been
installed.
解决方案把ncnn/CMakeLists.txt里的
add_subdirectory(examples)注释掉,本来默认就是注释的,但是看过我的第一篇ncnn文章 MobileNetSSD通过Ncnn前向推理框架在PC端的使用(目标检测 objection detection)的朋友可能这里修改了一下,需要改回来。
最后make install成功后
会在ncnn/build-android下产生一个install文件夹里面有两个文件
- include文件夹 里面包含各种常用的.h文件
- lib/libncnn.a文件 以我理解这个文件就是相当于把ncnn打包成android可导入的形式
命名为MobileNetSSD_demo
file/new/newproject
因为这里我们采用cmake编译.so文件的方法,所以相当于用java接口去调用c++,使用NDK技术,所以这边需要选择include c++ support之后next 选择Phone和Tablet之后选择空project之后next 到了下面这个界面需要选择c++11
finish
发现文件里多个cpp文件,下面也多了一个CMakeLists.txt
生成转换文件请看 MobileNetSSD通过Ncnn前向推理框架在PC端的使用(目标检测 objection detection)
- 在main目录下创建assets目录,将MobileNetSSD_deploy.param.bin (转换后网络模型参数)MobileNetSSD_deploy.bin (转换后的网络权重)到文件中去,自己创建一个words.txt也到其中
words.txt内容(如果是自己的dataset就按照自己的label创建即可)如下:
- 上述build-android得到的install文件中的include文件夹以及ncnn加密得到的编译
把mobilenet_v2.id.h到cpp目录下。(一会主要c++文件也放在其中这个一会讲到) - 在main目录下创建jniLibs/armeabi-v7a/目录,并把上述build-android得到的install文件中lib下的libncnn.a文件到该目录。(jniLibs下的这个文件夹名称和上面build-andorid时考虑的兼容硬件架构一致,如果这边使用RK3399则为v8)
- 还有一点你会发现新建的android工程中有cpp下native-lib.cpp文件里面是NDK代码的一个demo,你会在MainActivity中发现这个cpp的java接口代码,我当时研究NDK的时候也是根据这个demo自己去琢磨的,你也可以多看看如果没有学过NDK的话,这边就不赘述了直接删掉 最后的文件部署如下图所示
下面代码自己仿照ncnn的examples里的squeezencnn的安卓项目工程里面的代码所修改,这个项目工程是利用NDK-build不是我所讲的Cmake方式
1.MobileNetssd.cpp(创建或者直接从example里更改)
具体代码如下(有详细注释)
将.cpp文件放到cpp文件夹下
2.AndroidManifest.xml添加权限
3.CMakeLists.txt修改
4.build.gradle修改
5.自己编写java接口
命名为和.cpp文件一样的名称
这里就是MobileNetssd.java
- public native boolean Init(byte[] param, byte[] bin); // 初始化函数 对应于NDK编写的.cpp文件中的JNIEXPORT jboolean JNICALL
Java_com_example_che_mobilenetssd_demo_MobileNetssd_Init(JNIEnv *env, jobject obj, jbyteArray param, jbyteArray bin) - public native float[] Detect(Bitmap bitmap); // 检测函数 对应于NDK编写的.cpp文件中的JNIEXPORT jfloatArray JNICALL Java_com_example_che_mobilenetssd_demo_MobileNetssd_Detect(JNIEnv* env, jobject thiz, jobject bitmap)
其实有规律可寻以第二个为例子
函数前三个都是JNIEXPORT +函数返回类型(NDK形式)+JNICALL
Java_com_example_che_mobilenetssd_demo_MobileNetssd_Detect(JNIEnv* env, jobject thiz, jobject bitmap)
对于这个命名先看下面这个图你可能就懂了
相当于绝对路径那种感觉了显示java文件夹,再是com.example.che.mobilenetssd_demo这个包再是MobileNetssd.java文件最后是 java接口文件中的public native float[] Detect(Bitmap bitmap); 函数的文件名,即Java_com_example_che_mobilenetssd_demo_MobileNetssd_Detect,后面参数则为
(JNIEnv* env, jobject thiz,+原函数的函数参数(NDK类型格式))
其实正常来讲NDK这种不应该是先写cpp再写java接口而是应该先写java接口再利用IDE本身带有的NDK的开发环境可以直接双点写的java接口的函数(函数格式如上需要加一个native)之后快捷键按ALT+ENTER即可直接在cpp文件中添加成功,具体请看NDK技术即可,这里不赘余了。
接下来就是我的其他.java文件以及UI的XML文件了
6.activity_main.xml(res/layout/activity_main.xml)
7.MainActivity.java修改成如下
8.PhotoUtil.java(照片工具类)
全部完毕
1.build
点击Build,之后点击Make Project,等一会,不出意外应该是成功了
查看自己的这个文件夹的对应的编译硬件架构的文件夹下成功生成.so文件,名字为libMobileNetssd.so
2.真机测试
我喜欢用真机测试,插上真机打开开发者模式等等,可百度一下,很多,不赘述了
先导入一些测试图片,之后run 就好了,这个地方太基本不想多说了,没说过android的朋友稍微探索一下怎么成功导入app即可,这过程中可能因为手机版本等更换SDK版本等等问题,常见的就是修改sdk版本即可,在导入的过程中需要一些手机真机的钥匙等确认。
安装完毕打开app有几个权限需要手机确认以下即可,真机照片(这里会出现一个无法编译成功的错误,看总结里写到解决方式,主要和NDK命名规则有关)
前面提到一个 线程的问题,这里可以自行更改到速度最快即可,一般为4最快,这个也和你输入的图片
这边的代码目前只支持单目标检测,现在一张图片中有多个目标则无法成功检测出最后的框图版本,下一篇博客把这个实现写上准备,这里还有一点就是.cpp文件中的NDK函数的名称需要修改才能最后app装在手机上成功,我项目的android名称为一连串的,而这回起名为MobileNetSSD_demo形式(感觉自己也是没事找事= =),中多个下划线,这里直接关系到NDK的函数命名格式
在mobilenetssd_后多个1再加上demo才能关联成功,java接口的这个函数直接go to Declaration就可以直接关联到.cpp中这个函数了,Detect函数以此列推,如果你自己再走一遍流程起名是一连串的(比如MobileNetssddemo)就不会出现这样的问题了,但是这个问题不会影响之前的所有讲解,没有问题,改完之后需要clean project 之后重新make project 即可成功 成功结果如上图所示
已在我的github上,希望大家给个star follow.因为准备和下一篇博文多检测的分开重命名为single
https://github.com/chehongshu/ncnnforandroid_objectiondetection_Mobilenetssd/tree/master/MobileNetSSD_demo_single
PS: 如果觉得本篇本章对您有所帮助,欢迎关注、评论、点赞!Github给个Star就更完美了_!
如果想打包成android APK请参照我另一篇博文
Android studio打包APK Android Studio
https://blog.csdn.net/freezingxu/article/details/73917933
https://blog.csdn.net/qq_36982160/article/details/79931741
https://blog.csdn.net/qq_33200967/article/details/82421089#_85
安宁版权声明:本网信息来自于互联网,目的在于传递更多信息,并不代表本网赞同其观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,并请自行核实相关内容。本站不承担此类作品侵权行为的直接责任及连带责任。如若本网有任何内容侵犯您的权益,请及时联系我们,本站将会在24小时内处理完毕,E-mail:xinmeigg88@163.com