这段时间再做安防相关的硬件设备定制,涉及到了小区的业主和流动人员人员登记、闸机管理和小区内部摄像头等等。
这里面用到了人脸检测、识别,人脸检测用了虹软的算法,虹软的文档还是比较全的这里不多做介绍。这里主要说下android自带的人脸检测和人脸框的绘制。

先来看看人脸识别框特效:

这个例子使用Camera API实现的并不是Camera2 API,原因是发现2019年了还有的设备居然不支持Camera2的人脸识别,为了通用就用了Camera API。
以下为主要代码
上代码:
1、下来是处理人脸检测回调方法

                    //进行相机初始化cameraHelper = CameraControllerHelper.Builder().previewViewSize(Point(camera_surfaceview.measuredWidth, camera_surfaceview.measuredHeight)).rotation(mBaseAc.windowManager.defaultDisplay.rotation).specificCameraId(cameraId).isMirror(isMirror()).previewOn(camera_surfaceview).cameraListener(this@CameraFaceFm)//设置人脸检测回调方法.setFaceDetectionListener(object : Camera.FaceDetectionListener {override fun onFaceDetection(p0: Array<out Camera.Face>?, p1: Camera?) {if (faceRectView != null) {faceRectView.clearFaceInfo()faceRectView.addFaceInfo(p0!!.toList())}}}).build()val p = getScreenPoint()DrawFaceHelper.cameraWidth = p.x.toFloat()DrawFaceHelper.cameraHeight = p.y.toFloat()DrawFaceHelper.isBackCameraId = isBackCameraId()cameraHelper.init()cameraHelper.start()

2、相机的启动、参数设置和人脸检测

if (mCamera != null) {return}//若指定了相机ID且该相机存在,则打开指定的相机if (specificCameraId != null) {mCameraId = specificCameraId!!} else {//相机数量为2则打开1,1则打开0,相机ID 1为前置,0为后置mCameraId = Camera.getNumberOfCameras() - 1}//没有相机if (mCameraId == -1) {cameraListener?.onCameraError(Exception("camera not found"))return}if (mCamera == null) {mCamera = Camera.open(mCameraId)}displayOrientation = getCameraOri(rotation)mCamera!!.setDisplayOrientation(displayOrientation)try {val parameters = mCamera!!.parametersparameters.previewFormat = ImageFormat.NV21//预览大小设置previewSize = parameters.previewSizeval supportedPreviewSizes = parameters.supportedPreviewSizesif (supportedPreviewSizes != null && supportedPreviewSizes.size > 0) {previewSize = currentPreviewSize}parameters.setPreviewSize(previewSize!!.width, previewSize!!.height)pictureSize = parameters.pictureSizeval supportedPicviewSizes = parameters.supportedPreviewSizesif (supportedPicviewSizes != null && supportedPicviewSizes.size > 0) {pictureSize = currentPictureSize}parameters.setPictureSize(pictureSize!!.width, pictureSize!!.height)//对焦模式设置val supportedFocusModes = parameters.supportedFocusModesif (supportedFocusModes != null && supportedFocusModes.size > 0) {if (supportedFocusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {parameters.focusMode = Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE} else if (supportedFocusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) {parameters.focusMode = Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO} else if (supportedFocusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {parameters.focusMode = Camera.Parameters.FOCUS_MODE_AUTO}}setCameraParameters(parameters)mCamera!!.setPreviewTexture(previewDisplayView!!.getSurfaceTexture())mCamera!!.setPreviewCallback(this)mCamera!!.startPreview()//注意这段,这里是设置人脸检测监听和启动if (mFaceDetectionListener != null) {mCamera!!.setFaceDetectionListener(mFaceDetectionListener)mCamera!!.startFaceDetection()}if (autoFocusCallback != null) {mCamera!!.autoFocus(autoFocusCallback)}cameraListener?.onCameraOpened(mCamera!!, mCameraId, displayOrientation, isMirror)} catch (e: Exception) {if (cameraListener != null) {cameraListener.onCameraError(e)} else {e.printStackTrace()}}}

启动相机这块就不多做介绍,以为网上现成的文档还是很多的。

##下来才是重头戏!!!

3、在FaceRectView的onDraw方法内进行人脸框显示

    override fun onDraw(canvas: Canvas) {super.onDraw(canvas)if (faceRectList != null && faceRectList.isNotEmpty()) {DrawFaceHelper.drawFaceRect(canvas, faceRectList[0].rect, color, 3)//不断进行刷新,实现人脸框动画更新postInvalidate()} else {DrawFaceHelper.resetTimerInfo()}}

这里需要说明下,相机返回的Face信息里面的Rect的坐标并不是view的真实坐标,这个需要转换。转换方式见 android人脸检测点位置转换

4、用DrawFaceHelper中的drawFaceRect绘制人脸框

/*** 绘制数据信息到view上,若 [DrawInfo.getName] 不为null则绘制 [DrawInfo.getName]** @param canvas            需要被绘制的view的canvas* @param drawInfo          绘制信息* @param color             rect的颜色* @param faceRectThickness 人脸框线条粗细*/fun drawFaceRect(canvas: Canvas?, drawInfo: Rect?, color: Int, faceRectThickness: Int) {var displayOrientation: Int = if (isBackCameraId) { 90 } else { 270 }//将返回的人脸信息,转为view可识别的信息val matrix = CameraUtils.prepareMatrix(isBackCameraId, displayOrientation, cameraWidth.toInt(), cameraHeight.toInt())val rectF = RectF(drawInfo)matrix.mapRect(rectF)if (canvas == null || drawInfo == null) {return}if (timer == null) {initTimerInfo()}val paint = Paint()paint.style = Paint.Style.STROKE  //设置空心paint.strokeWidth = faceRectThickness.toFloat()val spic = 100val rect = Rect(rectF.left.toInt() - spic, rectF.top.toInt() - spic, rectF.right.toInt() + spic, rectF.bottom.toInt() + spic)val width = rect.right - rect.leftval height = rect.bottom - rect.top//比较小的设置为半径val radius = if (height > width) { width / 2 } else { height / 2 }val cx = (rect.left + rect.right) / 2val cy = (rect.top + rect.bottom) / 2//绘制遮罩层val maskPaint = Paint()//整个相机预览界面进行遮罩,透明度用来设置遮罩半透明canvas.saveLayerAlpha(0f, 0f, cameraWidth, cameraHeight, maskAlpha, Canvas.ALL_SAVE_FLAG)maskPaint.color = Color.BLACK//整个相机预览界面进行遮罩canvas.drawRect(Rect(0, 0, cameraWidth.toInt(), cameraHeight.toInt()), maskPaint)//重叠区域进行处理//只在源图像和目标图像不相交的地方绘制【源图像】,相交的地方根据目标图像的对应地方的alpha进行过滤,//目标图像完全不透明则完全过滤,完全透明则不过滤maskPaint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_OUT)maskPaint.color = Color.BLACKcanvas.drawCircle(cx.toFloat(), cy.toFloat(), radius.toFloat(), maskPaint)//自定义人脸框样式paint.flags = Paint.ANTI_ALIAS_FLAG  //抗锯齿paint.color = color//设置正方形,以便下面设置弧形为圆的弧形rect.left = cx - radiusrect.top = cy - radiusrect.right = cx + radiusrect.bottom = cy + radiusval rectF0 = getRectF(faceOffset0, rect)paint.strokeWidth = 4fpaint.alpha = faceAlpha0canvas.drawArc(rectF0, getStartAngle(faceStartAngle0, false), faceSweepAngle0, useCenter, paint)val rectF1 = getRectF(faceOffset1, rect)paint.strokeWidth = 8fpaint.alpha = faceAlpha1canvas.drawArc(rectF1, getStartAngle(faceStartAngle1, true), faceSweepAngle1, useCenter, paint)val rectF2 = getRectF(faceOffset2, rect)paint.strokeWidth = 3fpaint.alpha = faceAlpha2canvas.drawArc(rectF2, getStartAngle(faceStartAngle2, false), faceSweepAngle2, useCenter, paint)paint.alpha = faceAlpha3val rectF3 = getRectF(faceOffset3, rect)paint.strokeWidth = 9fcanvas.drawArc(rectF3, getStartAngle(faceStartAngle3, true), faceSweepAngle3, useCenter, paint)val rectF4 = getRectF(faceOffset3, rect)paint.strokeWidth = 9fcanvas.drawArc(rectF4, getStartAngle(faceStartAngle4, true), faceSweepAngle4, useCenter, paint)}/*** 设置圆环偏移量* @param startAngle 角度* @param clockwise  是否顺时针*/private fun getStartAngle(startAngle:Float, clockwise: Boolean):Float {val angle = if (clockwise) { startAngle + timeIndex } else { startAngle - timeIndex}return angle % 360}private fun getRectF(offset: Int, rect: Rect): RectF {val rectF = RectF(rect)rectF.left = rectF.left - offsetrectF.top = rectF.top - offsetrectF.right = rectF.right + offsetrectF.bottom = rectF.bottom + offsetreturn rectF}

这就是实现的大致流程。

代码里面只支持了显示一张人脸的检测方式。如有需要显示多张人脸的话请各位童鞋开动脑力自己解决!
完整代码请戳这里:FaceCamera

Android人脸检测功能和检测特效相关推荐

  1. android 检测过程,Android 系统对permision的检测过程

    Android 系统对permision的检测过程 RK3288 5.1 中以太网设置静态IP 对permission的检测 简略的调用过程如下: frameworks\opt\net\etherne ...

  2. Android内存泄漏的检测流程、捕捉以及分析

    https://blog.csdn.net/qq_20280683/article/details/77964208 Android内存泄漏的检测流程.捕捉以及分析 简述: 一个APP的性能,重度关乎 ...

  3. android电池容量查看器,Android AccuBattery(电池损耗检测软件)V1.2.5 安卓专业版

    Android AccuBattery(电池损耗检测软件)是一款功能实用的提供安卓手机电池保持最佳状态而设计的电池管家软件.AccuBattery科学地维护电池健康,显示电池使用情况以及测量电池容量( ...

  4. Android 第三方SDK的检测与提取

    Android 第三方SDK的检测一直是研究领域的热点与难点: 目前检测Android第三方SDK的方法主要分为两类 下手的目标也主要存在三点 首先说检测的点: AndroidManifest.xml ...

  5. Android之——模拟实现检测心率变化的应用实例

    Android之--模拟实现检测心率变化的应用实例 当今,市面上有了一些可以通过Android应用来检测病人心率,血压,体温,等等,一系列方便人们日常生活的Android手机应用.那么,这些实用的手机 ...

  6. 基于android的检测心率,基于android手机的血氧饱和度检测

    67 基于 android手机的血氧饱和度检测 许方成,赵曙光,杨 峰,黄佳佳 (东华大学信息科学与技术学院,上海 201620) 摘要:血氧饱和度是人体健康状况的标准指标,连续记录血氧饱和度可以预测 ...

  7. Android原生开发--模拟器检测工具包

    Android原生开发–模拟器检测工具包 模拟器检测工具包使用例子 //使用方法 Context context=getBaseContext(); boolean isEmn= EasyProtec ...

  8. Android实现佩戴安全帽检测和识别(含Android源码)

    Android实现佩戴安全帽检测和识别(含Android源码) 目录 Android实现佩戴安全帽检测和识别(含Android源码) 1. 前言 2. 佩戴安全帽检测和识别的方法 (1)基于目标检测的 ...

  9. android 活体检测方案,一种基于人脸识别认证的Android红外双目活体检测的制作方法...

    本发明涉及人脸识别领域,具体涉及一种基于人脸识别认证的Android红外双目活体检测. 背景技术: 在目前的利用红外线实现双目活体检测的技术中,普通红外双目,能够同时实时采集近红外和可见光两种图像,并 ...

  10. android edittext字数显示不全,Android的EditText字数检测和限制解决办法

    Android的EditText字数检测和限制解决办法 控件EditText在Android布局中经常用到,对EditText中输入的内容也经常需要进行限制,我们可以通过TextWatcher去观察输 ...

最新文章

  1. 3项目在ie11浏览器打不开_Chrome/Safari都输了:新Edge浏览器率先实现100%支持HTML5...
  2. C#设计技巧总结 网上转贴
  3. 一个C#睡觉前的夜晚
  4. Object-C 打开工程,选择模拟起时,提示no scheme
  5. dtree 无法出现横向滚动条 (clip)
  6. PIL中分离通道发生“AttributeError: 'NoneType' object has no attribute 'bands'”
  7. 还是动态生成一个控件
  8. linux系统运行pbs出现ntf,Linux系统启动故障修复
  9. 织梦cms响应式站长导航分类网站模板(自适应手机版)
  10. linux下下载fnl数据,NCEP再分析资料FNL数据在windows平台用cygwin批量下载方法
  11. [导入]SQL Server 索引基础知识(4)----主键与聚集索引
  12. IE浏览器9.0与王码五笔不兼容的问题
  13. Windows的SVN的下载和安装
  14. 红黑树(四)之 C++的实现 http://www.cnblogs.com/skywang12345/p/3624291.html?utm_source=tuicoolutm_medium=refe
  15. HTML 限制文本框只能输入特定字符(比如数字 onkeyup+onafterpaste)
  16. 基于android的手机位置系统,如何打造定位更精准的手机?基于Android系统的SDK方案了解一下~...
  17. 使用ffmpeg进行音频采样率转换
  18. 谷歌浏览器网盘倍速播放
  19. 初学媒体软件时的一些鼠绘作品
  20. 时序预测构建ARIMA模型时报错:NotImplementedError: statsmodels.tsa.arima_model.ARMA and statsmodels.tsa.arima_

热门文章

  1. 马哥教育SRE笔记【作业】week02
  2. STM32F4+W25Q64实现一个U盘
  3. python 什么是原类_python中什么是类
  4. 这是我见过最好的唐诗,而且通俗易懂2
  5. UC刘兰奇极速版制动刷金币
  6. minio更换端口启动
  7. linux kernel配置调试方法
  8. 【Windows】如何关闭svchost,win10系统svchost下载占网速,无缘无故下载软件
  9. 用python根据年份判断生肖_C#中根据年份判断十二生肖
  10. apkeditor pro_APK编辑器 APK Editor Pro v1.15.0 + ApkModifier v3.6