使用uniapp开发微信小程序的人脸采集功能/人脸识别功能

简介: 使用uniapp开发微信小程序的人脸采集功能/人脸识别功能

开发环境:

开发框架:uniapp

开发平台:微信小程序


标签和样式先上:

标签:


<template>
  <view class="page-content">
  <view class="containerV">
    <view class="headerV">
    <view class="top-tips1">
      <view>请将正对手机,头部匹配摄像区域</view>
    </view>
    <view class="top-tips2">
      为了捍卫你的不要脸,请拍摄本人头像
    </view>
    </view>
    <view class="contentV">
    <view class="mark"></view>
    <image v-if="tempImg" mode="widthFix" :src="tempImg" />
    <camera v-if='isAuthCamera' :device-position="devicePosition ?'front': 'back'" class="camera"
      flash="off" resolution='high' />
    <view v-show="!tempImg && tipsText" class="tipV">{{ tipsText }}</view>
    </view>
    <view class="footerV">
    <view style="width: 100%;">
      <view v-if="!tempImg" style="width: 100%;">
      <view class="privacyV">
        <view class="icon"></view>
        <view class="text">
        照片隐私<text @click="handleJumpSecurityClick">安全保障</text>中…
        </view>
      </view>
      <view class="bottom-tips-2">该照片作为你不要脸的铁证</view>
      <view class="take-photo-bgV">
        <!-- 图片上传 -->
        <view v-show="true" class="btn-change-upload" @click="handleChooseImage" />
        <!--拍照-->
        <view class="btn-take-photo" @click="handleTakePhotoClick" />
        <!-- 切换镜头 -->
        <view class="btn-change-camera" @click="handleChangeCameraClick" />
      </view>
      </view>
      <view class="confirmV" v-else>
      <view class="btn-cancel" @click="handleCancelClick">
        取消
      </view>
      <view class="btn-ok" @click="handleOkClick">
        确定
      </view>
      </view>
    </view>
    </view>
  </view>
  </view>
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
样式:
<style lang="scss" scoped>
  .page-content {
  width: 100%;
  height: 100%;
  .containerV {
    width: 100%;
    height: 100%;
    .headerV {
    .top-tips1 {
      margin-top: 60rpx;
      color: #1C1C1C;
      font-size: 36rpx;
      text-align: center;
    }
    .top-tips2 {
      margin-top: 20rpx;
      color: #00AAFF;
      font-size: 28rpx;
      text-align: center;
    }
    }
    .contentV {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 661rpx;
    margin-top: 30rpx;
    .tipV {
      bottom: 30rpx;
      position: absolute;
      line-height: 90rpx;
      padding-left: 24rpx;
      padding-right: 24rpx;
      max-width: calc(100vw - 50rpx * 2);
      text-align: center;
      font-size: 30rpx;
      background: #000000;
      opacity: 0.75;
      color: #FFFFFF;
      border-radius: 16rpx;
      overflow: hidden;
      white-space: nowrap;
      text-overflow: ellipsis;
      z-index: 5;
    }
    .camera {
      width: 100%;
      height: 100%;
    }
    .mark {
      position: absolute;
      left: 0;
      top: 0;
      z-index: 2;
      width: 750rpx;
      height: 100%;
      background: url("@/static/face/view_face_background.png") no-repeat center bottom;
      background-size: 750rpx 661rpx;
    }
    image {
      position: absolute;
      width: 100%;
      height: 100%;
      z-index: 3;
    }
    }
    .footerV {
    width: 100%;
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: center;
    .privacyV {
      padding-top: 30rpx;
      display: flex;
      flex-direction: row;
      align-items: center;
      justify-content: center;
      .text {
      font-size: 30rpx;
      color: #1C1C1C;
      text-align: center;
      line-height: 42rpx;
      margin-left: 15rpx;
      text {
        font-size: 30rpx;
        color: #00AAFF;
        text-align: center;
        line-height: 42rpx;
      }
      }
      .icon {
      width: 40rpx;
      height: 47rpx;
      background: url("@/static/face/icon_face_security.png") no-repeat;
      background-size: 100% auto;
      }
    }
    .bottom-tips-2 {
      margin-top: 20rpx;
      color: #999999;
      text-align: center;
      font-size: 26rpx;
    }
    .take-photo-bgV {
      width: 100%;
      margin-top: 30rpx;
      display: flex;
      flex-direction: row;
      align-items: center;
      justify-content: center;
      .btn-take-photo {
      // 由于左边没有按钮,所以左边要便宜更大,以便是拍照按钮居中
      margin: 0rpx 80rpx 0rpx 80rpx;
      width: 196rpx;
      height: 196rpx;
      background: url("https://pro-file-qn.ztjy61.com/1003020211103145058685NNR9vlTm.png") no-repeat;
      background-size: 100% auto;
      }
      .btn-change-upload {
      left: 130rpx;
      width: 80rpx;
      height: 80rpx;
      background: url("@/static/face/icon_face_upload_picture.png") no-repeat;
      background-size: 100% auto;
      }
      .btn-change-camera {
      right: 130rpx;
      width: 80rpx;
      height: 80rpx;
      background: url("@/static/face/icon_face_switch_cameras.png") no-repeat;
      background-size: 100% auto;
      }
    }
    .confirmV {
      margin: 200rpx 100rpx 0rpx 100rpx;
      display: flex;
      flex-direction: row;
      align-items: center;
      justify-content: space-between;
      .btn-cancel {
      font-size: 32rpx;
      color: #1C1C1C;
      }
      .btn-ok {
      font-size: 32rpx;
      color: #00AAFF;
      }
    }
    }
  }
  }
</style>


js逻辑:

关键点代码中已经注释



<script>
  export default {
  name: 'index',
  components: {
  },
  data() {
    return {
    tipsText: '', // 错误文案提示
    tempImg: '', // 本地图片路径
    cameraEngine: null, // 相机引擎
    devicePosition: false, // 摄像头朝向
    isAuthCamera: true, // 是否拥有相机权限
    }
  },
  onLoad(options) {
    this.initData()
  },
  methods: {
    // 初始化相机引擎
    initData() {
    // #ifdef MP-WEIXIN
    // 1、初始化人脸识别
    wx.initFaceDetect()
    // 2、创建 camera 上下文 CameraContext 对象
    this.cameraEngine = wx.createCameraContext()
    // 3、获取 Camera 实时帧数据
    const listener = this.cameraEngine.onCameraFrame((frame) => {
      if (this.tempImg) {
      return;
      }
      // 4、人脸识别,使用前需要通过 wx.initFaceDetect 进行一次初始化,推荐使用相机接口返回的帧数据
      wx.faceDetect({
      frameBuffer: frame.data,
      width: frame.width,
      height: frame.height,
      enablePoint: true,
      enableConf: true,
      enableAngle: true,
      enableMultiFace: true,
      success: (faceData) => {
        let face = faceData.faceInfo[0]
        if (faceData.x == -1 || faceData.y == -1) {
        this.tipsText = '检测不到人'
        }
        if (faceData.faceInfo.length > 1) {
        this.tipsText = '请保证只有一个人'
        } else {
        const {
          pitch,
          roll,
          yaw
        } = face.angleArray;
        const standard = 0.5
        if (Math.abs(pitch) >= standard || Math.abs(roll) >= standard ||
          Math.abs(yaw) >= standard) {
          this.tipsText = '请平视摄像头'
        } else if (face.confArray.global <= 0.8 || face.confArray.leftEye <=
          0.8 || face.confArray.mouth <= 0.8 || face.confArray.nose <= 0.8 ||
          face.confArray.rightEye <= 0.8) {
          this.tipsText = '请勿遮挡五官'
        } else {
          this.tipsText = '请拍照'
          // 这里可以写自己的逻辑了
        }
        }
      },
      fail: (err) => {
        if (err.x == -1 || err.y == -1) {
        this.tipsText = '检测不到人'
        } else {
        this.tipsText = err.errMsg || '网络错误,请退出页面重试'
        }
      },
      })
    })
    // 5、开始监听帧数据
    listener.start()
    // #endif
    },
    // 切换设备镜头
    handleChangeCameraClick() {
    this.devicePosition = !this.devicePosition;
    },
    // 图片上传
    handleChooseImage() {
    uni.chooseImage({
      count: 1,
      sizeType: ['original', 'compressed'],
      sourceType: ['album'],
      success: (res) => {
      if (res.errMsg === 'chooseImage:ok') {
        uni.showLoading({
        title: '照片上传中...'
        })
        console.log("===========:", res.tempFilePaths[0])
        this.handleOkClick()
      }
      },
      fail: (res) => {
      },
    });
    },
    // 拍照点击
    handleTakePhotoClick() {
    if (this.tipsText != "" && this.tipsText != "请拍照") {
      return;
    }
    uni.getSetting({
      success: (res) => {
      if (!res.authSetting['scope.camera']) {
        this.isAuthCamera = false
        uni.openSetting({
        success: (res) => {
          if (res.authSetting['scope.camera']) {
          this.isAuthCamera = true;
          }
        }
        })
      }
      }
    })
    this.cameraEngine.takePhoto({
      quality: "high",
      success: ({
      tempImagePath
      }) => {
      this.tempImg = tempImagePath
      console.log("=======tempImg:", this.tempImg)
      }
    })
    },
    // 点击确定上传
    handleOkClick() {
    uni.showLoading({
      mask: true,
      title: '校验中...'
    })
    // 更新人脸识别图片请求协议:传七牛图片链接    
    setTimeout(function() {
      uni.hideLoading()
      uni.showToast({
      icon: "none",
      title: "假装图片上传成功",
      duration: 2000,
      })
    }, 3000);
    },
    // 点击 - 取消上传
    handleCancelClick() {
    this.tempImg = ''
    },
    // 点击 - 人脸安全保障按钮
    handleJumpSecurityClick() {
    uni.showToast({
      icon: "none",
      title: "假装跳转人脸安全保障",
      duration: 2000,
    })
    },
  }
  }
</script>


拓展:

可以将图片上传至服务器,由服务器做人脸识别,这样功能就齐全了。


人脸采集


demo:

1、gitee:https://gitee.com/chenzm_186/face-detect-mini

2、csdn:https://download.csdn.net/download/weixin_38633659/85385944


相关文章
|
JSON 小程序 JavaScript
uni-app开发微信小程序的报错[渲染层错误]排查及解决
uni-app开发微信小程序的报错[渲染层错误]排查及解决
4935 7
|
小程序 JavaScript 前端开发
uni-app开发微信小程序:四大解决方案,轻松应对主包与vendor.js过大打包难题
uni-app开发微信小程序:四大解决方案,轻松应对主包与vendor.js过大打包难题
5372 1
|
JSON 安全 定位技术
微信附近人提取v3脚本, 微信附近人id提取技术插件,采集附近人wxid数据工具
本内容介绍微信“附近的人”功能的技术原理与实现方法,基于LBS服务,涉及位置模拟、协议分析及数据解析。通过修改GPS坐标或使用Frida等工具hook位置函数
|
人工智能 自然语言处理 小程序
技术小白如何利用DeepSeek半小时开发微信小程序?
通过通义灵码的“AI程序员”功能,即使没有编程基础也能轻松创建小程序或网页。借助DeepSeek V3和R1满血版模型,用户只需用自然语言描述需求,就能自动生成代码并优化程序。例如,一个文科生仅通过描述需求就成功开发了一款记录日常活动的微信小程序。此外,通义灵码还提供智能问答模式,帮助用户解决开发中的各种问题,极大简化了开发流程,让普通人的开发体验更加顺畅。
4241 11
技术小白如何利用DeepSeek半小时开发微信小程序?
|
小程序 Java 关系型数据库
weixin163基于微信小程序的校园二手交易平台系统设计与开发ssm(文档+源码)_kaic
本文介绍了一款基于微信小程序的校园二手物品交易平台的开发与实现。该平台采用Java语言开发服务端,使用MySQL数据库进行数据存储,前端以微信小程序为载体,支持管理员和学生两种角色操作。管理员可管理用户、商品分类及信息、交易记录等,而学生则能注册登录、发布购买商品、参与交流论坛等。系统设计注重交互性和安全性,通过SSM框架优化开发流程,确保高效稳定运行,满足用户便捷交易的需求,推动校园资源共享与循环利用。
|
小程序 JavaScript 前端开发
微信小程序开发全流程:从注册到上线的完整指南
这篇文章详细记录了微信小程序的完整开发到最终上线的每一个步骤。适合对小程序开发感兴趣的个人开发者或希望了解完整流程的学习者,涵盖了云开发、事件绑定、生命周期管理、组件使用等关键内容。
25562 14
|
小程序 关系型数据库 Java
weixin168“返家乡”高校暑期社会实践微信小程序设计与开发ssm(文档+源码)_kaic
本文探讨高校暑期社会实践微信小程序的开发与应用,旨在通过信息化手段提升活动管理效率。借助微信小程序技术、SSM框架及MySQL数据库,实现信息共享、流程规范和操作便捷。系统涵盖需求分析、可行性研究、设计实现等环节,确保技术可行、操作简便且经济合理。最终,该小程序可优化活动发布、学生信息管理和心得交流等功能,降低管理成本并提高工作效率。
|
JSON 缓存 小程序
微信小程序组件封装与复用:提升开发效率
本文深入探讨了微信小程序的组件封装与复用,涵盖组件的意义、创建步骤、属性与事件处理,并通过自定义弹窗组件的案例详细说明。组件封装能提高代码复用性、开发效率和可维护性,确保UI一致性。掌握这些技能有助于构建更高质量的小程序。
|
人工智能 小程序 搜索推荐
uni app下开发AI运动小程序解决方案
本文介绍了在小程序中实现AI运动识别的解决方案。该方案依托于UNI平台,通过高效便捷的插件形式,实现包括相机抽帧控制、人体识别、姿态识别等在内的多项功能,无需依赖后台服务器,大幅提高识别效率和用户体验。方案内置多种运动模式,支持自定义扩展,适用于AI健身、云上赛事、AI体测等多场景,适合新开发和存量改造项目。