1. 相关背景
Google 于2006年8月收购Neven Vision 公司 (该公司拥有 10 多项应用于移动设备领域的图像识别的专利),以此获得了图像识别的技术,并不是常快应用到免费的 Picasa 相冊管理程序中,提供基于人脸识别的相片管理功能,另外还推出了一个新项目叫Goggle ,能从照片中识别世界各地的地标建筑,相同Google 也把人脸识别功能加入�到了Android 中。只是因为个人隐私等相关因素,Google Goggles好像临时屏蔽了人脸识别功能 。
2. Android 中的人脸识别技术
底层库:android/external/neven/
framework 层:frameworks/base/media/java/android/media/FaceDetector.java
Java 层接口的限制:
仅仅能接受 Bitmap 格式的数据
仅仅能识别双眼距离大于 20 像素的人脸像(当然,这个可在framework层中改动)
仅仅能检測出人脸的位置(双眼的中心点及距离)
效果例如以下:
Google 于2006年8月收购Neven Vision 公司 (该公司拥有 10 多项应用于移动设备领域的图像识别的专利),以此获得了图像识别的技术,并不是常快应用到免费的 Picasa 相冊管理程序中,提供基于人脸识别的相片管理功能,另外还推出了一个新项目叫Goggle ,能从照片中识别世界各地的地标建筑,相同Google 也把人脸识别功能加入�到了Android 中。只是因为个人隐私等相关因素,Google Goggles好像临时屏蔽了人脸识别功能 。
2. Android 中的人脸识别技术
底层库:android/external/neven/
framework 层:frameworks/base/media/java/android/media/FaceDetector.java
Java 层接口的限制:
仅仅能接受 Bitmap 格式的数据
仅仅能识别双眼距离大于 20 像素的人脸像(当然,这个可在framework层中改动)
仅仅能检測出人脸的位置(双眼的中心点及距离)
不能对人脸进行匹配(查找指定的脸谱)
A. 为 Camera 加入�人脸识别的功能:使得 Camera 的取景器上能标识出人脸范围;假设硬件支持,能够对人脸进行对焦。
4. 静态图片处理代码实例:
package com.example.mydetect2; import android.os.Bundle; import android.app.Activity; import android.util.Log; import android.view.Menu; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.PointF; import android.media.FaceDetector; //人脸识别的关键类 import android.media.FaceDetector.Face; import android.view.View; public class MainActivity2 extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //setContentView(R.layout.activity_main_activity2); setContentView(new myView(this)); //使用自建的view来显示 Log.i("zhangcheng","MainActivity2 run here"); } private class myView extends View{ private int imageWidth, imageHeight; private int numberOfFace = 5; //最大检測的人脸数 private FaceDetector myFaceDetect; //人脸识别类的实例 private FaceDetector.Face[] myFace; //存储多张人脸的数组变量 float myEyesDistance; //两眼之间的距离 int numberOfFaceDetected; //实际检測到的人脸数 Bitmap myBitmap; public myView(Context context){ //view类的构造函数,必须有 super(context); BitmapFactory.Options BitmapFactoryOptionsbfo = new BitmapFactory.Options(); BitmapFactoryOptionsbfo.inPreferredConfig = Bitmap.Config.RGB_565; //构造位图生成的參数,必须为565。类名+enum myBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.baby, BitmapFactoryOptionsbfo); imageWidth = myBitmap.getWidth(); imageHeight = myBitmap.getHeight(); myFace = new FaceDetector.Face[numberOfFace]; //分配人脸数组空间 myFaceDetect = new FaceDetector(imageWidth, imageHeight, numberOfFace); numberOfFaceDetected = myFaceDetect.findFaces(myBitmap, myFace); //FaceDetector 构造实例并解析人脸 Log.i("zhangcheng","numberOfFaceDetected is " + numberOfFaceDetected); } protected void onDraw(Canvas canvas){ //override函数,必有 canvas.drawBitmap(myBitmap, 0, 0, null); //画出位图 Paint myPaint = new Paint(); myPaint.setColor(Color.GREEN); myPaint.setStyle(Paint.Style.STROKE); myPaint.setStrokeWidth(3); //设置位图上paint操作的參数 for(int i=0; i < numberOfFaceDetected; i++){ Face face = myFace[i]; PointF myMidPoint = new PointF(); face.getMidPoint(myMidPoint); myEyesDistance = face.eyesDistance(); //得到人脸中心点和眼间距离參数,并对每一个人脸进行画框 canvas.drawRect( //矩形框的位置參数 (int)(myMidPoint.x - myEyesDistance), (int)(myMidPoint.y - myEyesDistance), (int)(myMidPoint.x + myEyesDistance), (int)(myMidPoint.y + myEyesDistance), myPaint); } } } }
效果例如以下:
如要注意的地方:
依据文档描写叙述,输入图片必须为Bitmap RGB565格式。
人脸的检測方法是用双眼来检測人脸的位置,也就是说无法检測到嘴、側脸等,双眼必须同一时候可见,而且眼镜会影响检測的效果。
实际上,FaceDetector检測到的并非人的全脸,而仅仅是双眼。
实际測试中,发现图片太小的话检測不到人脸,试验中使用小于100x100的图片检測不到人脸,可是因为Android内存有限,图片太大的话,会出现无法载入图片的异常。
检測到的人脸存放到FaceDetector.Face类中,该类无法再扩展。从该类能够获取到人眼的中心位置和双眼之间的详细。