1. 微信小程序人脸识别
1. 初始化人脸识别
wx.initFaceDetect()
2. 创建 camera 上下文 CameraContext 对象
this.cameraEngine = wx.createCameraContext();
3.获取 Camera 实时帧数据
const listener = this.cameraEngine.onCameraFrame()
4.人脸识别,使用前需要通过 wx.initFaceDetect 进行一次初始化,推荐使用相机接口返回的帧数据
wx.faceDetect()
5.校验人脸是否居中(可调整或注释)
var centerWidth = 250; //中心位置宽度
var centerHeight = 250; //中心位置高度
if (face.x > (frame.width - centerWidth) / 2 && face.x < (frame.width - centerWidth) / 2 + centerWidth && face.y > (frame.height - centerHeight) / 2 && face.y < (frame.height -centerHeight) / 2 + centerHeight) {
this.tipsText = '校验中...'
this.isVerify = true;
// 太快获取的人脸可能比较抽象,给用户一个准备时间
// setTimeout(async () => {
this.base64 = await this.changeDataToBase64(frame);
this.searchUserFace();
// }, 300)
} else {
this.tipsText = '请将人脸对准中心位置'
}
6. 把满足条件的当前帧数据转为base64(通过canvas转换临时文件在转换为base64只需要1秒不到,比使用upng.js及pako.js的形式快很多(3-7秒),而且upng.js在部分机型容易卡死)
changeDataToBase64(frame) {
return new Promise((resolve, reject) => {
var data = new Uint8Array(frame.data);
var clamped = new Uint8ClampedArray(data);
let that = this;
// 当前帧数据转为data并画在canvas上
wx.canvasPutImageData({
canvasId: 'myCanvas',
x: 0,
y: 0,
width: frame.width,
height: frame.height,
data: clamped,
success(res) {
// 转换临时文件
wx.canvasToTempFilePath({
x: 0,
y: 0,
width: frame.width,
height: frame.height,
canvasId: 'myCanvas',
fileType: 'jpg',
destWidth: frame.width,
destHeight: frame.height, // 精度修改
quality: 0.5,
success(res) {
// 临时文件转base64
wx.getFileSystemManager().readFile({
filePath: res.tempFilePath, //选择图片返回的相对路径
encoding: 'base64', //编码格式
success: res => {
// 保存base64
resolve(res.data);
}
})
},
fail(res) {
reject(false);
}
});
},
fail(error) {
console.log(error);
}
})
})
},
7. 接入腾讯云第三方人脸识别 -人员管理及人脸搜索功能(每月免费10000次就很润)
完整代码
<template>
<view>
<view class="d-flex justify-content-between align-items-center update-box mt-40 mr-32">
<!-- 镜头翻转 -->
<image @click="devicePosition=!devicePosition" class="camera-change-image" mode="widthFix"
src="@/static/images/camera_change.png"></image>
<!-- 扫二维码 -->
<image @click="clickScanCode()" class="scan-image" src="@/static/images/face_scan.png" mode="aspectFit">
</image>
</view>
<view class="head-image-box w-100 text-center position-relative">
<!-- resolution:获取人脸图片后的清晰度 low:低 -->
<camera v-if='isAuthCamera' :device-position="devicePosition ?'back': 'front'" class="camera" flash="off"
resolution='low' />
<view class="title" v-show="tipsText">{{ tipsText }}</view>
<cover-view class="cover-box" v-show="isShow">
<cover-image class="image-box" src="@/static/images/camera_verify.png"></cover-image>
<!-- cover-view 不支持动画所以只能变通的形式实现 -->
<cover-image :style="'transform: translateY('+translateY+'rpx);'" class="line"
src="@/static/images/bg_line.png"></cover-image>
<!-- <cover-view class="line"></cover-view> -->
</cover-view>
<canvas id="myCanvas" canvas-id="myCanvas"
:style="'width:'+screenWidth+'px;'+'height:'+screenHeight+'px'"></canvas>
</view>
</view>
</template>
<script>
export default {
name: 'index',
data() {
return {
isShow: false,
tipsText: '', // 错误文案提示
tempImg: '', // 本地图片路径
cameraEngine: null, // 相机引擎
devicePosition: true, // 摄像头朝向
isAuthCamera: true, // 是否拥有相机权限
isVerify: false,
translateY: -24,
timer: null,
isFlag: true,
origin: null,
base64: "",
personId: "",
isFlag2: true,
screenWidth: 375,
screenHeight: 640
}
},
onShow: function() {
this.isVerify = false;
this.tipsText = "";
this.isFlag = true;
this.lineAnimation();
},
onLoad(options) {
this.initData();
},
onUnload() {
this.clearTimer();
},
onHide() {
this.clearTimer();
},
methods: {
clearTimer(){
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
}
this.isFlag = false;
},
// 初始化相机引擎
initData() {
// #ifdef MP-WEIXIN
// 1、初始化人脸识别
wx.initFaceDetect();
// 2、创建 camera 上下文 CameraContext 对象
this.cameraEngine = wx.createCameraContext();
this.isShow = true;
// 3、获取 Camera 实时帧数据
const listener = this.cameraEngine.onCameraFrame((frame) => {
if (this.isVerify) return
//动态设置canvas的宽高,不设置会导致部分机型人脸不完整导致不能识别-----很重要!很重要!很重要!
if (this.isFlag2) {
this.isFlag2 = false;
this.screenWidth = frame.width;
this.screenHeight = frame.height;
}
// 4、人脸识别,使用前需要通过 wx.initFaceDetect 进行一次初始化,推荐使用相机接口返回的帧数据
wx.faceDetect({
frameBuffer: frame.data,
width: frame.width,
height: frame.height,
enablePoint: true,
enableConf: true,
enableAngle: true,
enableMultiFace: true,
success: async (faceData) => {
let face = faceData.faceInfo[0]
if (face.x == -1 || face.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 {
if (this.isVerify) return
//人脸位置校验
var centerWidth = 250;
var centerHeight = 250;
if (face.x > (frame.width - centerWidth) / 2 && face.x < (frame
.width - centerWidth) / 2 + centerWidth && face.y > (frame
.height - centerHeight) / 2 && face.y < (frame.height -
centerHeight) / 2 + centerHeight) {
this.tipsText = '校验中...'
this.isVerify = true;
// 太快获取的人脸可能比较抽象,给用户一个准备时间
// setTimeout(async () => {
this.base64 = await this.changeDataToBase64(
frame);
this.searchUserFace();
// }, 300)
} else {
this.tipsText = '请将人脸对准中心位置'
}
}
}
},
fail: (err) => {
if (this.isVerify) return
if (err.x == -1 || err.y == -1) {
this.tipsText = '检测不到人'
} else {
this.tipsText = err.errMsg || '网络错误,请退出页面重试'
}
},
})
})
// 5、开始监听帧数据
listener.start()
// #endif
},
clickScanCode() {
// 只允许通过相机扫码
// #ifdef MP-WEIXIN
uni.scanCode({
onlyFromCamera: true,
success: (res) => {
var data = JSON.parse(res.result.replace(/\ufeff/g, ""));
}
});
// #endif
},
changeDataToBase64(frame) {
return new Promise((resolve, reject) => {
var data = new Uint8Array(frame.data);
var clamped = new Uint8ClampedArray(data);
let that = this;
var width = this.screenWidth;
var height = frame.height * this.screenWidth / frame.width;
wx.canvasPutImageData({
canvasId: 'myCanvas',
x: 0,
y: 0,
width: frame.width,
height: frame.height,
data: clamped,
success(res) { // 转换临时文件
wx.canvasToTempFilePath({
x: 0,
y: 0,
width: width,
height: height,
canvasId: 'myCanvas',
fileType: 'jpg',
destWidth: width,
destHeight: height, // 精度修改
quality: 0.5,
success(res) {
// 临时文件转base64
uni.getFileSystemManager().readFile({
filePath: res.tempFilePath, //选择图片返回的相对路径
encoding: 'base64', //编码格式
success: res => {
// 保存base64
resolve(res.data);
}
})
},
fail(res) {
reject(false);
}
});
},
fail(error) {
console.log(error);
}
})
})
},
searchUserFace() {
// 1.人脸识别错误 把isVerify设置为true继续识别
// 2.人脸识别成功,做对应的逻辑
// var params = {
// faceImage: this.base64,
//
// }
// searchFaces(params).then(res => {
// if (res.code == 200) {
// wx.stopFaceDetect(); //关闭人脸识别
// this.listener.stop(); //关闭camera摄像头监听
// this.clickPushDetail(res.data.personCode);
// this.tipsText = '校验成功'
// }
// }).catch(error => {
// setTimeout(() => {
// this.isVerify = false;
// }, 500)
// this.tipsText = '暂未查找到相关人员'
// })
},
clickPushDetail() {
// 跳转到其他页面
},
lineAnimation() {
if (this.timer) return
this.timer = setInterval(() => {
this.translateY += 8;
if (this.translateY >= 460) {
this.translateY = 10;
}
}, 40)
},
}
}
</script>
<style>
page {
background-color: #000000;
}
</style>
<style lang="scss" scoped>
.camera-change-image {
width: 52rpx;
margin-left: 40rpx;
// margin-top: 24rpx;
}
.scan-image {
width: 48rpx;
}
.update-box {
color: #ffffff;
}
.operation-box {
position: fixed;
width: 100%;
bottom: calc(120rpx + env(safe-area-inset-bottom));
// font-size: 32rpx;
.icon-box {
width: 76rpx;
height: 76rpx;
&.first {
width: 72rpx;
height: 72rpx;
}
}
}
.head-image-box {
position: absolute;
top: 10vh;
color: white;
.camera {
width: 750rpx;
height: 872rpx;
position: relative;
z-index: 10;
}
#myCanvas {
position: absolute;
z-index: 1;
top: -10000px;
}
.title {
font-size: 40rpx;
margin-top: 60rpx;
// font-weight: bold;
}
.cover-box {
position: absolute;
top: 40%;
left: 50%;
transform: translate(-50%, -50%);
width: 500rpx;
height: 500rpx;
}
.image-box {
width: 100%;
height: 100%;
}
.line {
position: absolute;
top: 0rpx;
left: 8rpx;
right: 8rpx;
width: auto;
height: 30rpx;
z-index: 2;
}
}
</style>
2. H5人脸识别
详见:h5人脸识别文章来源地址https://www.toymoban.com/news/detail-484863.html
文章来源:https://www.toymoban.com/news/detail-484863.html
到了这里,关于微信小程序人脸识别/采集改进版(wx.faceDetect)-支持人脸中心位置校验,人脸图片采集(速度更快),人脸搜索的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!