作者为Jack__0023


1、背景

最近甲方提出个东西,希望能够检测到是否有人观看过我们投放的内容,那么这种的话,在我看来只需要能粗糙检测到人就可以了,那么也就不需要去使用opencv或者第三方SDK,直接使用Camera自带的提供检测功能即可。

bak:人脸检测不是人脸识别,识别还要对比,检测只是看看有没有人。

2、简介和代码区

2-1、简介区域

2-1-1、提供检测的类:其实源码里面已经有提供检测的类 android.media.FaceDetector(可以看源码或者自行百度一下)

2-1-2、注意事项:

2-1-2-1、android.media.FaceDetector 好像对检查的图片格式有要求,只能检测 RGB_565 格式的图片,所以如果没效果,注意是不是没注意格式

2-1-2-2、我是基于android 5.1的版本的,别的版本我没去测试,如果效果不好的话可以私信我

2-1-2-3、我是在 onPreviewFrame 方法里面实现的 (小字体的是帧数设置的方式)

如果嫌 帧数过多,你可以通过 Camera.Parameters 类的 getSupportedPreviewFpsRange() 方法 获取每秒的获取帧数区间(下面会有贴代码的),然后通过 Camera.Parameters 类的 setPreviewFpsRange() 方法 设置帧数区间,(setPreviewFrameRate 方法官方已经不建议使用了),可以看看 setPreviewFpsRange 说了什么

/**
* Sets the minimum and maximum preview fps. This controls the rate of
* preview frames received in {[@link]() PreviewCallback}. The minimum and
* maximum preview fps must be one of the elements from {[@link]()
* #getSupportedPreviewFpsRange}.
*
* [@param]() min the minimum preview fps (scaled by 1000).
* [@param]() max the maximum preview fps (scaled by 1000).
* [@throws]() RuntimeException if fps range is invalid.
* @see #setPreviewCallbackWithBuffer(Camera.PreviewCallback)
* @see #getSupportedPreviewFpsRange()
*/
public void setPreviewFpsRange(int min, int max) {
set(KEY_PREVIEW_FPS_RANGE, "" + min + "," + max);
}

大概的意思就是 设置最小和最大预览fps。这可以控制{@link PreviewCallback}中收到的预览帧的速率。最小和最大预览fps必须是{@ link#getSupportedPreviewFpsRange}中的元素之一。

比如想设置每秒为1到3,那么你要填入的是最小值1000和最大值3000(没错,数量*1000),虽然我 getSupportedPreviewFpsRange 里面是15000到20000,但是我设置为最大值最小值是3000,结果每秒是5张(也算满意吧)

2-2、代码区域

2-2-1、 帧数检查和设置区域

WindowManager manager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
Display display = manager.getDefaultDisplay();
Camera.Parameters param = mCamera.getParameters();
param.setPreviewSize(640, 480);
//帧数设置区域
param.setPreviewFpsRange(1000, 3000);
List range = param.getSupportedPreviewFpsRange();
Log.d("zhaojing", "range:" + range.size());
//帧数检查,一般会有2个值,第一个是最小,第二个是最大,你这里可以修改一下代码就好了
for (int j = 0; j < range.size(); j++) {
int[] r = range.get(j);
for (int k = 0; k < r.length; k++) {
Log.d("zhaojing", "r["+k+"]:"+r[k]);
}
}

2-2-2、 人脸检测区域 (这段代码可以继续优化的,例如每秒5帧,你可以再进行运算变成3帧之内,还有其他的性能优化,代码优化,这段是我写来测试的,就没注意很多)

@Override
public void onPreviewFrame(byte[] data, Camera camera) {
count++;
// Log.v("yaoxumin123456789", "onPreviewFrame| 来了" + count);
mCamera.addCallbackBuffer(data);
BitmapFactory.Options newOpts = new BitmapFactory.Options();
newOpts.inJustDecodeBounds = true;
YuvImage yuvimage = new YuvImage(data, ImageFormat.NV21, 640, 480, null);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
yuvimage.compressToJpeg(new Rect(0, 0, 640, 480), 100, baos);// 80--JPG图片的质量[0-100],100最高
byte[] rawImage = baos.toByteArray();
//将rawImage转换成bitmap
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.RGB_565;
Bitmap bitmap = BitmapFactory.decodeByteArray(rawImage, 0, rawImage.length, options);
//只有565格式才能被识别,这里进行人脸检测
Bitmap tmpBmp = bitmap.copy(Bitmap.Config.RGB_565, true);
FaceDetector faceDet = new FaceDetector(tmpBmp.getWidth(), tmpBmp.getHeight(), 10);
//用来填装人脸的个数
FaceDetector.Face[] faceList = new FaceDetector.Face[10];
int faceNumber = faceDet.findFaces(tmpBmp, faceList);
if (faceNumber > 0) {//识别到人脸了,该怎么做就看你的了少年
Log.v("yaoxumin", "识别到的人的数量为:" + faceNumber);
}
}

效果如图

android 能调用系统的人脸识别嘛 基于android系统的人脸检测_android 能调用系统的人脸识别嘛

基本上重要代码就在上面(人脸检测区域 )了,有问题都可以私聊我。