uni-app项目中使用tracking.js人脸识别

CSDN话题挑战赛第2期
uni-app项目中使用tracking.js人脸识别:前端技术分享

说在前面

针对uni-app项目中倒计时拍照、对齐人脸按钮拍照等拍照方式,导致的识别效率下降,人脸信息捕捉不完全,进而浪费计算资源等问题。本文将tracking.js应用到uni-app项目中,可以在识别出人脸的前提下,将图像信息传输到后端进行比对。

引言

首先介绍下tracking.js与uni-app:

  1. tracking.js是一个独立的JavaScript库,用于跟踪从相机实时收到的数据。跟踪的数据既可以是颜色,也可以是人,也就是说我们可以通过检测到某特定颜色,或者检测一个人体/脸的出现与移动,来触发JavaScript 事件。

  2. uni-app 是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、Web(响应式)、以及各种小程序(微信/支付宝/百度/头条/飞书/QQ/快手/钉钉/淘宝)、快应用等多个平台。

「uni-app项目中使用tracking.js人脸识别」

最近想把web端使用tracking.js的人脸识别应用在uni-app项目中,那当然是直接使用Ctrl+C Ctrl+V大法,显而易见的报错了,明明在web端就好用,在uni-app中就不好用呢?经过不断地试错与对比终于发现了问题,原来是uni-app封装了一些同名媒体组件,而这些组件和原生的用法不一样(吐血)

问题复现

分别在web端和uni-app端项目中运行下列代码,web端正常运行,uni-app报错了,结果如图一、图二所示:

this.video = document.getElementById('video');
let canvas = document.getElementById('canvas');
console.log(this.video);
console.log(canvas);

图一 web端中运行结果

图一 web端结果

图二 uni-app中运行结果
图二 uni-app结果
可以看出到document.getElementById获取到的video与canvas标签不一致,显示为uni-video和uni-canvas,即uni-app中的已经封装好的video与canvas。而video与canvas标签则如图三所示:

图三video与canvas标签
图三video与canvas标签

解决方法

根据图三,将封装好的video与canvas进行拆解。

拆解:

this.video = document.getElementById('video').children[0].children[0];
let canvas = document.getElementById('canvas').children[0];
console.log(this.video);
console.log(canvas);

拆解后:
在这里插入图片描述
拆解后的标签就可以对应上了,接下来用之前方法测试一下,成功搞定!

其中需要注意的一点是uni-app中的video参数需要注意一下。

<video id="video" objectFit="cover" style="width:690px;height:690px" :controls="false" :show-center-play-btn="false" :autoplay="true" :loop="true">

:controls=“false”:不显示操作按钮
:show-center-play-btn=“false”:不显示play按钮
:autoplay=“true”:开启自动播放
:loop=“true”:开启轮播

源代码

face.vue文件

<template>
    <view class="container">
		<image class="bg" src="../static/images/login/digHole.png"></image>
        <view class="video-box">
            <video id="video" objectFit="cover" style="width:690px;height:690px" :controls="false" :show-center-play-btn="false" :autoplay="true" :loop="true">
			</video>
            <canvas id="canvas" style="width:690px;height:690px"></canvas>
            <canvas id="canvas_2" style="width:690px;height:690px"></canvas>
        </view>
    </view>

</template>

<script>
    import "../assets/tracking-min.js";
    import "../assets/face-min.js";

    export default {
        data() {
            return {
				saveArray: {},
                trackerTask: null,
                mediaStreamTrack: null,
                video: null,
                screenshotCanvas: null,
                uploadLock: true // 上传锁
            }
        },
        mounted() {
            this.init();
        },
        methods: {
            // 初始化设置
            init() {
                if (!(document.getElementById('video') &&
                    document.getElementById('video').children[0] !== null &&
                    document.getElementById('video').children[0].children[0] !== null &&
                    document.getElementById('canvas') &&
                    document.getElementById('canvas').children[0] !== null &&
                    document.getElementById('canvas_2') &&
                    document.getElementById('canvas_2').children[0] !== null)) {
                } else {
                    this.video = this.mediaStreamTrack = document.getElementById('video').children[0].children[0];
                    this.screenshotCanvas = document.getElementById('canvas_2').children[0];
                    let myVideo = document.getElementById('video').children[0].children[0];
                    let canvas = document.getElementById('canvas').children[0];
                    let context = canvas.getContext('2d');

                    // 固定写法
                    let tracker = new window.tracking.ObjectTracker('face');
                    tracker.setInitialScale(4);
                    tracker.setStepSize(2);
                    tracker.setEdgesDensity(0.1);
                    //摄像头初始化

                    this.trackerTask = window.tracking.track(myVideo, tracker, {camera: true});

                    let _this = this;
					 let saveArray = {};
                    tracker.on('track', function (event) {
                        // 检测出人脸 绘画人脸位置
                        context.clearRect(0, 0, 690, 690);
                        event.data.forEach(function (rect) {
                            context.strokeStyle = '#0764B7';
                            context.strokeRect(rect.x, rect.y, rect.width, rect.height);
							saveArray.x = rect.x;
							saveArray.y = rect.y;
							saveArray.width = rect.width;
							saveArray.height = rect.height;
                        });
						//识别范围
						let canvas1 = document.getElementById('canvas').children[0];
						let context1 = canvas.getContext('2d');
						context1.strokeStyle = "#69fff1";
						context1.moveTo(150, 60);
						context1.lineTo(520, 60);
						context1.lineTo(520, 580);
						context1.lineTo(150, 580);
						context1.lineTo(150, 60);
						context1.stroke();
						// event.data.length长度为多少代表检测几张人脸
                        setInterval(() => {
                            if (
                                saveArray.x > 140 &&
                                saveArray.x + saveArray.width < 550 &&
                                saveArray.y > 40 &&
                                saveArray.y + saveArray.height < 600 &&
                                saveArray.width < 260 &&
                                saveArray.height < 500
                            ) {
                                // this.getPhoto();
                                if (_this.uploadLock && event.data.length) {
                                    //上传图片
                                    _this.screenshotAndUpload();
                                }
                                for (let key in saveArray) {
                                    delete saveArray[key];
                                }
                            }
                        }, 2000);
                    });
                }
            },
            // 上传图片
            screenshotAndUpload() {
                // 上锁避免重复发送请求
                this.uploadLock = false;
                // 绘制当前帧图片转换为base64格式
                let canvas2 = this.screenshotCanvas;
                let video = this.video;
                let ctx = canvas2.getContext('2d');

                ctx.clearRect(0, 0, 690, 690);
                // ctx.drawImage(video, 0, 0, 690, 690);
                ctx.drawImage(video, 180,90,300,510,0,0,300,510);
                let base64Img = canvas2.toDataURL('image/jpeg');
                ctx.clearRect(0, 0, 690, 690);
                // 打印出 base64Img
                console.log('base64Img:', base64Img)
                // this.faceRecognition(base64Img)
                // 请求接口成功以后打开锁
                // this.uploadLock = true;
            },
            //关闭摄像头
            async destroyed() {
                if (!this.mediaStreamTrack) {
                    return
                }
                this.mediaStreamTrack.srcObject.getTracks()[0].stop();
                this.trackerTask.stop()
            },
        }
    }
</script>

<style scoped lang="scss">
    /* 绘图canvas 不需显示隐藏即可 */
    #screenshotCanvas {
        display: none;
    }
	.bg{
		position: fixed;
		width: 100%;
		height: 100%;
		top: 0;
		left: 0;
		z-index: 1;
	}
	.container{
		height: 1080px;
		display: flex;
		/* 水平垂直居中 */
		justify-content: center;
		align-items: center;
	}

    .video-box {
		margin-top: 80px;
		margin-right: 10px;
        width: 690px;
        height: 690px;
    }

    video, #canvas,#canvas_2 {
		position: absolute;
        border: #000000 5px solid;
    }
</style>

效果图

效果图

总结

uni-app 是一个使用 Vue.js 开发所有前端应用的框架,所以我感觉很多在web端可以实现的代码,在uni-app也可以复用,将来会再挖掘一些在uni-app中使用的插件。

  • 16
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 23
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

犬莱八荒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值