在上一篇博客目标检测——TensorFlow口罩人脸目标检测中已经介绍了使用TensorFlow Objecti Detection API来进行口罩人脸目标检测,本文将在此基础上将使用TensorFlow Lite将模型迁移到安卓端,在安卓手机上进行目标检测。
模型转换
在data下新建tflite文件夹用来存放转换后的文件,然后在models/research/object_detection中执行(根据自己情况修改,可改成绝对路径):
python export_tflite_ssd_graph.py \--pipeline_config_path=./models/dataset/data/savemodel/pipeline.config \--trained_checkpoint_prefix=./models/dataset/data/model.ckpt-10000 \--output_directory=./models/dataset/data/tflite \--add_postprocessing_op=true
运行成功后tflite文件夹中将生成tflite_graph.pb 和tflite_graph.pbtxt两个文件文件(如下图):
Bazel安装和编译转换工具
各系统安装Bazel方法可以参考官网
本人使用的是Ubuntu18.04版本,安装方法如下:
步骤1:将Bazel发行版URI添加为包源
sudo apt install curl
curl https://bazel.build/bazel-release.pub.gpg | sudo apt-key add -
echo "deb [arch=amd64] https://storage.googleapis.com/bazel-apt stable jdk1.8" | sudo tee /etc/apt/sources.list.d/bazel.list
步骤2:安装和更新Bazel
sudo apt update && sudo apt install bazel
sudo apt update && sudo apt full-upgrade
步骤3:安装JDK(可选)
Ubuntu 18.04 (LTS) 默认使用OpenJDK 11:
sudo apt install openjdk-11-jdk
下载源码:
git clone https://github.com/tensorflow/tensorflow.git
根据自己实际路径:
cd tensorflow
bazel build tensorflow/python/tools:freeze_graph
bazel build tensorflow/contrib/lite/toco:toco
编译错误
这个编译太多坑了TAT,经历各种BUG才成功,下面列出编译的时候遇到的一些错误:
第一个是在bazel build tensorflow/python/tools:freeze_graph的时候,刚开始正常运行,然后突然就断了,具体的报错没记住,反正编译之前最好先增加swap区域内存。
解决方法:内存不足,增加swap区域内存。
sudo dd if=/dev/zero of=/root/swapfile bs=1M count=15360 # 15G
sudo mkswap /root/swapfile
sudo swapon /root/swapfile
可以通过free查看我们的设置
free -h
执行完后从2G变成了16G:
每次编译出现错误后,执行一下下面的命令再重新编译:
bazel clean --expunge
编译 bazel build tensorflow/contrib/lite/toco:toco时的错误:
no such package ‘tensorflow/contrib/lite/toco’:…
解决方法:改成 bazel build tensorflow/lite/toco:toco
(原因:The toco target has been moved from //tensorflow/contrib/lite/toco to //tensorflow/lite/toco)
编译成功:
其中还有各种各样的坑没列出,一定要坚持住!!!
编译完成后,用bazel生成tflite文件(根据自己实际情况修改路径和生成的模型名称):
bazel run tensorflow/lite/toco:toco -- \
--input_file=./models/dataset/data/tflite/tflite_graph.pb \
--output_file=./models/dataset/data/tflite/maskdetect.tflite \
--input_shapes=1,300,300,3 \
--input_arrays=normalized_input_image_tensor \
--output_arrays='TFLite_Detection_PostProcess','TFLite_Detection_PostProcess:1','TFLite_Detection_PostProcess:2','TFLite_Detection_PostProcess:3' \
--inference_type=FLOAT \
--allow_custom_ops
最终得到了tflite模型 TAT!!!
模型迁移
下载源码:
git clon https://github.com/tensorflow/examples.git
在Android Studio中打开/home/well/AndroidStudioProjects/examples/lite/examples/object_detection/android 项目,其他安装配置啥的就不多介绍了(累)。
把上面的tflite模型放到/examples/lite/examples/object_detection/android/app/src/main/assets文件夹中,然后在assets文件夹中新建masklabelmap.txt,写上自己的类别名,格式如下,不要手贱删除第一行的三个?。
修改DetectorActivity.java中54~56行。
将build.gradle(Module:app)中的apply from:'download_model.gradle’注释掉。
最后连上手机,在Android Studio运行项目就大功告成!!!!
隐私问题就不用真人检测的图了,以下是对着电脑图片的检测。
运行安卓项目报错:E/AndroidRuntime: FATAL EXCEPTION: inference
Process: org.tensorflow.lite.examples.detection, PID: 17660
java.lang.IllegalArgumentException: Cannot convert between a TensorFlowLite buffer with 1080000 bytes and a Java Buffer with 270000 bytes.
解决方法:将DetectorActivity.java的54行改成TF_OD_API_IS_QUANTIZED = false
至此整个项目就完成了,有任何问题欢迎流言。