`
chriszeng87
  • 浏览: 740945 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Android中的人脸检测(静态和动态)

阅读更多

(1)背景。

       Google 于2006年8月收购Neven Vision 公司 (该公司拥有10多项应用于移动设备领域的图像识别的专利),以此获得了图像识别的技术,并加入到android中。Android 中的人脸识别技术,用到的底层库:android/external/neven/,framework 层:frameworks/base/media/java/android/media/FaceDetector.java。

       Java 层接口的限制:A,只能接受Bitmap 格式的数据;B,只能识别双眼距离大于20 像素的人脸像(当然,这个可在framework层中修改);C,只能检测出人脸的位置(双眼的中心点及距离),不能对人脸进行匹配(查找指定的脸谱)。

        人脸识别技术的应用:A,为Camera 添加人脸识别的功能,使得Camera 的取景器上能标识出人脸范围;如果硬件支持,可以对人脸进行对焦。B,为相册程序添加按人脸索引相册的功能,按人脸索引相册,按人脸分组,搜索相册。

(2)Neven库给上层提供的主要方法:
        A,android.media.FaceDetector .FaceDetector(int width, int height, int maxFaces):Creates a FaceDetector, configured with the size of the images to be analysed and the maximum number of faces that can be detected. These parameters cannot be changed once the object is constructed.

        B,int android.media.FaceDetector .findFaces(Bitmap bitmap, Face [] faces):Finds all the faces found in a given Bitmap . The supplied array is populated with FaceDetector.Face s for each face found. The bitmap must be in 565 format (for now).

(3) 静态图片处理代码实例:

       通过对位图的处理,捕获位图中的人脸,并以绿框显示,有多个人脸就提示多个绿框。首先新建一个activity,由于位图资源会用代码显示出来,所以不需在layout中使用widget。

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. package com.example.mydetect2;  
  2.   
  3. import android.os.Bundle;  
  4. import android.app.Activity;  
  5. import android.util.Log;  
  6. import android.view.Menu;  
  7. import android.content.Context;   
  8. import android.graphics.Bitmap;   
  9. import android.graphics.BitmapFactory;   
  10. import android.graphics.Canvas;   
  11. import android.graphics.Color;   
  12. import android.graphics.Paint;   
  13. import android.graphics.PointF;   
  14. import android.media.FaceDetector;  //人脸识别的关键类  
  15. import android.media.FaceDetector.Face;   
  16. import android.view.View;   
  17.   
  18. public class MainActivity2 extends Activity {  
  19.   
  20.     @Override  
  21.     protected void onCreate(Bundle savedInstanceState) {  
  22.         super.onCreate(savedInstanceState);  
  23.         //setContentView(R.layout.activity_main_activity2);  
  24.         setContentView(new myView(this));   //使用自建的view来显示  
  25.         Log.i("zhangcheng","MainActivity2 run here");  
  26.     }  
  27.   
  28.     private class myView extends View{  
  29.         private int imageWidth, imageHeight;  
  30.         private int numberOfFace = 5;       //最大检测的人脸数  
  31.         private FaceDetector myFaceDetect;  //人脸识别类的实例  
  32.         private FaceDetector.Face[] myFace; //存储多张人脸的数组变量  
  33.         float myEyesDistance;           //两眼之间的距离  
  34.         int numberOfFaceDetected;       //实际检测到的人脸数  
  35.         Bitmap myBitmap;  
  36.   
  37.         public myView(Context context){     //view类的构造函数,必须有  
  38.             super(context);   
  39.             BitmapFactory.Options BitmapFactoryOptionsbfo = new BitmapFactory.Options();   
  40.             BitmapFactoryOptionsbfo.inPreferredConfig = Bitmap.Config.RGB_565;  //构造位图生成的参数,必须为565。类名+enum  
  41.             myBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.baby, BitmapFactoryOptionsbfo);     
  42.             imageWidth = myBitmap.getWidth();   
  43.             imageHeight = myBitmap.getHeight();   
  44.             myFace = new FaceDetector.Face[numberOfFace];       //分配人脸数组空间  
  45.             myFaceDetect = new FaceDetector(imageWidth, imageHeight, numberOfFace);   
  46.             numberOfFaceDetected = myFaceDetect.findFaces(myBitmap, myFace);    //FaceDetector 构造实例并解析人脸  
  47.             Log.i("zhangcheng","numberOfFaceDetected is " + numberOfFaceDetected);  
  48.         }  
  49.           
  50.         protected void onDraw(Canvas canvas){           //override函数,必有  
  51.             canvas.drawBitmap(myBitmap, 00null);    //画出位图   
  52.             Paint myPaint = new Paint();   
  53.             myPaint.setColor(Color.GREEN);   
  54.             myPaint.setStyle(Paint.Style.STROKE);   
  55.             myPaint.setStrokeWidth(3);          //设置位图上paint操作的参数  
  56.   
  57.             for(int i=0; i < numberOfFaceDetected; i++){  
  58.                 Face face = myFace[i];  
  59.                 PointF myMidPoint = new PointF();   
  60.                 face.getMidPoint(myMidPoint);   
  61.                 myEyesDistance = face.eyesDistance();   //得到人脸中心点和眼间距离参数,并对每个人脸进行画框  
  62.                 canvas.drawRect(            //矩形框的位置参数  
  63.                         (int)(myMidPoint.x - myEyesDistance),   
  64.                         (int)(myMidPoint.y - myEyesDistance),   
  65.                         (int)(myMidPoint.x + myEyesDistance),   
  66.                         (int)(myMidPoint.y + myEyesDistance),   
  67.                         myPaint);  
  68.             }  
  69.         }  
  70.     }  
  71. }  


      以上为activity,工程的xml文件没有什么特殊地方。最后得到的结果如下,图片资源是png的也可以。

 


 (4) 动态预览识别人脸代码实例

       该过程用于后台工作,没有界面也没有预览。所以没有采用上面那种处理位图资源的方式。Import的类就不列出了,核心的代码和流程如下:

A,打开摄像头,获得初步摄像头回调数据,用到是setpreviewcallback

protected Camera mCameraDevice = null;// 摄像头对象实例

private long mScanBeginTime = 0;   // 扫描开始时间
private long mScanEndTime = 0;   // 扫描结束时间
private long mSpecPreviewTime = 0;   // 扫描持续时间

private int orientionOfCamera ;   //前置摄像头layout角度

int numberOfFaceDetected;    //最终识别人脸数目

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. public void startFaceDetection() {  
  2.         try {  
  3.                 mCameraDevice = Camera.open(1);     //打开前置  
  4.                 if (mCameraDevice != null)  
  5.                     Log.i(TAG, "open cameradevice success! ");  
  6.             } catch (Exception e) {             //Exception代替很多具体的异常  
  7.                 mCameraDevice = null;  
  8.                 Log.w(TAG, "open cameraFail");  
  9.                 mHandler.postDelayed(r,5000);   //如果摄像头被占用,人眼识别每5秒检测看有没有释放前置  
  10.                 return;  
  11.         }   
  12.               
  13.         Log.i(TAG, "startFaceDetection");  
  14.         Camera.Parameters parameters = mCameraDevice.getParameters();  
  15.         setCameraDisplayOrientation(1,mCameraDevice);              //设置预览方向   
  16.               
  17.         mCameraDevice.setPreviewCallback(new PreviewCallback(){  
  18.             public void onPreviewFrame(byte[] data, Camera camera){  
  19.                 mScanEndTime = System.currentTimeMillis();   //记录摄像头返回数据的时间  
  20.                 mSpecPreviewTime = mScanEndTime - mScanBeginTime;  //从onPreviewFrame获取摄像头数据的时间  
  21.                 Log.i(TAG, "onPreviewFrame and mSpecPreviewTime = " + String.valueOf(mSpecPreviewTime));  
  22.                 Camera.Size localSize = camera.getParameters().getPreviewSize();  //获得预览分辨率  
  23.                 YuvImage localYuvImage = new YuvImage(data, 17, localSize.width, localSize.height, null);  
  24.                 ByteArrayOutputStream localByteArrayOutputStream = new ByteArrayOutputStream();  
  25.                 localYuvImage.compressToJpeg(new Rect(00, localSize.width, localSize.height), 80, localByteArrayOutputStream);    //把摄像头回调数据转成YUV,再按图像尺寸压缩成JPEG,从输出流中转成数组  
  26.                 byte[] arrayOfByte = localByteArrayOutputStream.toByteArray();  
  27.                 CameraRelease();   //及早释放camera资源,避免影响camera设备的正常调用  
  28.                 StoreByteImage(arrayOfByte);  
  29.             }  
  30.         });  
  31.   
  32.         mCameraDevice.startPreview();         //该语句可放在回调后面,当执行到这里,调用前面的setPreviewCallback  
  33.         mScanBeginTime = System.currentTimeMillis();// 记录下系统开始扫描的时间  
  34.     }  

B,设置预览方向的函数说明,该函数比较重要,因为方向直接影响bitmap构造时的矩阵旋转角度,影响最终人脸识别的成功与否

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. public void setCameraDisplayOrientation(int paramInt, Camera paramCamera){  
  2.         CameraInfo info = new CameraInfo();  
  3.         Camera.getCameraInfo(paramInt, info);  
  4.         int rotation = ((WindowManager)getSystemService("window")).getDefaultDisplay().getRotation();  //获得显示器件角度  
  5.         int degrees = 0;  
  6.         Log.i(TAG,"getRotation's rotation is " + String.valueOf(rotation));  
  7.         switch (rotation) {  
  8.             case Surface.ROTATION_0: degrees = 0break;  
  9.             case Surface.ROTATION_90: degrees = 90break;  
  10.             case Surface.ROTATION_180: degrees = 180break;  
  11.             case Surface.ROTATION_270: degrees = 270break;  
  12.         }  
  13.   
  14.         orientionOfCamera = info.orientation;      //获得摄像头的安装旋转角度  
  15.         int result;  
  16.         if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {  
  17.             result = (info.orientation + degrees) % 360;  
  18.             result = (360 - result) % 360;  // compensate the mirror  
  19.         } else {  // back-facing  
  20.             result = (info.orientation - degrees + 360) % 360;  
  21.         }  
  22.         paramCamera.setDisplayOrientation(result);  //注意前后置的处理,前置是映象画面,该段是SDK文档的标准DEMO  
  23.     }  

C,对摄像头回调数据进行转换并最终解成BITMAP后再人脸识别的过程

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. public void StoreByteImage(byte[] paramArrayOfByte){  
  2.         mSpecStopTime = System.currentTimeMillis();  
  3.         mSpecCameraTime = mSpecStopTime - mScanBeginTime;  
  4.                        
  5.         Log.i(TAG, "StoreByteImage and mSpecCameraTime is " + String.valueOf(mSpecCameraTime));  
  6.   
  7.         BitmapFactory.Options localOptions = new BitmapFactory.Options();  
  8.             Bitmap localBitmap1 = BitmapFactory.decodeByteArray(paramArrayOfByte, 0, paramArrayOfByte.length, localOptions);  
  9.             int i = localBitmap1.getWidth();  
  10.             int j = localBitmap1.getHeight();   //从上步解出的JPEG数组中接出BMP,即RAW->JPEG->BMP  
  11.             Matrix localMatrix = new Matrix();  
  12.             //int k = cameraResOr;  
  13.             Bitmap localBitmap2 = null;  
  14.             FaceDetector localFaceDetector = null;  
  15.   
  16.         switch(orientionOfCamera){   //根据前置安装旋转的角度来重新构造BMP  
  17.             case 0:  
  18.                 localFaceDetector = new FaceDetector(i, j, 1);  
  19.                         localMatrix.postRotate(0.0F, i / 2, j / 2);  
  20.                         localBitmap2 = Bitmap.createBitmap(i, j, Bitmap.Config.RGB_565);  
  21.                 break;  
  22.             case 90:  
  23.                 localFaceDetector = new FaceDetector(j, i, 1);   //长宽互换  
  24.                         localMatrix.postRotate(-270.0F, j / 2, i / 2);  //正90度的话就反方向转270度,一样效果  
  25.                         localBitmap2 = Bitmap.createBitmap(i, j, Bitmap.Config.RGB_565);  
  26.                 break;                        
  27.             case 180:  
  28.                 localFaceDetector = new FaceDetector(i, j, 1);  
  29.                         localMatrix.postRotate(-180.0F, i / 2, j / 2);  
  30.                         localBitmap2 = Bitmap.createBitmap(i, j, Bitmap.Config.RGB_565);  
  31.                 break;  
  32.             case 270:  
  33.                 localFaceDetector = new FaceDetector(j, i, 1);  
  34.                         localMatrix.postRotate(-90.0F, j / 2, i / 2);  
  35.                         localBitmap2 = Bitmap.createBitmap(j, i, Bitmap.Config.RGB_565);  //localBitmap2应是没有数据的  
  36.                 break;  
  37.         }  
  38.   
  39.         FaceDetector.Face[] arrayOfFace = new FaceDetector.Face[1];  
  40.             Paint localPaint1 = new Paint();  
  41.             Paint localPaint2 = new Paint();  
  42.         localPaint1.setDither(true);  
  43.             localPaint2.setColor(-65536);  
  44.             localPaint2.setStyle(Paint.Style.STROKE);  
  45.             localPaint2.setStrokeWidth(2.0F);  
  46.             Canvas localCanvas = new Canvas();  
  47.             localCanvas.setBitmap(localBitmap2);  
  48.             localCanvas.setMatrix(localMatrix);  
  49.             localCanvas.drawBitmap(localBitmap1, 0.0F, 0.0F, localPaint1); //该处将localBitmap1和localBitmap2关联(可不要?)  
  50.   
  51.         numberOfFaceDetected = localFaceDetector.findFaces(localBitmap2, arrayOfFace); //返回识脸的结果  
  52.             localBitmap2.recycle();  
  53.             localBitmap1.recycle();   //释放位图资源  
  54.   
  55.         FaceDetectDeal(numberOfFaceDetected);  
  56.     }  

 

 

参考原文:http://blog.renren.com/share/234025064/6227088558

参考原文:http://www.csdn.net/article/a/2012-04-27/2805150

参考原文:http://www.cnblogs.com/feisky/archive/2010/09/12/1824320.html

 

转自:http://blog.csdn.net/zhandoushi1982/article/details/8613916

分享到:
评论

相关推荐

    基于Android静态图片人脸检测demo

    本文将深入探讨如何使用Android自带的人脸检测API来实现静态图片中的人脸检测,并绘制出眼睛和人脸的矩形框。 首先,Android SDK提供了一个名为`FaceDetector`的类,它位于`android.media`包下,专门用于检测图像中...

    基于Android自带API的 静态图片人脸检测demo

    利用android自带人脸检测APi检测图片中的人脸并绘制出眼睛和人脸矩形框,代码讲解请参考博客:http://blog.csdn.net/yanzi1225627/article/details/17651809

    Android中的人脸检测的示例代码(静态和动态)

    在本文中,我们将深入探讨如何在Android中实现静态和动态的人脸检测,以及相关的示例代码。 首先,Android的人脸检测功能依赖于Google在2006年收购的Neven Vision公司的技术。这一技术被集成到Android系统中,位于`...

    Android 开发 API人脸检测实例教程

    虽然它的主要目的是获取音频和视频信息,但也可以用于从帧中提取静态图像,然后进行人脸检测。不过,其人脸检测功能相对简单,可能无法满足复杂的需求。 2. **OpenCV库**:OpenCV是一个开源的计算机视觉库,包含了...

    基于seetaface6的人脸识别源码_android版

    在Android应用中,首先需要进行人脸检测,即在图像中找到人脸的位置。SeetaFace6使用的是单阶段检测器,能够在图像中快速而准确地定位人脸。这个过程通常包括预处理(如灰度化、归一化)、人脸候选区域生成和候选...

    在android手机上使用opencv库识别静态人脸图像的眼睛位置

    在这个过程中,我们将探讨如何通过OpenCV实现人脸检测和眼睛定位。 首先,我们需要集成OpenCV到Android项目中。这通常通过添加OpenCV的Android SDK作为依赖来完成。在Android Studio中,可以在build.gradle文件中...

    Android系统下OpenCV的人脸检测模块的设计_公衍宇1

    在Android系统下,OpenCV的人脸检测模块设计是一项关键技术,主要解决了如何将OpenCV库编译和移植到Android平台的问题。OpenCV(Open Source Computer Vision Library)是一个强大的计算机视觉库,广泛应用于图像...

    Android 基于face++人脸对比API.实现人脸登录功能

    1. **人脸检测**:这是整个过程的第一步,通过Face++ API在上传的图片中检测出人脸的位置和大小。API通常会返回一个包含人脸位置信息的矩形框,以便后续处理。 2. **特征提取**:在人脸检测后,API会提取出人脸的...

    Android 人脸识别,完美识别

    OpenCV库提供了强大的图像处理功能,包括Haar级联分类器和Local Binary Patterns Histograms (LBPH)等方法来进行人脸检测。然而,如描述中提到的,可能由于设置问题或对API的理解不足,开发者可能会遇到前置摄像头...

    Android人脸识别源码

    这个"Android人脸识别源码"项目显然旨在提供一个高效且准确的解决方案,能够识别人脸,无论是静态照片还是动态视频。 人脸识别技术的核心是通过算法分析和比较人脸的特征来确定个体身份。以下是一些关键知识点: 1...

    基于Android的Centerface人脸检测

    在这个项目中,开发者选择在Android Studio 4这个成熟的开发环境中集成Centerface算法,为移动设备提供高效的人脸检测解决方案。 首先,我们要理解Centerface算法的核心原理。Centerface是一种基于单阶段的深度学习...

    Android API人脸检测范例代码.rar

    Android API人脸检测范例代码,打开一张含有人脸的照片,程序会自动识别人脸区域,在人的眼睛区域标识出红圈,看着更像是人眼检测,哈哈。这个人脸检测是静态的,也就是打开图片识别,并不能实现像手机取景时的人脸...

    人脸识别(静态)

    在这个项目中,可能采用了百度AI的API,该API提供了人脸检测、特征提取和比对等功能。 2. **Android Studio**:Android Studio是Google推出的一款集成开发环境(IDE),专为Android应用开发设计。开发者使用它编写...

    基于Android的人脸识别

    ML Kit的人脸检测API可以直接在设备上运行,无需云端服务,因此响应速度快且数据隐私得到保护。只需几行代码,就可以实现在实时摄像头流或静态图片中检测人脸。 在AndroidFaceCropper-master这个项目中,我们可能...

    ReactNative的人脸检测和识别库高品质甚至更快

    "React Native的人脸检测和识别库高品质甚至更快"这个标题表明,我们讨论的是一个专门针对React Native的库,用于在移动应用中实现高效、高质量的人脸检测和识别功能。 在移动应用开发中,人脸检测和识别是机器学习...

    find_your_beauty.rar_Android人脸_android_人脸_人脸美化

    总的来说,"find_your_beauty.rar"这个压缩包中的内容可能涵盖了Android人脸检测与美化应用的多个方面,包括但不限于人脸检测、图像处理、机器学习模型的运用、Android开发技术以及用户体验设计。这些技术的应用使得...

    Android人脸识别

    本文将深入探讨Android系统中的人脸识别技术,包括基础理论、API使用以及一个基于Android自带API的静态图片人脸检测示例。 1. 基础理论: - 人脸识别技术主要分为几个步骤:预处理、特征提取、匹配和识别。预处理...

    Android应用源码之开发 API人脸检测实例教程.rar

    这个实例教程将带领我们深入理解如何在Android中利用API来实现高效准确的人脸检测功能。以下是对这个压缩包内容的详细解析: 1. **人脸检测API**: - 人脸检测通常涉及计算机视觉领域,Android提供了一个名为`...

    Android平台最新opencv静态库

    OpenCV库在Android上主要有两种形式:静态库和动态库。静态库将所有依赖项打包到单一的库文件中,使得应用在运行时无需依赖外部库,但会增加APK的大小。动态库则是在运行时从系统中加载所需的库文件,能减小APK体积...

Global site tag (gtag.js) - Google Analytics