

OpenCV Java入门六 使用神经网算法辩识人脸
source link: https://blog.csdn.net/lifetragedy/article/details/127133541
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

前面几章我们积累了足够的opencv使用技巧。这一章我们就会进入最激动人心的辩识人脸。我们知道识脸和辩识人脸有着本质的区别。
- 识脸:这是一个人的脸。
- 辩识人脸:这是谁的脸,这才是我们需要的。
我们还是使用在第五课:OpenCV Java入门五 结合摄像头识脸和拍照内的FaceRecognize这个类。
我们记得在第五课里,这个类是一个JFrame类,它长成这个样:

我们这次就要来完成【Train】和【Identify】这两个按钮内的动作了。
先说opencv辩识人脸的过程
- opencv通过摄像头把人脸流一个个读下来;
- 把读下来的人脸打人“这是谁”的标识;
- 然后把这是谁+这一堆人脸(越多越好,100多张照片差不多了)使用LBPHFaceRecognizer生成一个.yml的模型文件,这个就是训练模型;
- 辩识人脸时,使用LBPHFaceRecognizer读入之前的.yml训练模文件,然后通过摄像头实时读入的当前人脸使用faceRecognizer.predict(trainFace, predictedLabel, confidence);计算出:可信度;
- 在提取当前人脸的可信度和标签时,就算标签内有“姓名/标签”但是这个可信度即:confidence数值太大时我们就叫该人员和模型内的标签的人脸的可信度差距太大。差距越大、可信度越低、那么confidence数值就越大,那么越不可信。因此一般confidence取50,>50即不可信;
技术上要解决的重点
界面交互上需要注意的点
从代码上看其实一点不难,关键的是这次的应用在图形交互上很强,为了做出外面POS机、刷脸进门的实时效果,我们对于以下几个过程都需要做异步线程的分离设计。否则就会出现在显示人脸时你点了训练按钮,训练进程卡死了人脸在屏幕上的显示。或者是你在辩识这是谁时卡死了屏幕上的实时显示,那么这个用户体验会非常的不好。
因此我们对于训练、识别都做成了异步,把这些实现都套在了new Thread(){}.start()里这样去执行了。
训练模型的设计
我们准备了一个这样的文件夹
这个文件平就是和我们的训练模型相匹配的,我们可以看到在D:\opencv-demo\face\目录下是一个个以人名命名的文件平,然后把该人员的人脸全部存在这个带有人名标签的目录下。然后届时一调用opencv的生成训练模型API就可以完成训练和打标这样的层次结构了。

以下是一个标准的opencv生成的训练模型格式

读取:图片目录->标签->图片的工具类方法
我们用java.io.File来完成这件事,然后我们把存到一个下面这样的Java数据结构中。使得它成为一个List<FileBean> trainSamples。
然后我们再设计一个Map<String, List<Integer>> labelOfPerson = new HashMap<String, List<Integer>>();
在把图片从文件目录内读取成trainSamples后,在对这个trainSamples做populate(不好意思我这边不知道中文该如何表达这个动作,你可以认为是一边循环一边取值的这么一个意境)时把这个lable给打上,打完再通过faceRecognizer.train(images, labels)即完成了识练,然后你要输出这个训练模型那么只需要faceRecognizer.save(modelFolder + "\\face_model.yml")即可。

完整【Train】代码
这个按钮为on/off式设计,点一下开始训练点一下停止训练。为此我们设计了一个布尔值。我们就来看这个【Train]按钮的代码吧

运行起来效果如下


然后你自己觉得过了差不多有30秒左右了,再去点一下【Train】按钮,你会发觉在D:\opencv-demo\model下我们生成了face_model.yml这个训练模型了。
同时它会在D:\opencv-demo\face\mk下生成这么多的文件。

我们把辩识人脸也做了一个按钮【Identify】,这个按钮也是一个on/off的按钮,点一下开始识别,点一下停止识别。
识别时,如果是模型认识的人脸,它就会在绿色方框圈出来的人脸的左上角打上这个人的名字,否则即显示unknow代表不认识这个人。
辩识人脸只需要读摄像头,结合模型,然后作faceRecognizer.predict(trainFace, predictedLabel, confidence)即可。
唯一有一个小技巧就是,我们要把辩识出来的人脸打上“名字”,我们用了以下这个小函数:
下面为了让大家一次性感受到opencv在人脸辩识上的魅力,我把整个FaceRecognize.java一次给出

实际运行效果
我拿我的脸训练的模型来识别我自己的效果。

识别不认识的人的效果

对于人脸技术的商业应用扩展知识的传授
截止至此,OpenCV入门系列已经全部完成了。
一般对于一个商业级别的人脸系统如:刷脸支付,技术核心无外乎是这样,没有太大难度和创新。无非就是商业环境使用的人脸识别有几点是和我们的教程不一样的地方:
- 活检SDK,即商业环境正式应用的人脸识别的SK是可以“活检”的。意思是:如果你搞一张照片那么是骗不过活检人脸识别的,这就是为什么我们在使用随申码、支付宝、微信的人脸识别时需要上下、左右摇摇头、张张嘴的原因;
- 双目摄像头,有了活检SDK还需要有双目红外摄像头,我在家里用的就是双目红外摄像头,它不是普通的一般的摄像头,相对也会贵个几倍。因为只有这种双目红外摄像头才能配合活检识别算法;
- 场景上要求新客输入手机号的过程就在采集人脸了(train),一般一个新客注册,屏幕提示往往会要求客户输入11位手机号,这个输入的过程快则10秒,慢则30秒内。我们通过我的教程也看到了,人脸的“训练“过程其实很快的,只需要有>100张图,这个模型的准确率就接近95%,图片越多识别准确率越高。因此训练机器对于新客的人脸识别一般就是利用这个输入手机号的阶段来完成的;
- 模型文件的存储,在我们的例子中使用的是.yml文件,实际我们会把模型写成流式存储或者使用nosql存储在redis内,以完成快速读取和检索。把标签和模型的对应我们会也使用redis做键-label,value-模型数据来作存储;
- 个人信息法,国家对人脸识别是属于个人敏感信息,相关商业应用时一定要好好熟读网安法和个人信息法,并根据两部法的规定好好采取相应的保护人脸模型、数据等隐私数据的手段;
当你完成了以上五个步骤,那么这个例子就会变成一个真正的商业级应用了,抛开第5点技术上实现一点不难,双目红外摄像头一般有点小贵,400-600CNY左右。因此不妨自己动一下手试试吧。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK