在android打开照相机时自动会对焦,并且能自动识别人脸,这个是利用google自带的FaceDetector做人脸检测识别 下面就简单介绍一下Fade Detector 的用法

1,照相机的打开,拍照识别时首先对摄像头进行配置

a,将摄像头Camera和SurfaceView绑定具体,在百度一搜一大堆 ,具体代码如下

@Override
protected void onPostCreate(@Nullable Bundle savedInstanceState) {Log.e(TAG, "onPostCreate");super.onPostCreate(savedInstanceState);// Check for the camera permission before accessing the camera.  If the// permission is not granted yet, request permission.SurfaceHolder holder = surfaceView.getHolder();holder.addCallback(this);holder.setFormat(ImageFormat.NV21);
}

在surfaceHolder中 oncreate方法中打开摄像头

public void surfaceCreated(SurfaceHolder surfaceHolder) {Log.e(TAG, "surfaceCreated");//Find the total number of cameras availablenumberOfCameras    = Camera.getNumberOfCameras();Camera.CameraInfo cameraInfo=new Camera.CameraInfo();for (int i=0;i< Camera.getNumberOfCameras();i++){Camera.getCameraInfo(i,cameraInfo);if(cameraInfo.facing==Camera.CameraInfo.CAMERA_FACING_FRONT){if(cameraId==1)cameraId=i;}}mCamera=Camera.open(cameraId);Camera.getCameraInfo(cameraId,cameraInfo);if(cameraInfo.facing==Camera.CameraInfo.CAMERA_FACING_FRONT){mFaceView.setFront(true);}try{mCamera.setPreviewDisplay(surfaceView.getHolder());}catch (Exception e){e.printStackTrace();}
}

当surfaceView调用完onCreate 之后紧接着会回调 onSeurfaceChange()函数因此在次函数中继续做摄像头的一些初始化和配置

public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) {Log.e(TAG, "surfaceChanged");// We have no surface, return immediately:if (surfaceHolder.getSurface() == null) {return;}// Try to stop the current preview:try {mCamera.stopPreview();} catch (Exception e) {// Ignore...}configureCamera(width, height);setDisplayOrientation();setErrorCallback();// Create media.FaceDetectorfloat aspect=(float) previewHeight / (float) previewWidth;faceDetector=new FaceDetector(prevSettingWidth,(int)(prevSettingWidth*aspect),MAX_FACE);// Everything is configured! Finally start the camera preview again:startPreview();
}
public void configureCamera(int width,int height){Camera.Parameters parameters=mCamera.getParameters();// Set the PreviewSize and AutoFocus:setOptimalPreviewSize(parameters, width, height);setAutoFocus(parameters);// And set the parameters:mCamera.setParameters(parameters);
}private void setDisplayOrientation(){mDisplayRotation    = Utils.getDisplayRotation(FaceRGBAct.this);mDisplayOrientation = Utils.getDisplayOrientation(mDisplayRotation, cameraId);mCamera.setDisplayOrientation(mDisplayOrientation);if (mFaceView != null) {mFaceView.setDisplayOrientation(mDisplayOrientation);}
}private void setErrorCallback() {mCamera.setErrorCallback(mErrorCallback);
}private void setOptimalPreviewSize(Camera.Parameters cameraParameters,int width,int height){List<Camera.Size> previewSizes=cameraParameters.getSupportedPreviewSizes();float targetRatio=(float)width/height;Camera.Size previewSize=Utils.getOptimalPreviewSize(this,previewSizes,targetRatio);previewWidth   = previewSize.width;previewHeight  = previewSize.height;Log.e(TAG, "previewWidth" + previewWidth);Log.e(TAG, "previewHeight" + previewHeight);/*** Calculate size to scale full frame bitmap to smaller bitmap* Detect face in scaled bitmap have high performance than full bitmap.* The smaller image size -> detect faster, but distance to detect face shorter,* so calculate the size follow your purpose*/if (previewWidth / 4 > 360) {prevSettingWidth = 360;prevSettingHeight = 270;} else if (previewWidth / 4 > 320) {prevSettingWidth = 320;prevSettingHeight = 240;} else if (previewWidth / 4 > 240) {prevSettingWidth = 240;prevSettingHeight = 160;} else {prevSettingWidth = 160;prevSettingHeight = 120;}Log.i(TAG, "****************");Log.e(TAG, "previewWidth****" + prevSettingWidth);Log.e(TAG, "previewHeight****" + prevSettingHeight);cameraParameters.setPreviewSize(previewSize.width, previewSize.height);mFaceView.setPreviewWidth(previewWidth);mFaceView.setPreviewHeight(previewHeight);
}

关键点

onPreviewFrame回调函数,当摄像头设置好开始预览时,会不断的回调次函数,实时的将每次预览的数据通过该函数传传递回来,我们要获取图像只需要再次函数中获取就行,同时注意性能问题,因为次函数不断地会回调,因此不能做耗时的操作,需要开启子线程去处理即可,具体如下:

@Override
public void onPreviewFrame(byte[] bytes, Camera camera) {if(!isThreadWorking){if (counter == 0)start = System.currentTimeMillis();isThreadWorking=true;waitForFdetThreadComplete();detectThread=new FaceDetectThread(handler,this);detectThread.setData(bytes);detectThread.start();}
}
    private class FaceDetectThread extends Thread{private Handler         handler;private byte[]          data=null;private Context         context;private Bitmap          mBitmap;static final int        REFRESH_COMPLETE=0x1112;public FaceDetectThread(Handler handler, Context context) {this.context = context;this.handler = handler;}public void setData(byte[] data) {this.data = data;}@Overridepublic void run() {float aspect = (float)previewHeight / (float)previewWidth;int   w      = prevSettingWidth;int   h      = (int)(prevSettingWidth * aspect);Bitmap bitmap = Bitmap.createBitmap(previewWidth, previewHeight, Bitmap.Config.RGB_565);// face detection: first convert the image from NV21 to RGB_565YuvImage yuv = new YuvImage(data, ImageFormat.NV21,bitmap.getWidth(),bitmap.getHeight(),null);// TODO: make rect a member and use it for width and height values aboveRect rectImage = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());// TODO: use a threaded option or a circular buffer for converting streams?//see http://ostermiller.org/convert_java_outputstream_inputstream.htmlByteArrayOutputStream baout = new ByteArrayOutputStream();if (!yuv.compressToJpeg(rectImage, 100, baout)) {Log.e("CreateBitmap", "compressToJpeg failed");}BitmapFactory.Options bfo  = new BitmapFactory.Options();bfo.inPreferredConfig      = Bitmap.Config.RGB_565;bitmap                     = BitmapFactory.decodeStream(new ByteArrayInputStream(baout.toByteArray()), null, bfo);/*  Log.i(TAG, "bitmapWidth****" + bitmap.getWidth());Log.i(TAG, "bitmapHeight****" + bitmap.getHeight());
*/Bitmap bmp = Bitmap.createScaledBitmap(bitmap, 320, 240, false);/*  Log.i(TAG, "**********************************");Log.i(TAG, "bitmapWidth****" + bmp.getWidth());Log.i(TAG, "bitmapHeight****" + bmp.getHeight());*/float xScale = (float) previewWidth  / (float) prevSettingWidth;float yScale = (float) previewHeight / (float) h;Camera.CameraInfo info = new Camera.CameraInfo();Camera.getCameraInfo(cameraId, info);int rotate = mDisplayOrientation;//Log.e("***ortate***",rotate+"");if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT && mDisplayRotation % 180 == 0) {if (rotate + 180 > 360) {//Log.e("***ortate-180***",rotate+"");rotate = rotate - 180;} else//Log.e("***ortate+180***",rotate+"");rotate = rotate + 180;}switch (rotate) {case 90:bmp = ImageUtils.rotate(bmp, 90);xScale = (float) previewHeight / bmp.getWidth();yScale = (float) previewWidth  / bmp.getHeight();break;case 180:bmp = ImageUtils.rotate(bmp, 180);break;case 270:bmp = ImageUtils.rotate(bmp, 270);xScale = (float) previewHeight / (float) h;yScale = (float) previewWidth  / (float) prevSettingWidth;break;}/* Log.i(TAG, "%%%%%%%%%%%%%%%%%%%%%%");Log.i(TAG, "bitmapWidth****" + bmp.getWidth());Log.i(TAG, "bitmapHeight****" + bmp.getHeight());*/FaceApp.getInstance().getNetInfo().runOnThreadServer(Constant.DETECTED,bmp,mHandler);faceDetector = new FaceDetector(bmp.getWidth(), bmp.getHeight(), MAX_FACE);FaceDetector.Face[] fullResults = new FaceDetector.Face[MAX_FACE];faceDetector.findFaces(bmp, fullResults);for (int i = 0; i < MAX_FACE; i++) {if (fullResults[i] == null) {faces[i].clear();} else {PointF mid = new PointF();fullResults[i].getMidPoint(mid);mid.x *= xScale;mid.y *= yScale-0.5;float   eyesDis     = fullResults[i].eyesDistance() * xScale;float   confidence  = fullResults[i].confidence();float   pose        = fullResults[i].pose(android.media.FaceDetector.Face.EULER_Y);int     idFace      = Id;/*Rect rect = new Rect((int) (mid.x - eyesDis * 1.20f),(int) (mid.y - eyesDis * 0.10f),(int) (mid.x + eyesDis * 1.20f),(int) (mid.y + eyesDis * 1.85f));*/Rect rect = new Rect((int) (mid.x - eyesDis * 1.20f),(int) (mid.y - eyesDis * 0.30f),(int) (mid.x + eyesDis * 1.20f),(int) (mid.y + eyesDis * 1.85f));/*** Only detect face size > 100x100*/if (rect.height() * rect.width() > 100 * 100) {for (int j = 0; j < MAX_FACE; j++) {float   eyesDisPre  = faces_previous[j].eyesDistance();PointF midPre      = new PointF();faces_previous[j].getMidPoint(midPre);RectF rectCheck = new RectF((midPre.x - eyesDisPre * 1.5f),(midPre.y - eyesDisPre * 1.15f),(midPre.x + eyesDisPre * 1.5f),(midPre.y + eyesDisPre * 1.85f));if (rectCheck.contains(mid.x, mid.y) &&(System.currentTimeMillis() - faces_previous[j].getTime()) < 1000) {idFace = faces_previous[j].getId();break;}}if (idFace == Id)Id++;faces[i].setFace(idFace, mid, eyesDis, confidence, pose, System.currentTimeMillis());faces_previous[i].set(faces[i].getId(), faces[i].getMidEye(),faces[i].eyesDistance(), faces[i].getConfidence(),faces[i].getPose(), faces[i].getTime());//// if focus in a face 5 frame -> take picture face display in RecyclerView// because of some first frame have low quality//if (facesCount.get(idFace) == null) {facesCount.put(idFace, 0);} else {int count = facesCount.get(idFace) + 1;if (count <= 5)facesCount.put(idFace, count);//// Crop Face to display in RecylerView///* if (count == 5) {mBitmap = ImageUtils.cropFace(faces[i], bitmap, rotate);if (mBitmap != null) {handler.post(new Runnable() {public void run() {//FaceObServernotice.getInstance().notifyObserver(0,mbitmap);mHandler.sendEmptyMessageDelayed(REFRESH_COMPLETE, 0);
//                                            imagePreviewAdapter.add(mbitmap);}});}}*/}}}}handler.post(new Runnable() {public void run() {//send face to FaceView to draw rectmFaceView.setFaces(faces);//calculate FPSend = System.currentTimeMillis();counter++;double time = (double) (end - start) / 1000;if (time != 0)fps = counter / time;mFaceView.setFPS(fps);if (counter == (Integer.MAX_VALUE - 1000))counter = 0;isThreadWorking = false;}});}/*private Handler         mHandler = new Handler() {public void handleMessage(android.os.Message msg) {switch (msg.what) {case REFRESH_COMPLETE:if(ScanApp.scanInfo==null){*//* Intent intent = new Intent(FaceDetectRGBActivity.this, MainAct.class);startActivity( intent);*//*setResult(RESULT_OK);}else{Intent intent = new Intent(FaceDetectRGBActivity.this, FaceVerifyAct.class);ByteArrayOutputStream output = new ByteArrayOutputStream();//初始化一个流对象//把bitmap100%高质量压缩 到 output对象里mbitmap.compress(Bitmap.CompressFormat.PNG, 100, output);//result = output.toByteArray();//转换成功了  result就是一个bit的资源数组intent.putExtra("bitmap",output.toByteArray());startActivity(intent);}FaceDetectRGBActivity.this.finish();break;}}};*/}

注意再此处将图片压缩为320* 240 具体可根据自己的摄像头来调试,

最后再交个FaceDetector 检测处理

具体可参照如下代码,此代码包含华为云人脸识别活体检测等功能 去掉及原生的人脸识别

https://github.com/lvzongning/android-FaceDetected/tree/5dcb9ed49387b0bbc59fd6eaad61c471c247dea8

android 原生人脸检测相关推荐

  1. 算法移植优化(三)android dlib 人脸检测使用

    android dlib 人脸检测使用 一.编译阶段 1.在cmakelist.txt中加入: include(src/main/cpp/dlib/cmake) 然后再链接dlib库就可以了: tar ...

  2. android关闭人脸检测功能,【Android知识】录像预览模式下打开人脸检测

    开发的一款高通平台Android 9.0基于Camera2实现的预览界面通过侧键实现拍照,录像等功能的应用中,预览界面默认是采用的原生的VideoModule.java界面实现,测试发现设置中开启人脸 ...

  3. android之人脸检测FaceDetector||人体?

    1. http://blog.csdn.net/shaojie519/article/details/6729333 FaceDetector检测到的并不是人的全脸,而只是双眼. 实际测试中,发现图片 ...

  4. 人脸检测和行人检测2:YOLOv5实现人脸检测和行人检测(含数据集和训练代码)

    人脸检测和行人检测2:YOLOv5实现人脸检测和行人检测(含数据集和训练代码) 目录 人脸检测和行人检测2:YOLOv5实现人脸检测和行人检测(含数据集和训练代码) 1. 前言 2. 人脸检测和行人检 ...

  5. Android原生 通过图片检测到人脸

    Android 使用原生库实现人脸检测 /*** 绘制脸部方框的view,实测发现返回的脸部数据中没有具体的眼睛,嘴巴等数据*/ public class DrawFacesView extends ...

  6. Android中的人脸检测入门

    原文作者 : Paul Trebilcox-Ruiz 译文出自 : 开发技术前线 www.devtf.cn 转载声明: 本译文已授权开发者头条享有独家转载权,未经允许,不得转载! 译者 : Langl ...

  7. Android人脸检测方案汇总

    因为要用到Android本地相机人脸检测,检测到人脸再做进一步处理.这里只记录从相机中实时检测人脸功能.本文只是一个简单的汇总. 1. Android原生FaceDetectionListener 部 ...

  8. Android实现人脸识别(人脸检测)初识

    title: Android实现人脸识别(人脸检测)初识 categories: Android tags: 人脸识别 人脸检测 相机处理 date: 2020-05-21 11:35:51 介绍 本 ...

  9. Android NDK开发——人脸检测与静默活体检测

    前言 1.开发环境是win10,IDE是Android studio 北极狐,用到的库有NCNN,OpenCV. 2.NCNN库可以用官方编译好的releases库,也可以按官方文档自己编译. 3.O ...

最新文章

  1. java性能保障技术_狙击P7!阿里大佬亲授“Java性能调优技术宝典”,太完整了!...
  2. android Button 监听的几种方式
  3. 计算机系统的优化项目,电脑开机显示时间后有个优化项目是什么意思
  4. ITNEXT :“这个项目可能会改变我们使用 Kubernetes 的方式”
  5. 第19讲:Pyppeteer 爬取实战
  6. [C++面试题]之冒泡排序
  7. 计算bed区间gc含量,碱基深度等
  8. 安徽计算机软件工程学院,安徽软件工程专业大学排名
  9. Web Directions South 2012的四个大创意
  10. linux传输系统架构,Linux后端程序成长关键技术——底层体系结构
  11. 配置系统初始化失败0 x84b10001当在Windows上安装SQL Server
  12. 实现 | 朴素贝叶斯模型算法研究与实例分析
  13. Segmentation fault (core dumped) 和double free or corruption (out)Aborted (core dumped)
  14. android字体加横线
  15. 大疆云台如何使用华为mate20pro_大疆灵眸手机云台3软件升级 完美支持Mate30系列...
  16. 在k8s上部署cerebro访问集群外部署的es
  17. python中如何导入torch_[PyTorch入门]之数据导入与处理
  18. LKJ国锂科技一场影响人类生活的大变革
  19. 让企业用上金融合规专有云,腾讯云专有云TCE矩阵来支招儿!
  20. 如何祛痘?美丽时光小编分享自己的战痘经历

热门文章

  1. oracle表变为分区表,「分区表」oracle中将普通表变更为分区表 - 金橙教程网
  2. YoloV7训练最强操作教程.
  3. 扫地机器人杂牌的怎么样_扫地机器人入坑测评不同牌子
  4. php发送http请求重启艾泰路由器(非动态加密验证的路由器)
  5. javascript计算倒计时
  6. 每日一博 - 闲聊“突发流量”的应对之道
  7. js: 添加事件监听addEventListener、移除事件监听removeEventListener
  8. 【Spring Boot论坛项目实战】3、开发社区核心功能
  9. Linux常用的四种配置网卡方式
  10. 海量遥感数据处理与GEE云计算