vue3 调取摄像头 人脸识别 获取人脸特征值

1、创建视频画布标签

 <div class="photo">

      <video  ref="video" autoplay />

      <canvas ref="canvas" />

   </div>

2、获取标签 定义数据  

安装face-api.js

 npm install face-api.js

下载模型,用于对比
下载地址:face-api.js使用模型
下载后放置于public中 

// 引入face-api.js中的方法

import {

  detectAllFaces,

  TinyFaceDetectorOptions,

  bufferToImage,

  detectSingleFace,

  nets,

  matchDimensions,

  resizeResults,

  draw,

  SsdMobilenetv1Options,

  Box,

} from 'face-api.js'

const options = new SsdMobilenetv1Options({

  // 最小置信阈值

  // 默认值:0.5

  minConfidence: 0.5,

})

const title = ref('人脸识别') //  初始化title

const canvas = ref('canvas') // 图像画布

const ctx = document.createElement('canvas').getContext('2d')

const video = ref('video') // 视频元素

let imgUrl = reactive<string | null>(null) // 照片路径

const stream = ref(null) // 当前流

const getUserMediaFail = ref(false) // 获取用户媒体失败

const boxObject = ref({ width: 100, height: 100 }) // 初始化box

const viewFinderBox = ref({

  topLeft: {

    x: 0,

    y: 0,

  },

  topRight: {

    x: 0,

    y: 0,

  },

  bottomLeft: {

    x: 0,

    y: 0,

  },

  bottomRight: {

    x: 0,

    y: 0,

  },

}) // 初始化viewFin3、derBox

 3、调用摄像头方法

/** 调用摄像头 */

const getUserMedia = (

  success: NavigatorUserMediaSuccessCallback,

  error: NavigatorUserMediaErrorCallback

) => {

  //优先使用前置摄像头:{ video: { facingMode: "user" } }

  //强制使用后置摄像头:{ video: { facingMode: { exact: "environment" } } }

  const constraints = {

    video: {

      facingMode: 'user',

    },

  }

  if (navigator.mediaDevices.getUserMedia) {

    // 最新的标准API

    navigator.mediaDevices.getUserMedia(constraints).then(success).catch(error)

  } else if (navigator.webkitGetUserMedia) {

    // webkit核心浏览器

    navigator.webkitGetUserMedia(constraints, success, error)

  } else if (navigator.mozGetUserMedia) {

    // firfox浏览器

    navigator.mozGetUserMedia(constraints, success, error)

  } else if (navigator.getUserMedia) {

    // 旧版API

    navigator.getUserMedia(constraints, success, error)

  }

}

 4、截取快照

const cameraShoot = (

  video: HTMLVideoElement,

) => {

  const canvas = document.createElement('canvas')

  canvas.width = video.videoWidth

  canvas.height = video.videoHeight

  canvas

    .getContext('2d')

    ?.drawImage(

      video,

    (canvas.width - canvas.width * (320 / 240)) / 2,

    0,

    canvas.width * (320 / 240),

    canvas.height

    )

  return new Promise<Blob | null>((resolve) =>

    canvas.toBlob(resolve, 'image/jpeg'),

  )

}

 5、画盒子 框人脸 

const drawBox = (box, label) => {

  if (!canvas.value) return

  const context = canvas.value.getContext('2d')

  context?.clearRect(box.x, box.y, box.width, box.height)

  const drawBox = new draw.DrawBox(box, {

    label: label,

  })

  drawBox.draw(canvas.value)

}

 6、视频停止

const handleStopVideo = () => {

  if (stream.value) {

    stream.value.getTracks().forEach((track) => {

      track.stop()

    })

  }

}

 7、人脸检测

const detectFace = async () => {

  //非常重要:防止卡死

  await new Promise((resolve) => requestAnimationFrame(resolve))

  if (

    !canvas.value ||

    !video.value ||

    !video.value.currentTime ||

    video.value.paused ||

    video.value.ended

  )

    return detectFace()

   

  // 检测图像中具有最高置信度得分的脸部

  const result = await detectSingleFace(video.value, options)

  if (!result) return detectFace()

  // 匹配尺寸

  const dims = matchDimensions(canvas.value, video.value, true)

  // 调整检测到的框的大小,以防显示的图像的大小与原始

  const resizedResult = resizeResults(result, dims)

  const box = resizedResult.box

  drawBox(box, '识别中')

  video.value.pause()

  // 截取人脸图片

  const image =await cameraShoot(

    video.value,

  )

   // 图片blob类型转file类型

  let files = new window.File([image], '人脸头像.jpeg', {

    type: 'image/jpeg'

  })

  // 转标签元素 为获取人脸特征值

  let img = await bufferToImage(files);

  // 提取人脸特征值

  const detections = await detectAllFaces(img, new TinyFaceDetectorOptions()).withFaceLandmarks().withFaceDescriptors();

    if (detections.length > 0) {

      ctx.drawImage(img, 0, 0, canvas.width, canvas.height);

      detections.forEach((detection) => {

        // 提取人脸特征值并进行后续操作

       let data= detection.descriptor   

        // 接口上传人脸特征值进行对比返回验证结果   

        const detectResult = await uploadImg(data) 

          if (detectResult.msg ==='验证成功') {  

            getResult({

              type: 'success',

              label: '通过',

              id: infor.id,

              time: time,

            })

          }else{

            getResult({

              type: 'danger',

              label: '未通过',

              id: infor.id,

              time: "13:00:00",

            })

          }

          handleStopVideo()  

        })

      });

  } else {

    console.log('未检测到人脸');

    video.value.play()

    return detectFace()

  }

  if (!image) {

    drawBox(box, '识别失败')

    await delay(1000)

    video.value.play()

    return detectFace()

  }

}

 8、获取用户媒体流

onMounted(() => {
  // 获取用户媒体流
  getUserMedia(
    (streams) => {
      //后续用于停止视频流
      stream.value = streams
      //显示视频
      if (video.value) {
        video.value['srcObject'] = streams

        video.value.play(); // 防止视频延迟显示
      }
    },
    (error) => (getUserMediaFail.value = true)
  )

  //  加载算法模型  文件存储在 public 文件夹下models文件夹

  Promise.all([

      nets.ssdMobilenetv1.loadFromUri('/models'),

      nets.tinyFaceDetector.loadFromUri('/models'),

      nets.faceLandmark68Net.loadFromUri('/models'),

      nets.faceRecognitionNet.loadFromUri('/models')

    ]).then(startFaceRecognition());
  detectFace()
})

9、样式部分

.photo {

    width: 200px;

    height: 300px;

    display: flex;

    flex-direction: column;

    align-items: center;

    justify-content: center;

    position: relative;

    video {

      width: 100%;

      height: 100%;

      // object-fit: fill;

      transform: scaleX(-1);

    }

    img{

      width: 100%;

    }

    canvas {

      width: 100%;

      height: 100%;

      position: absolute;

      top: 0px;

    }

  }

 上述完成可识别到人脸,获取到特征值数据 

可根据自己的需求调整

  • 24
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
系统功能1、管理员管理:根据不同角色设置不同的管理权限;2、小区管理,管理多个小区资料,新增、修改、删除、摄像头管理等功能;3、小区摄像头管理:摄像头的新增、修改及删除功能;4、居民管理:居民资料新增,修改,删除,Excel批量导入,导出,居民人脸采集;5、访客登记:访客的新增,修改,删除,进入登记,离开登记,查询等功能;6、人脸识别:居民出入小区人脸识别功能的实现,使用腾讯AI人脸识别技术实现;7、出入记录:居民出入小区的人脸识别记录查询;8、小区地图:所有小区在地图的分布情况,使用百度地图实现;9、使用Echarts技术实现小区人员分类统计(柱状)图表;10、菜单管理:新增、修改、删除菜单功能(包括目录,菜单,按钮)11、角色管理:新增、修改、删除角色(系统角色、普通角色)12、系统日志:记录了系统中所有操作的日志,方便发现问题,查找原因;运行环境:  1、JDK1.8及以上版本  2、Tomcat 8.5及以上版本  3、MySql 5.7及以上版本  4、Redis开发工具:  1、前端开发工具:Visual Studio Code  2、后端开发工具:Intellij IDEA使用技术:  1、Vue2.x+ElementUI(前端)  2、Springboot+MyBatisPlus+Redis+Shiro+Swagger(后端)  3、人脸识别技术(腾讯AI)  4、MySql数据库技术  5、Redis缓存技术  6、百度地图  7、Echarts图表技术  8、POI Excel导入导出技术  9、Shiro权限控制:菜单管理,角色管理,权限管理(按钮及用户级别权限)  10、 Swagger接口配置管理,接口文档管理技术  11、Token单点技术(一个用户不能同时在多个设备登录使用)  12、前后端分离跨域设置等技术

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值