小程序人脸分析

公司的业务需求是用户在使用某个功能前,必须使用人脸识别,确保当前使用人是用户本人,防止某些功能乱用。后端用的是腾讯的人脸识别方案,这里只是前端的识别代码,保证人脸剧中,大小合适,有一个人脸以上

小程序代码,主要利用的是wx.createVKSession这个API来实现,样式部分可自行修改

这部分代码只是小程序前端识别的代码,真正的人脸比对代码是在后端,需要前端识别到人脸后上传到后端进行比对。
部分位置可根据业务需求要样式来修改,这里只是我自己调整的位置

wxml

html 复制代码
<view class="title">{{verifyText}}</view>
<view class="container">
<image src="{{faceImg}}" wx:if="{{faceImg}}" class="faceImg" mode="widthFix"/>
  <camera class="camera" device-position="front"  flash="off"></camera>
</view>

js部分

javascript 复制代码
let listener = null;
let videoCtx = null;
let VKSession = null;
let faceVerifyTime = null; //面容验证倒计时

Page({
  data: {
    faceImgHeight: 314,
    faceImgWidth: 314,
    face: {
      origin: {
        x: 0,
        y: 0
      },
      size: {
        width: 0,
        height: 0
      },
      points:[]
    },
    verifyText:"请移动面容到框内",
    isCentre:false, //是否面容在正中间
    startVerify:false, //是否正在验证
    faceImg:"", //面容图片地址
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad() {
    this.getAuthSetting(); //获取权限
    
    this.initFaceVerify()
  },
  getAuthSetting(){
    wx.getSetting({
      success :(res)=> {
        if(!res.authSetting['scope.camera']){
          wx.showModal({
            title: '请允许获取摄像头权限',
            showCancel:false,
            complete: (modalRes) => {
              if (modalRes.confirm) {
                wx.openSetting({
                  success:(settingRes)=>{
                    if(!settingRes.authSetting['scope.camera']){
                      this.getAuthSetting()
                    }else{
                      wx.navigateBack()
                    }
                  }
                })
              }
            }
          })
        }
      }
    })
  },
  initFaceVerify(){
    videoCtx = null;
    listener=null;
    VKSession=null;
    videoCtx = wx.createCameraContext();
    let count = 0;
    listener = videoCtx.onCameraFrame((frame) => {
      count++;
      if (count === 5) {
        this.detectFace(frame);
        count = 0;
      }
    });
    VKSession = wx.createVKSession({
      version: 'v1',
      track: {
        plane: {
          mode: 1
        },
        face: {
          mode: 2
        }
      }
    });
    VKSession.on('updateAnchors', (anchors) => {
      // 有面容
      console.log(anchors,'有面容')
     
      if(this.data.startVerify){
        return;
      }
      let anchor = anchors[0];
        this.setData({
          face: {
            points: anchor.points,
            origin: anchor.origin,
            size: anchor.size
          }
        },()=>{
          this.isFaceCentered()
        })
    })
    VKSession.on('removeAnchors', (anchors) => {
      // 面容消失
      if(this.data.startVerify){
        return;
      }
      this.setData({
        verifyText:'请移动面容到框内',
        isCentre:false,
        face:{}
      },()=>{
        clearTimeout(faceVerifyTime)
        faceVerifyTime = null;
      })
    })
    setTimeout(() => {
      // 直接开始
      this.handleStart()
    }, 500);
  },
  onUnload() {
    VKSession.destroy();
  },
  picture(){
    this.setData({
      startVerify:true
    },()=>{
      clearTimeout(faceVerifyTime)
      faceVerifyTime = null;
      videoCtx.takePhoto({
        quality:'original',
        success:(e)=>{
          //上传照片接口,图片换成远端url地址 自行替换
          uploadImage(e.tempImagePath).then((res)=>{
            this.setData({
              faceImg:res
            })
            wx.showLoading({
              title: '正在验证',
            })

            try {
              // 执行后端分析人脸
              api({
                img:res
              }).then((writeoffRes) => {
                //识别成功
                //自行处理识别成功结果
              }).catch(err => {
                wx.hideLoading();
                wx.showModal({
                  title: err.msg,
                  showCancel:false,
                  confirmText:'重新核验',
                  complete: (res) => {
                    if (res.confirm) {
                      this.setData({
                        startVerify:false,
                        faceImg:"",
                        verifyText:'请移动面容到框内',
                        isCentre:false,
                        face:{}
                      },()=>{
                        this.handleStart()
                      })
                    }
                  }
                })
              })
            } catch (error) {
              console.log(error)
            }
          }).catch(()=>{
            this.setData({
              startVerify:false,
              faceImg:"",
              verifyText:'请移动面容到框内',
              isCentre:false,
              face:{}
            },()=>{
              this.handleStart()
              wx.showToast({
                title: '网络连接失败,请重试',
              })
            })
          })
        }
      })
    })
    
  },
  handleStart() {
    VKSession.start((errno) => {
      console.warn('VKSession.start errno', errno);
    });
    listener.start();
  },
  handleStop() {
    listener.stop({
      complete: (res) => {
        console.warn('listener.stop', res);
      }
    });
    VKSession.stop();
  },
  async detectFace(frame) {
    // 获取面容
      VKSession.detectFace({
        frameBuffer: frame.data,
        width: frame.width,
        height: frame.height,
        scoreThreshold: 0.8,
        sourceType: 0,
        modelMode: 2
      });
  },
  isFaceCentered() {
    // 判断面容是否在中间
    if(!this.data.face.points){
      return;
    }
    let points = this.data.face.points[43]; //位置
    let size = this.data.face.size; //大小
    if(points.x>0.65||points.x<0.4||points.y>0.65||points.y<0.35){
      this.setData({
        verifyText:'请移动面容到框内',
        isCentre:false,
        face:{}
      },()=>{
        clearTimeout(faceVerifyTime)
        faceVerifyTime = null;
      })
      return
    }else if(size.width>0.95||size.width<0.32){
      this.setData({
        verifyText:'请移动面容显示完整面容',
        isCentre:false,
        face:{}
      },()=>{
        clearTimeout(faceVerifyTime)
        faceVerifyTime = null;
      })
      return
    }
    this.setData({
      verifyText:'请保持不动',
      isCentre:true
    },()=>{
      this.verifyCentre()
    })
  },
  verifyCentre(){
    // 开始验证面容
    if(faceVerifyTime||this.data.startVerify){
      return
    }else{
      faceVerifyTime = setTimeout(() => {
        if(this.data.isCentre){
            this.handleStop()
            this.picture()
        }else{
          clearTimeout(faceVerifyTime)
          faceVerifyTime = null;
        }
      }, 1500);
    }
  }
})

style

css 复制代码
.container {
  position: relative;
  padding: 200rpx 0;
}
.title{
  position: absolute;
  width: 100%;
  text-align: center;
  padding-top: 100rpx;
  font-size: 36rpx;
}
.camera{
  width: 600rpx;
  height: 600rpx;
  border-radius: 50% 50%;
  margin: 0 auto;
}
.faceImg{
  width: 600rpx;
  height: 600rpx;
  border-radius: 50% 50%;
  margin: 0 auto;
  position: absolute;
  z-index: 999;
}
相关推荐
技术闲聊DD6 小时前
小程序原生-利用setData()对不同类型的数据进行增删改
小程序
康康爹6 小时前
uniapp 小程序,登录上传头像昵称页面处理步骤
小程序·uni-app
小雨cc5566ru6 小时前
小程序 uniapp+Android+hbuilderx体育场地预约管理系统的设计与实现
android·小程序·uni-app
DK七七11 小时前
【PHP陪玩系统源码】游戏陪玩系统app,陪玩小程序优势
前端·vue.js·游戏·小程序·php·uniapp
正小安20 小时前
MobX-Miniprogram:微信小程序的状态管理利器
微信小程序·小程序
GDAL1 天前
软考鸭微信小程序:助力软考备考的便捷工具
微信小程序·小程序
技术闲聊DD1 天前
小程序原生-列表渲染
小程序
2401_844137951 天前
JAVA智慧社区系统跑腿家政本地生活商城系统小程序源码
微信·微信小程序·小程序·生活·微信公众平台·微信开放平台
程序员入门进阶1 天前
4S店4S店客户管理系统小程序(lw+演示+源码+运行)
小程序
光影少年1 天前
Vue Mini基于 Vue 3 的小程序框架
前端·vue.js·小程序