概述
人脸检测是指从一副图片或者一帧视频中检测是否存在人脸。通过该技术手段可以判定有没有人脸出现在给定的图片中。注意它和人脸识别是有差异的,人脸检测解决的是照片中有没有人脸的问题,而人脸识别解决的是照片中的人脸是谁的问题。Android SDK 提供了人脸检测的接口,本篇博文介绍基于 Android SDK 实现人脸检测的方法。
Android SDK 中的 FaceDetector 介绍
Android SDK 中支持人脸检测,它提供了一个直接在位图上进行人脸检测的方法,这个 API 是android.media.FaceDetector,源文件路径是:
frameworks/base/media/java/android/media/FaceDetector.java
调用 findFaces 方法就可进行人脸检测,该方法返回检测到的人脸总数,并且会将每个”人脸”的信息保存在FaceDetector.Face 的数组中。每个 Face 都包含下面几点信息:
- 该 Face 为人脸的可信度.取值范围是 0~1,大于 0.3 则表明可信度较高。
- 双眼之间的距离
- 双眼中点的 x,y 坐标
- 脸部的欧拉角度,可用于判断抬头,侧脸的角度等。
识别流程是这样的:
1. 读取一张图片至 Bitmap,且该 Bitmap 必须是 565 格式。
2. 调用 findFaces 方法分析 Bitmap(注意待分析的 Bitmap 宽度必须是偶数),将探测到的人脸数据存储在一个FaceDetector.Face 数组中,并返回检测到的人脸总数。
人脸检测核心代码
- 读取一张图片至 Bitmap,且该 Bitmap 必须是 565 格式。
private Bitmap getBitmap(int resid) {
BitmapFactory.Options bitmapOption = new BitmapFactory.Options();
bitmapOption.inPreferredConfig = Bitmap.Config.RGB_565;
Bitmap myBitmap = BitmapFactory.decodeResource(getResources(), resid,
bitmapOption);
return myBitmap;
}
- 调用 findFaces 方法分析 Bitmap
private int findFace(Bitmap bitmap){
//保证 bitmap 的宽度为偶数
if ((1 == (myBitmap.getWidth() % 2))) {
myBitmap = Bitmap.createScaledBitmap(myBitmap,
myBitmap.getWidth() + 1, myBitmap.getHeight(), false);
}
//设置最多检测多少个 Face
int maxFace = 2;
FaceDetector mFaceDetector = new FaceDetector(bitmap.getWidth(),
bitmap.getHeight(), maxFace);
FaceDetector.Face[] mFace = new FaceDetector.Face[maxFace];
// 实际检测到的脸数
int faceCount = mFaceDetector.findFaces(bitmap, mFace);
return faceCount;
}
FaceDetector性能
检测时间平均耗费2s 左右,下图是debug FaceDetector的时间戳信息。
FaceDetector 的不足
在人物面部显示不全,比如侧脸,或者部分衣帽遮挡脸部时,会导致检测结果不正确。比如下面这个美女侧脸图通过FaceDetector就没能检测出来。