详解android人脸检测你一定会遇到的坑

  

笔者今年做了一个和人脸有关的android产品,主要是获取摄像头返回的预览数据流,判断该数据流是否包含了人的脸,有人脸时显示摄像头预览框,无人脸时摄像头预览框隐藏,看上去这个功能并不复杂,其实在开发过程中,遇到的问题也不多,全部都处理了,在正式推出前,这个产品在公司内部也测试了几个月,也没发现错误,但最近实施人员,在客户公司做实施时,反馈回来各种问题,这些问题有部分是程序错误,也有一部分是和硬件有关,因为测试环境有限,笔者无法对各种型号,各个厂家的硬件进行测试,这篇文章主要是记录,摄像头给我们带来的一些坑,分享给涉及到人脸开发的朋友,让大家少走弯路。

  

<强>一:概述

  

Android SDK中支持人脸检测,它提供了一个直接在位图上进行人脸检测的方法,这个API是android.media。FaceDetector、源文件路径是:
  

  

框架/库/媒体/java/android/媒体/FaceDetector。java
  

  

调用findFaces方法就可进行人脸检测,该方法返回检测到的人脸总数,并且会将每个人“脸”的信息保存在FaceDetector。脸的数组中,每个脸都包含下面几点信息:

  
      <李>该面为人脸的可信度。取值范围是0 ~ 1,大于0.3则表明可信度较高。   <李>双眼之间的距离李   <李>双眼中点的x, y坐标李   <李>脸部的欧拉角度,可用于判断抬头,侧脸的角度等。   
  

识别流程是这样的:
  

  

1。读取一张图片至位图,且该位图必须是565格式。
  

  

2。调用findFaces方法分析图(注意待分析的位图宽度必须是偶数),将探测到的人脸数据存储在一个FaceDetector。面对数组中,并返回检测到的人脸总数.Android SDK中的FaceDetector介绍

  

android有原生的api做人脸检测,通过android.media.FaceDetector来检测位图是否包含人脸,android.media.FaceDetector.Face来检测人脸位置信息,我们需要在活动中实现Carema。PreviewCallBack接口,该接口有一个onPreviewFrame方法,这个方法返回摄像头实时图像的数据流,由于这个方法返回的数据流时nv21格式,我们需要转换图才能进行人脸检测,转换过程如下:byte[]——比;YuvImage——比;ByteArrayOutputStream——比;byte[]——在,位图,具体转换的代码如下:

        相机。尺寸大?mtCamera.getParameters () .getPreviewSize ();   YuvImage YuvImage=new YuvImage (mData ImageFormat。NV21,大小。宽度、大小。高度,null);   yuvImage.compressToJpeg(新矩形(0,0,大小。宽度,size.height), 100年,mBitmapOutput);   选项。inPreferredConfig=Bitmap.Config.RGB_565;   位图=BitmapFactory.decodeByteArray (mBitmapOutput.toByteArray (), 0, mBitmapOutput.toByteArray ()。长度,选择);   mBitmapOutput.reset ();   位图=位图。createBitmap(位图,0,0,bitmap.getWidth (), bitmap.getHeight (), mMatrix, false),      

通过上面的转换,我们已经得到了人脸检测的位图,此时只需要进行人脸检测就好了,代码如下:

        探测器=new FaceDetector (source.getWidth (), source.getHeight (), maxFaceNum);   面对[]面临=新面孔(maxFaceNum);   探测器。findFaces(来源,脸);      

代码基本上就哪么多,由于受到硬件的影响,上面的代码有很多地雷。

  

二:人脸检测常见问题

  

产品上线后,主要问题有,人站在摄像头面前,应用无法识别人的脸,软件运行性能也会下降,出现严重卡顿等问题,当前我比较郁闷,明明在测试环境都运行几个月了,都没有出现这些问题,正式实施的时候,问题不断,通过近两个月的整理,主要问题有以下几个。

  

2.1,,无法识别人脸

  

1):相机角度问题

  

由于我在测试的时候,摄像头图像是垂直的,没有任何问题,但正式使用时,摄像头来自不同商家,导致摄像头图像是水平的了,如下图:

  

详解android人脸检测你一定会遇到的坑”>,</p>
  <p> <img src=   公共空白setCameraDisplayOrientation(活动活动,int cameraId android.hardware。相机镜头){   android.hardware.Camera。CameraInfo信息=new android.hardware.Camera.CameraInfo ();   android.hardware.Camera。getCameraInfo (cameraId信息);   int旋转=活动。getWindowManager ()。getDefaultDisplay ()。getRotation ();   int度=0;   开关(旋转){   案例Surface.ROTATION_0:   度=0;   打破;   案例Surface.ROTATION_90:   度=90;   打破;   案例Surface.ROTATION_180:   度=180;   打破;   案例Surface.ROTATION_270:   度=270;   打破;   }   int结果;   如果信息。面对==Camera.CameraInfo.CAMERA_FACING_FRONT) {   结果=(信息。定位+ % 360度);   结果=(360 -)% 360;//补偿镜子   其他}{//后面的   结果=(信息。取向- 360度+ 360)%;   }   mOrienta=结果;//该值有其它用途   相机。setDisplayOrientation(结果);   }      

详解android人脸检测你一定会遇到的坑