一行代码Android上实现人脸检测、关键点检测、口罩检测

原文博客:Doi技术团队
链接地址:https://blog.doiduoyi.com/authors/1584446358138
初心:记录优秀的Doi技术团队学习经历
本文链接:一行代码Android上实现人脸检测、关键点检测、口罩检测

一行代码实现人脸检测,人脸关键点检测和戴口罩检测。

Face[] result = FaceDetectionUtil.getInstance(MainActivity.this).predictImage(bitmap);

本项目是使用Paddle Lite 的C++实现的人脸检测,人脸关键点检测和戴口罩检测,并将编译好的动态库和静态库部署在Android应用上,在Android设备上实现人脸检测,人脸关键点检测和戴口罩检测,所以本应不会使用到C++开发,可以只使用笔者提供的JNI接口实现这些功能。在ai这个module是笔者在开发时使用到的,读者在使用这个项目时,完全可以删除掉,如果是看C++实现,也可以看这个module的源码。

源码地址:https://github.com/yeyupiaoling/FaceKeyPointsMask

Android开发

assets目录是存放各个模型的文件,pyramidbox.nb模式是人脸检测,首先第一步是需要检查人脸才能进行下一步的识别。facekeypoints.nb这个是人脸关键点检测,检测到人脸之后,通过这个模型检测人脸关键点。maskclassifier.nb这个模型是口罩分类模型,检测到人脸之后,用这个识别是否戴口罩。第一步笔者再训练一个性别分类和年龄模型,这样一个程序就可以同时实现人脸检测,人脸关键点检测、戴口罩检测和性别年龄识别等5个功能。

jniLibs是存放编译的C++代码和Paddle Lite的动态库,这文件虽然大,但是打包成apk之后项目会非常小。

com.yeyupiaoling.ai是存放识别功能的代码,这个包文件不能修改,因为里面包含了JNI接口,跟C++代码保持一致。PaddleNative.java就是识别的JNI接口。Face.java是C++返回结果的结构体,通过这个java bean 解析识别结果。FaceDetectionUtil.java为识别工具类。Utils.java为其他通用的工具方法。

使用识别

有了以上的工具类,识别就变得很容易了,就只需要以下的一行代码即可实现识别,该方法不仅支持Bitmap格式,还可以直接使用图片的路径进行预测。

Face[] result = FaceDetectionUtil.getInstance(MainActivity.this).predictImage(bitmap);

识别的结果如果我想把识别结果显示可以使用以下一行代码,因为预测时使用的图片大小有等比例缩小,不能直接使用原来的Bitmap进行画识别信息,需要使用getBitmap()获取缩小的图片才能正确画预测结果。

Bitmap b = Utils.drawBitmap(FaceDetectionUtil.getInstance(MainActivity.this).getBitmap(), result);

这样在Android上实现人脸检测、关键点检测、口罩检测就大功告成了。

效果图:
在这里插入图片描述

已标记关键词 清除标记
# 问题详述 在写AS的数据绑定练习项目时,写好的app在虚拟机上运行出现了keeps stopping的闪退现象。检查代码后发现由AS自动生成的ActivityMainBindingImpl类出现了红色下划线提示。报错信息为Cannot inherit from final "..." ![图片说明](https://img-ask.csdn.net/upload/202004/01/1585752378_306723.png) # 相关代码信息 Databinding的构建代码为 ``` public class MainActivity extends AppCompatActivity { MyViewModel myViewModel; ActivityMainBinding binding; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = DataBindingUtil.setContentView(this, R.layout.activity_main); myViewModel = ViewModelProviders.of(this).get(MyViewModel.class); binding.setData(myViewModel); binding.setLifecycleOwner(this); } } ``` 其中_MyViewModel_ 是由_ViewModel_ 派生出的一个子类,在_activity\_main.xml_ 布局文件中已经设置为DataBinding Layout,并设置了一个变量data ``` <data> <variable name="data" type="com.example.ex1scoring.MyViewModel" /> </data> ``` # 已经进行的尝试 1.检查确认了类名没有出错,页面布局文件名为_activity\_main.xml _。 2.检查了生成的父类ActivityMainBinding的代码,虽然类的成员属性都有final修饰,但没有发现类前有final的修饰(以下为ActivityMainBinding类的首行) ``` public abstract class ActivityMainBinding extends ViewDataBinding {//todo} ``` # 推测可能的原因 在将myViewModel绑定到布局页面上的时候使用了 ``` myViewModel = ViewModelProviders.of(this).get(MyViewModel.class); ``` 但是AS3.6.1似乎已经不推荐这种用法了。在代码提示中有划去的横线。不知道是不是因为这个问题。翻看官方文档后推荐直接使用ViewModelProvider来进行构造。但是没有具体的实例,作为新手我没能明白具体应该怎么实现。 希望大家能给予一些帮助。谢谢各位大佬!
©️2020 CSDN 皮肤主题: 创作都市 设计师:CSDN官方博客 返回首页