- wx.createVKSession人脸识别传入onCameraFrame实时帧数据识别不到人像?
// pages/audio/index.ts Page({ /** * 页面的初始数据 */ data: { audioUrl: '', videoUrl: '' }, /** * 生命周期函数--监听页面加载 */ onLoad() { videoCtx = wx.createCameraContext(); let count = 0; listener = videoCtx.onCameraFrame((frame:any) => { count++; if (count === 10) { this.detectFace(frame); count = 0; } }); VKSession = wx.createVKSession({ version: 'v1', track: { plane: { mode: 1 }, face: { mode: 2 } } }); VKSession.on('updateAnchors', (anchors:any) => { console.warn('anchors', anchors); }) }, handleStart() { videoCtx.startRecord({ timeoutCallback: (res:any) => { console.warn(res); this.setData({ videoUrl: res.tempVideoPath }) }, timeout: 300, complete: (res:any) => { console.warn('videoCtx.startRecord complete', res); } }); VKSession.start((errno:any) => { console.warn('VKSession.start errno', errno); }); listener.start(); }, handleStop() { listener.stop({ complete: (res:any) => { console.warn('listener.stop', res); } }); VKSession.stop(); videoCtx.stopRecord({ compressed: true, success: (res:any) => { console.warn('videoCtx.stopRecord success', res); this.setData({ videoUrl: res.tempVideoPath }) }, fail: (res:any) => { console.warn('videoCtx.stopRecord fail', res); } }); }, async detectFace(frame:any) { console.warn(frame.data); VKSession.detectFace({ frameBuffer: frame.data, width: frame.width, height: frame.height, scoreThreshold: 0.8, sourceType: 0, modelMode: 1 }); }, handleError() {}, }); [图片] 代码片段: https://developers.weixin.qq.com/s/yoorZhmf7aJ6
2023-06-27 - 小程序体验版可以正常使用相机、开发者工具真机调试可以使用相机(小程序设置中相机权限开启了),但是发布
小程序体验版可以正常使用相机、开发者工具真机调试可以使用相机(小程序设置中相机权限开启了),但是发布之后,相机页面不能打开,微信小程序性能日志中未记录任何错误日志,下面是代码,在跳转到这个页面之前有调用授权代码(小程序设置中相机权限是开启的) uni.authorize({ scope: 'scope.camera', success() { console.log('isAuthCamera') this_.goPersonVerify() }, fail(e){ console.log("fail:openSetting") console.log(e) Tips.toast("已拒绝相机权限") } }) 上面是授权代码,下面是故障页面(用户小程序设置中相机权限是开启的) <template> <view class="page-content"> <view class="containerV"> <!-- 标题 --> <view class="headerV"> <view class="top-tips1"> <view>{{tipsText}}</view> </view> </view> <!-- 拍摄区域 --> <view class="contentV"> <view class="mark"></view> <image class="image" v-if="tempImg" mode="widthFix" :src="tempImg" /> <camera v-if='isAuthCamera' :device-position="devicePosition ?'front': 'back'" class="camera" flash="off" resolution='high' /> </view> <!-- 操作区域 --> <view class="footerV"> <view style="width: 100%;"> <view v-if="!tempImg" style="width: 100%;"> <view class="take-photo-bgV"> <!-- 图片上传 --> <!-- <view v-show="true" class="btn-change-upload" @click="handleChooseImage" />--> <!-- 切换镜头 --> <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 class="margin-lg"><text class="text-ABC text-bold">{{personVerifyForm.name}}</text></view> <view class="margin-lg"><text class="text-ABC text-bold">{{personVerifyForm.idCard}}</text></view> </view> </view> </view> </view> </template> <script> import { pathToBase64, } from 'image-tools' import Tips from "../../common/util/tip"; export default { components:{}, data() { return { personVerifyForm:{ name:'', idCard:'', imageType:"BASE64", image:'', passed:'', score:'0' }, tipsText: '请将脸部移入框内', // 错误文案提示 tempImg: '', // 本地图片路径 cameraEngine: null, // 相机引擎 devicePosition: true, // 摄像头朝向 isAuthCamera: true, // 是否拥有相机权限 }; },onLoad(options) { this.personVerifyForm.name = options.name this.personVerifyForm.idCard = options.idCard this.init() },onShow() { }, methods:{ handleChangeCameraClick() { // 切换设备镜头 console.log('切换设备镜头') this.devicePosition = !this.devicePosition; }, init(){ // #ifdef MP-WEIXIN // 1、初始化人脸识别 wx.initFaceDetect() console.log('初始化人脸识别完成wx.createVKSession()') // 2、创建 camera 上下文 CameraContext 对象 this.cameraEngine = wx.createCameraContext() console.log('初始化人脸识别完成',this.cameraEngine) // 3、获取 Camera 实时帧数据 const listener = this.cameraEngine.onCameraFrame((frame) => { console.log('获取 Camera 实时帧数据') 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 = '请拍照' // 这里可以写自己的逻辑了 this.handleTakePhotoClick() } } }, fail: (err) => { if (err.x == -1 || err.y == -1) { this.tipsText = '检测不到人' } else { console.log(err) this.tipsText = err.errMsg || '网络错误,请退出页面重试' } }, }) }) console.log('启动监听') // 5、开始监听帧数据 listener.start() // #endif }, handleTakePhotoClick() { // 拍照点击 console.log("拍照点击") this.cameraEngine.takePhoto({ quality: "high", success: ({ tempImagePath }) => { console.log("拍照点击success") this.handleOkClick(tempImagePath) } }) }, async handleOkClick(filePath) { // 点击确定上传 Tips.loading("认证中……") pathToBase64(filePath).then(data => { console.log("人脸认证:",data) this.personVerifyForm.image = data.split(",")[1] this.$http.post('front/cus/face/personVerify',this.personVerifyForm).then(res=>{ console.log("res::",res) Tips.loaded() if(res.data.success&&res.data.result.passed=='1'){ this.personVerifyForm = res.data.result Tips.toast("认证通过") uni.$emit('personVerify',this.personVerifyForm); uni.navigateBack({ delta: 1 }); }else { Tips.toast("认证失败,请重试") uni.navigateBack({ delta: 1 }); } }).catch(function () { Tips.toast("网络错误") uni.navigateBack({ delta: 1 }); }).finally(function () { Tips.loaded() }) }) } } } </script> <style lang="scss"> page {height: 100%;width: 100%;} .page-content { width: 100%;height: 100%; .containerV { width: 100%;height: 100%;display: flex;flex-direction: column; /* 标题 */ .headerV { padding: 163rpx 0 56rpx;text-align: center; .top-tips1 {color: #333333;font-size: 42rpx;} } /* 拍摄区域 */ .contentV { position: relative;display: flex;flex-direction: column;align-items: center;justify-content: center; width: 564rpx;height: 564rpx;border-radius: 50%;margin: 0 auto;border: 10rpx solid #1568E0;background-color: #d8d8d8; .camera {width: 100%;height: 100%;border-radius: 50%;z-index: 2;} .mark {position: absolute;left: 0;top: 0;z-index: 1;width: 100%;height: 100%;border-radius: 50%;} .image {position: absolute;width: 100%;height: 100%;z-index: 3;border-radius: 50%;} } /* 操作按钮 */ .footerV { width: 100%;flex-grow: 1;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;} } } .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://www.hujinqiang.com/anjiantong/face/photo.png") no-repeat;background-size: 100% auto;} .btn-change-upload {left: 130rpx;width: 80rpx;height: 80rpx;background: url("https://www.hujinqiang.com/anjiantong/face/album.png") no-repeat;background-size: 100% auto;} .btn-change-camera {right: 130rpx;width: 80rpx;height: 80rpx;background: url("https://www.hujinqiang.com/anjiantong/face/changing.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>
2023-07-05 - updateAnchors,removeAnchors 事件不触发?
session.on('updateAnchors', anchors => { anchors.forEach(anchor => { console.log('anchor.type', anchor.type) AR虚拟对象.matrixAutoUpdate = false AR虚拟对象.matrix.fromArray(anchor.transform) }) }) updateAnchors 事件不会发生,代码不走动态监测
2022-12-21