在这篇文章中,我想描述一下如何使用Android检测图像中的人脸。 我将使用相机获取图片,然后该应用将在图像中检测到的面部周围绘制一些矩形。 为此,我们只需使用Android API,例如:
- FaceDetector用于检测位图中的人脸
- 包含有关检测到的 面部 信息的 面部 对象
因此,我们必须在应用程序中执行三个步骤:
- 拍照
- 检测图片中的人脸
- 围绕检测到的脸部绘制矩形
使用Android用相机拍照
这一步非常简单,因为我们只需要调用一个意图并准备好接收结果即可。 目的很简单:
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_RETURN_CODE);
要检索结果(拍摄的照片),我们必须在活动中覆盖一个方法:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAMERA_RETURN_CODE) {
Bitmap cameraBmp = (Bitmap) data.getExtras().get("data");
}
}
在第4行,我们使用带有数据键的extra来检索图片。
检测图片中的人脸
在这一点上,我们使用从级别1开始的Android SDK附带的API。为实现我们的逻辑,我们创建了一个自定义组件,该组件可扩展
ImageView ,我们称之为FaceImageView 。
public class FaceImageView extends ImageView {
...
}
为了检测人脸,我们首先将图像转换为556格式的位图,否则我们将无法使用API中所述的图像,因此我们需要:
Bitmap tmpBmp = image.copy(Config.RGB_565, true);
现在我们有了正确格式的图像,我们创建了FaceDetector的实例:
FaceDetector faceDet = new FaceDetector(tmpBmp.getWidth(), tmpBmp.getHeight(), MAX_FACES);
传递图像宽度和图像高度以及我们要检测的脸部数量(在我们的情况下,它是简单常数)。 现在,我们调用findFaces方法来检测人脸,结果,我们期望一个Face实例数组,该数组的长度必须等于我们要检测的人脸数量:
faceDet.findFaces(tmpBmp, faceList);
其中faceList是我们的数组。
现在,我们必须分析数组中的每个项目并获得结果。 我们只是想获得人脸的中点和眼睛的距离 。 我们使用这两个信息为检测到的每个面Kong绘制矩形:
for (int i=0; i < faceList.length; i++) {
Face face = faceList[i];
Log.d("FaceDet", "Face ["+face+"]");
if (face != null) {
Log.d("FaceDet", "Face ["+i+"] - Confidence ["+face.confidence()+"]");
PointF pf = new PointF();
face.getMidPoint(pf);
Log.d("FaceDet", "\t Eyes distance ["+face.eyesDistance()+"] - Face midpoint ["+pf+"]");
RectF r = new RectF();
r.left = pf.x - face.eyesDistance() / 2;
r.right = pf.x + face.eyesDistance() / 2;
r.top = pf.y - face.eyesDistance() / 2;
r.bottom = pf.y + face.eyesDistance() / 2;
rects[i] = r;
}
}
在第(9-13)行中,我们计算矩形顶点,并将其存储在RectF对象中。 如果我们要运行该应用程序,则可以使用在我们的开发环境中配置的真实智能手机或avd。 在这种情况下,请确保已将相机配置为使用:
运行示例并查看日志,我们有:
我们注意到,该应用检测到一张脸,而其他人为空,因为图片中没有更多的脸。
在检测到的脸部周围绘制矩形
最后一步是在检测到的面部周围绘制矩形。 在这种情况下,我们可以通过以下方式使用之前获取的信息:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint p = new Paint();
canvas.drawBitmap(image, 0, 0, p);
Paint rectPaint = new Paint();
rectPaint.setStrokeWidth(2);
rectPaint.setColor(Color.BLUE);
rectPaint.setStyle(Style.STROKE);
for (int i=0; i < MAX_FACES; i++) {
RectF r = rects[i];
if (r != null)
canvas.drawRect(r, rectPaint);
}
}
翻译自: https://www.javacodegeeks.com/2013/09/android-detect-face.html