青岛大学本科生毕业论文(设计)
LayoutParams.WRAP_CONTENT));
5.2.4 创建图片
setContentView就是设置一个Activity的显示界面,
使用setContentView可以在Activity中动态切换显示的View,这样先用LayoutInflater把布局xml文件引入成View对象,再通过setContentView(View view)方法来切换视图。
在屏幕上一块区域,WRAP_CONTENT,包裹组件:
Bitmap b = BitmapFactory.decodeResource(getResources(), R.drawable.face1);
mFaceBitmap = b.copy(Bitmap.Config.RGB_565, true); b.recycle();
采用Bitmap叠加Drawable文件夹中的face1图片
b.copy根据该位图的大小产生一个新位图,根据指定的结构设置新位图的结构,然后把位图的像素拷贝到新位图中,返回的位图和原图有同样的像素密度。参数:config结果图预期的结构,isMutable:如果是true,那么产生的图片是可变的。
mFaceWidth = mFaceBitmap.getWidth();
mFaceHeight = mFaceBitmap.getHeight(); mIV.setImageBitmap(mFaceBitmap);
5.2.5 获取人脸图片
调用doLengthyCalc()方法,实现背景图上检测人脸,最重要的方法实现在setFace(),它将FaceDetector对象实例化,同时调用findFaces,结果存放在faces里,人脸的中点转移到MyImageView。
通过FaceDetector可以设定检测到人脸数目的上限。比如设置最多只检测10张脸: private static final int MAX_FACES = 10;
Android人脸检测返回其他有用的信息,例同时会返回如eyesDistance,pose,以及confidence。我们可以通过eyesDistance来定位眼睛的中心位置。
5.2.6 人脸的眼部定位
本文主要对人脸识别的认证是对人脸中眼的部位进行的确定,也就是说对人眼部的识别来达到识别整个脸部的,因此对眼部的设置至关重要,主要程序段及程序功能介绍:
用类FaceDetector 取最大脸个数,创建对象。
FaceDetector.Face [] faces = new FaceDetector.Face[MAX_FACES]; PointF eyescenter = new PointF();
float eyesdist = 0.0f;//眼睛距离的初始值为0,因为人脸是用双眼来检测人脸的位置。
25
青岛大学本科生毕业论文(设计)
fd = new FaceDetector(mFaceWidth, mFaceHeight, MAX_FACES);
count = fd.findFaces(mFaceBitmap, faces);//调用FaceDetector中的findFaces方法,确定人脸的位置
if (count > 0) {
fpx = new int[count * 2];
fpy = new int[count * 2]; //如果返回人脸的个数大于0,则将记录人脸x和y坐标 for (int i = 0; i < count; i++) { try {
faces[i].getMidPoint(eyescenter);
eyesdist = faces[i].eyesDistance();//每个人脸根据眼睛连线的中点值,确定人脸之间的距离;
// set up left eye location
fpx[2 * i] = (int)(eyescenter.x - eyesdist / 2); fpy[2 * i] = (int)eyescenter.y; 距离值的一半,Y轴为眼睛中心的y值
// set up right eye location
fpx[2 * i + 1] = (int)(eyescenter.x + eyesdist / 2);
fpy[2 * i + 1] = (int)eyescenter.y;//计算左眼位置x轴为眼睛中心值的x坐标加两眼距离值的一半,Y轴为眼睛中心的y值
//计算左眼位置x轴为眼睛中心值的x坐标减两眼
if (DEBUG)
Log.e(TAG,
\
+ i
+ \+ faces[i].confidence() + \+ faces[i].eyesDistance() + \+ faces[i]
.pose(FaceDetector.Face.EULER_X)
+ \+ faces[i]
.pose(FaceDetector.Face.EULER_Y)
+ \+ faces[i]
26
青岛大学本科生毕业论文(设计)
}
}
}
.pose(FaceDetector.Face.EULER_Z)
+ \+ eyescenter.x + \+ \
} catch (Exception e) {
Log.e(TAG, \
mIV.setDisplayPoints(fpx, fpy, count * 2, 1);
实现setDisplayPoints() 在被检测出的人脸上标记渲染,如果参数debug值=1,则提示人脸检测的可信度值。
可信度值在android.media.FaceDetector.Face.CONFIDENCE_THRESHOLD中定义。
5.2.7 定义图片大小
扩展了基类ImageView,设计MyImageView类,引用了android的类库android.graphics.Bitmap; class MyImageView extends ImageView
定义图片尺寸大小:
private bitmap mBitmap;
private Canvas mCanvas; private int mBitmapWidth = 200; private int mBitmapHeight = 200;
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
5.2.8 创建位图及画板
Android 中的画笔是 Paint类,Paint 中包含了很多方法对其属性进行设置,主方法如下:
setAntiAlias: 设置画笔的锯齿效果。 setColor: 设置画笔颜色
setARGB: 设置画笔的a,r,p,g值。 setAlpha: 设置Alpha值 setTextSize: 设置字体尺寸
setStyle: 设置画笔风格,空心或者实心
27
青岛大学本科生毕业论文(设计)
setStrokeWidth: 设置空心的边框宽度 getColor: 得到画笔的颜色 getAlpha: 得到画笔的Alpha值 空心边框 画笔颜色为红色的线 /**画笔的类型**/
mPaint.setStyle(Paint.Style.STROKE); /**设置画笔变为圆滑状**/
mPaint.setStrokeCap(Paint.Cap.ROUND); /**设置线的宽度**/ mPaint.setStrokeWidth(5); 得到位图的高、宽创建位图和画板 public void setImageBitmap(Bitmap bm) { if (bm != null) { mBitmapWidth = bm.getWidth(); mBitmapHeight = bm.getHeight(); mBitmap
=
Bitmap.createBitmap(mBitmapWidth,
Bitmap.Config.RGB_565);
mCanvas = new Canvas();
mCanvas.setBitmap(mBitmap); mCanvas.drawBitmap(bm, 0, 0, null);
}
用于在画布上绘制图像,通过指定Bitmap对象来实现。 bitmap:Bitmap对象,代表了图像资源。 left:图像显示的左边位置。 top:图像显示的上边位置。 paint:绘制时所使用的画笔。 左上角开始画图,不用画笔 super.onSizeChanged(w, h, oldw, oldh); mBitmapWidth = (mBitmap != null) ? mBitmap.getWidth() : 0; mBitmapHeight = (mBitmap != null) ? mBitmap.getHeight() : 0; if (mBitmapWidth == w && mBitmapHeight == h) {
return;
if (mBitmapWidth < w) mBitmapWidth = w;
if (mBitmapHeight < h) mBitmapHeight = h;
}
28
mBitmapHeight,
青岛大学本科生毕业论文(设计)
在MyImageView中添加setDisplayPoints() ,用来在被检测出的人脸上标记渲染。获取图片的高度、宽度,如果图片小于设定的高、宽,则放大图
public void setDisplayPoints(int [] xx, int [] yy, int total, int style) {
mDisplayStyle = style; mPX = null; mPY = null;
if (xx != null && yy != null && total > 0) { }
mPX = new int[total]; mPY = new int[total]; for (int i = 0; i < total; i++) { }
mPX[i] = xx[i]; mPY[i] = yy[i];
画笔风格是空心,x和y坐标等于xx和yy数组 protected void onDraw(Canvas canvas) {
super.onDraw(canvas); if (mBitmap != null) {
canvas.drawBitmap(mBitmap, 0, 0, null); if (mPX != null && mPY != null) {
for (int i = 0; i < mPX.length; i++) {
if (mDisplayStyle == 1) { }
canvas.drawCircle(mPX[i], mPY[i], 10.0f, mPaint);
canvas.drawRect(mPX[i] - 20, mPY[i] - 20, mPX[i] + 20, } else {
mPY[i] + 20, mPaint);
在画板上画图:
如果位图不是空,则调用canvas.drawBitmap方法从左上角画图,x和y坐标不是空,则根据x的长度值循环,判断mDisplayStyle == 1。
调用画圆圈方法,canvas.drawCircle(mPX[i], mPY[i], 10.0f, mPaint);从x和y的坐标上开始画半径为10的圆,如果不是则画矩形。
29