Android人脸识别原理
Android的人脸识别在没接触前,想的应该是比较高端的一种处理技术。但当百度了一番后,发现,其实你可以很简单的实现这个。
Android本身提供的人脸识别原理其实是很简单的,找到图片上你左右双眼的位置,然后在眼睛四周画个框标识出来。
Android人脸识别演示
要做演示,首先需要准备好材料。
1、准备好图片;
2、对图片进行识别;
3、如果图片中有人脸,则将人脸标识出来。
新建一个工程,我们将图片放入到工程的res/drawable-hdpi下。在代码中取图片信息。
整体的代码如下:
package com.example.facedetector_csdn;
import android.media.FaceDetector;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.app.Activity;
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.graphics.RectF;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.app.Activity;
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.graphics.RectF;
public class MainActivity extends Activity {
ImageView imgView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imgView=(ImageView)findViewById(R.id.img);
Button btnButton=(Button)findViewById(R.id.btn);
btnButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
secondStep(firstStep());
}
});
}
//Step 1. 读取一张图片至Bitmap
public Bitmap firstStep()
{
//取图片并转为bitmap格式
Bitmap sampleBmp=BitmapFactory.decodeResource(getResources(), R.drawable.img);
//FaceDetecor只能读取RGB 565格式的Bitmap,所以在开始识别前,我们需要将上面得到的Bitmap进行一次格式转换。
Bitmap tmpBmp = sampleBmp.copy(Bitmap.Config.RGB_565, true);
return tmpBmp;
}
//Step2. 识别图片中的人脸,并标识
public void secondStep(Bitmap bitmap)
{
//设定最大可查的人脸数量
int MAX_FACES=5;
FaceDetector faceDet = new FaceDetector(bitmap.getWidth(), bitmap.getHeight(), MAX_FACES);
//将人脸数据存储到facelist中
FaceDetector.Face[] faceList = new FaceDetector.Face[MAX_FACES];
faceDet.findFaces(bitmap, faceList);
// FaceDetector API文档我们发现,它查找人脸的原理是:找眼睛。
// 它返回的人脸数据face,通过调用public float eyesDistance (),public void getMidPoint (PointF point),
// 我们可以得到探测到的两眼间距,以及两眼中心点位置(MidPoint)。
// public float confidence () 可以返回该人脸数据的可信度(0~1),这个值越大,该人脸数据的准确度也就越高。
RectF[] faceRects=new RectF[faceList.length];
for (int i=0; i < faceList.length; i++) {
FaceDetector.Face face = faceList[i];
Log.d("FaceDet", "Face ["+face+"]");
if (face != null) {
//confidence标识一个匹配度,在0~1区间,越接近1,表示匹配越高。如果需要可以加上这个判断条件
//这里不做判断
Log.d("FaceDet", "Face ["+i+"] - Confidence ["+face.confidence()+"]");
//获取两眼中心点的坐标位置
PointF pf = new PointF();
face.getMidPoint(pf);
//这里的框,参数分别是:左上角的X,Y 右下角的X,Y
//也就是左上角(r.left,r.top),右下角( r.right,r.bottom)。作为定位,确定这个框的格局。
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;
faceRects[i] = r;
//画框:对原图进行处理,并在图上显示人脸框。
Canvas canvas = new Canvas(bitmap);
Paint p = new Paint();
p.setAntiAlias(true);
p.setStrokeWidth(2);
p.setStyle(Paint.Style.STROKE);
p.setColor(Color.BLUE);
//画一个圈圈
canvas.drawCircle(r.left, pf.y, 10, p);
canvas.drawCircle(r.right, pf.y, 10, p);
//画框
canvas.drawRect(r, p);
//图片显示
imgView.setImageBitmap(bitmap);
}
}
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imgView=(ImageView)findViewById(R.id.img);
Button btnButton=(Button)findViewById(R.id.btn);
btnButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
secondStep(firstStep());
}
});
}
//Step 1. 读取一张图片至Bitmap
public Bitmap firstStep()
{
//取图片并转为bitmap格式
Bitmap sampleBmp=BitmapFactory.decodeResource(getResources(), R.drawable.img);
//FaceDetecor只能读取RGB 565格式的Bitmap,所以在开始识别前,我们需要将上面得到的Bitmap进行一次格式转换。
Bitmap tmpBmp = sampleBmp.copy(Bitmap.Config.RGB_565, true);
return tmpBmp;
}
//Step2. 识别图片中的人脸,并标识
public void secondStep(Bitmap bitmap)
{
//设定最大可查的人脸数量
int MAX_FACES=5;
FaceDetector faceDet = new FaceDetector(bitmap.getWidth(), bitmap.getHeight(), MAX_FACES);
//将人脸数据存储到facelist中
FaceDetector.Face[] faceList = new FaceDetector.Face[MAX_FACES];
faceDet.findFaces(bitmap, faceList);
// FaceDetector API文档我们发现,它查找人脸的原理是:找眼睛。
// 它返回的人脸数据face,通过调用public float eyesDistance (),public void getMidPoint (PointF point),
// 我们可以得到探测到的两眼间距,以及两眼中心点位置(MidPoint)。
// public float confidence () 可以返回该人脸数据的可信度(0~1),这个值越大,该人脸数据的准确度也就越高。
RectF[] faceRects=new RectF[faceList.length];
for (int i=0; i < faceList.length; i++) {
FaceDetector.Face face = faceList[i];
Log.d("FaceDet", "Face ["+face+"]");
if (face != null) {
//confidence标识一个匹配度,在0~1区间,越接近1,表示匹配越高。如果需要可以加上这个判断条件
//这里不做判断
Log.d("FaceDet", "Face ["+i+"] - Confidence ["+face.confidence()+"]");
//获取两眼中心点的坐标位置
PointF pf = new PointF();
face.getMidPoint(pf);
//这里的框,参数分别是:左上角的X,Y 右下角的X,Y
//也就是左上角(r.left,r.top),右下角( r.right,r.bottom)。作为定位,确定这个框的格局。
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;
faceRects[i] = r;
//画框:对原图进行处理,并在图上显示人脸框。
Canvas canvas = new Canvas(bitmap);
Paint p = new Paint();
p.setAntiAlias(true);
p.setStrokeWidth(2);
p.setStyle(Paint.Style.STROKE);
p.setColor(Color.BLUE);
//画一个圈圈
canvas.drawCircle(r.left, pf.y, 10, p);
canvas.drawCircle(r.right, pf.y, 10, p);
//画框
canvas.drawRect(r, p);
//图片显示
imgView.setImageBitmap(bitmap);
}
}
}
}
代码的处理很简单,获取图片,转换图片格式,将图片中可能存在的人脸数据存储到数组中,对数组中可能存在的人脸数据进行处理,画框。
比尔盖茨镇楼,点击检测人脸,效果如下:
效果是出来了,虽然挺难看。
上面这个图片,只有比尔盖茨一张脸,而我们设定的最大值是5,这样我们换个图片,看看是否可以检测到多个人脸。
到这里我们看到我们想要的效果都实现了。如果你想要识别同一个人的两张照片,其实也可以按这个流程来处理,对比。
最后,我们还来验证一个问题,Android人脸识别既然是以眼睛作为查找的原理,那我们闭上眼睛会怎么样呢,看一张闭眼的美女图片,在检测人脸前后是否有变化。
前后无变化,代码会提示你
检测不到人脸数据。因此想要检测人脸,请睁开你的眼睛。
转载:http://blog.csdn.net/yangzhaomuma/article/details/50194753