微信小程序如何实现人脸追踪?
2019-12-05 16:31:33 250
Step1
wxml代码
<view> <camera device-position="{{status.camera}}" flash="off" binderror="error" style="width: 100%; height: 300px;"> <cover-view style='left:{{frame.left}}px;top:{{frame.top}}px;width:{{frame.width}}px;height:{{frame.height}}px'></cover-view> </camera> <view bindtap='record'>{{status.record ? '结束录像' : '开始录像'}}</view> <view bindtap='changeCamera'>{{status.camera === 'back' ? '前置摄像头' : '后置摄像头'}}</view> <view bindtap='faceTracking'>人脸追踪</view></view>
wxss代码
// 人脸追踪定位的框框
.frame{ position: absolute; border: 1rpx solid yellow;}
Step2
因为是人脸追踪,由于小程序的api并没有关于人工智能方面的,因为我们需要借助百度api或者腾讯的api进行人脸的定位,我这里采用的百度的api(百度api的用法我这里就不详细去讲了,大家可以通过百度api的官网进行对应的了解)。
注意:api提供的文件数据流可选的是视频文件或者图片文件,因此在业务流程是只要开启人脸追踪,就需要每秒的去进行追踪,因此完整的视频数据流是不可取的,所以只能改用方法,每0.5s通过调用微信小程序api进行对camera的组件进行截图上传至百度api上进行实现人脸追踪。
百度api过去到的定位信息
由于要上镜加上本人比较害羞的原因,最终效果图就不给大家看了。
js代码
// pages/camera/camera.js
Page({
/**
* 页面的初始数据
*/
data: {
status: {
record: false,
camera: 'back'
},
pic: '',
frame: {
left: 0,
top: 0,
width: 0,
height: 0,
},
windowWidth:0,
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.ctx = wx.createCameraContext();
var sysInfo = wx.getSystemInfoSync()
this.setData({
windowWidth: sysInfo.windowWidth,
})
},
faceTracking:function(){
this.takePhoto()
this.interval = setInterval(this.takePhoto, 500)
},
takePhoto: function () {
let that = this;
var takephonewidth;
var takephoneheight;
this.ctx.takePhoto({
quality: "low",
success: function (photo) {
that.data.pic = photo.tempImagePath;
that.setData({
pic: that.data.pic
})
wx.getImageInfo({
src: photo.tempImagePath,
success: function (pic) {
takephonewidth = pic.width;
takephoneheight = pic.height;
}
})
wx.getFileSystemManager().readFile({
filePath: photo.tempImagePath, //选择图片返回的相对路径
encoding: 'base64', //编码格式
success: function (base64pic) {
wx.request({
url: "https://aip.baidubce.com/rest/2.0/face/v3/detect?access_token=你的access_token",
data: {
image: base64pic.data,
image_type: "BASE64",
max_face_num: 10
},
method: 'POST',
dataType: "json",
header: {
'content-type': 'application/json'
},
success: function (res) {
if (res.data.error_code === 0) {
for (let j = 0; j < res.data.result.face_num; j++) {
that.data.frame.left = res.data.result.face_list[j].location.left / takephonewidth * that.data.windowWidth
that.data.frame.top = res.data.result.face_list[j].location.top / takephoneheight * 300
that.data.frame.width = res.data.result.face_list[j].location.width / takephonewidth * that.data.windowWidth
that.data.frame.height = res.data.result.face_list[j].location.height / takephoneheight * 300
}
that.setData({
frame:that.data.frame
})
console.log(that.data.frame)
}
}
})
}
})
}
})
},
record: function () {
if (this.data.status.record) {
this.data.status.record = false;
this.setData({
status: this.data.status,
})
ctx.stopRecord({
success: (res) => {
console.log(res)
}
})
} else {
this.data.status.record = true;
this.setData({
status: this.data.status,
})
ctx.startRecord({
timeoutCallback: (res) => {
console.log(res)
},
success: (res) => {
console.log(res)
}
})
}
},
changeCamera: function () {
this.data.status.camera = this.data.status.camera === 'back' ? 'front' : 'back';
this.setData({
status: this.data.status
})
}
})
总结
总体效果看来是很不错的,至少基本上能够把人脸追踪的效果实现出来,只是感觉上并不是最优解。因为是不停的依赖于api的帮助,而且最终用view或者canvas画出的框跟随人移动的也是有一定的延迟,所实现的出来的效果还是有待提高的,性能上也是,不停的去调用请求接口也是非常耗损性能的。但是目前由于也是没有好的办法,也希望大家多多提点意见,能够提供一个更好的解决办法。
睿江云官网链接:https://www.eflycloud.com/home?from=RJ0032