vue实现拍照人脸识别功能带人脸选中框

2023-11-20

前言:

       实现打开摄像头,并识别人脸。

实现效果:

实现步骤:

一、安装

(1)官网下载 tracking.js 的代码包官网入口

(2)npm下载

执行命令: cnpm install tracking --save

二、demo案例代码

<template>
    <div class="testTracking">
        <video
                id="video"
                width="1000"
                height="700"
                preload
                autoplay
                loop
                muted
        ></video>
        <canvas id="canvas" width="1000" height="700"></canvas>
        <div class="buttonDiv">
            <button type="button" @click="submit" style="font-size: 3vw;">提取照片</button>
            <button type="button" name="button" @click="checkFace" style="font-size: 3vw;">检测人脸</button>
            <button type="button" name="button" @click="getCompetence" style="font-size: 3vw;">
                打开摄像头
            </button>
            <button type="button" name="button" @click="de" style="font-size: 3vw;">停</button>
        </div>
    </div>
</template>

<script>
    require("tracking/build/tracking-min.js");
    require("tracking/build/data/face-min.js");
    require("tracking/build/data/mouth-min.js");
    require("tracking/examples/assets/stats.min.js");
    export default {
        name: "testTracking",
        data() {
            return {};
        },
        methods: {
            checkFace() {
                var video = document.getElementById("video");
                var canvas = document.getElementById("canvas");
                var context = canvas.getContext("2d");

                var tracker = new tracking.ObjectTracker("face");
                tracker.setInitialScale(4);
                tracker.setStepSize(2);
                tracker.setEdgesDensity(0.1);

                this.trackerTask = tracking.track("#video", tracker, { camera: true });

                tracker.on("track", function (event) {
                    if (event.data.length <= 0) {
                        return;
                    }
                    context.clearRect(0, 0, canvas.width, canvas.height);
                    event.data.forEach(function (rect) {
                        context.strokeStyle = '#a64ceb';
                        context.strokeRect(rect.x, rect.y, rect.width, rect.height);
                        context.font = '11px Helvetica';
                        context.fillStyle = "#fff";
                        context.fillText('x: ' + rect.x + 'px', rect.x + rect.width + 5, rect.y + 11);
                        context.fillText('y: ' + rect.y + 'px', rect.x + rect.width + 5, rect.y + 22);
                    });
                });
            },
            submit() {
                let that = this;
                let canvas = document.getElementById("canvas");
                let context = canvas.getContext("2d");
                let video = document.getElementById("video");
                context.drawImage(video, 0, 0, 1000, 700);
                canvas.toBlob((blob) => {
                    // axios.post({ faceUrl: URL.createObjectURL(blob) }).then((res) => {
                    //   console.log("上传成功");
                    // });
                    var reader = new FileReader();
                    reader.readAsDataURL(blob);
                    console.log(reader);
                });
            },
            getCompetence() {
                var _this = this;
                this.thisCancas = document.getElementById("canvas");
                this.thisContext = this.thisCancas.getContext("2d");
                this.thisVideo = document.getElementById("video");
                // 旧版本浏览器可能根本不支持mediaDevices,我们首先设置一个空对象
                if (navigator.mediaDevices === undefined) {
                    navigator.mediaDevices = {};
                }
                // 一些浏览器实现了部分mediaDevices,我们不能只分配一个对象
                // 使用getUserMedia,因为它会覆盖现有的属性。
                // 这里,如果缺少getUserMedia属性,就添加它。
                if (navigator.mediaDevices.getUserMedia === undefined) {
                    navigator.mediaDevices.getUserMedia = function (constraints) {
                        // 首先获取现存的getUserMedia(如果存在)
                        var getUserMedia =
                            navigator.webkitGetUserMedia ||
                            navigator.mozGetUserMedia ||
                            navigator.getUserMedia;
                        // 有些浏览器不支持,会返回错误信息
                        // 保持接口一致
                        if (!getUserMedia) {
                            return Promise.reject(
                                new Error("getUserMedia is not implemented in this browser")
                            );
                        }
                        // 否则,使用Promise将调用包装到旧的navigator.getUserMedia
                        return new Promise(function (resolve, reject) {
                            getUserMedia.call(navigator, constraints, resolve, reject);
                        });
                    };
                }
                var constraints = {
                    audio: false,
                    video: {
                        width: this.videoWidth,
                        height: this.videoHeight,
                        transform: "scaleX(-1)",
                    },
                };
                navigator.mediaDevices
                    .getUserMedia(constraints)
                    .then(function (stream) {
                        // 旧的浏览器可能没有srcObject
                        if ("srcObject" in _this.thisVideo) {
                            _this.thisVideo.srcObject = stream;
                        } else {
                            // 避免在新的浏览器中使用它,因为它正在被弃用。
                            _this.thisVideo.src = window.URL.createObjectURL(stream);
                        }
                        _this.thisVideo.onloadedmetadata = function (e) {
                            _this.thisVideo.play();
                        };
                    })
                    .catch((err) => {
                        console.log(err);
                    });
            },
            de() {
                // 停止侦测
                this.trackerTask.stop();
                // 关闭摄像头
                this.trackerTask.closeCamera();
            },
        },
        destroyed() {
            // 停止侦测
            this.trackerTask.stop();
            // 关闭摄像头
            this.trackerTask.closeCamera();
        },
    };
</script>

<style lang="less" scoped>
    .testTracking {
        height: 100vh;
        width: 100%;
        position: relative;
        > * {
            position: absolute;
            left: 0;
            right: 0;
            margin: auto;
        }
        video,
        canvas {
            top: 0;
        }
        .buttonDiv {
            bottom: 10px;
        }
    }
</style>

***demo到此结束了***

参考文章:https://blog.csdn.net/qingwu1104/article/details/100881658

 

此外:上面的是案例,下面是另一份应用,不予解释,

<template>
    <div style="width: 100%;height: 100%;">
        <Select v-model="modelSel" style="width:200px;margin-bottom:1%;" @on-change="changeSel">
            <Option v-for="(item,index) in videoArr" :value="item.id" :key="index">{{ item.label }}</Option>
        </Select>
        <div class="testTracking">
            <!--开启摄像头-->
            <!--<Button  type="primary"  @click="callCamera" style="margin-right: 10px;">开启摄像头</Button>-->
            <!--<Button @click = 'changePhoto' style="margin-right: 10px;">切换摄像头</Button>-->
            <!--关闭摄像头-->
            <!--<Button  type="primary"  @click="closeCamera">关闭摄像头</Button>-->
            <!--canvas截取流-->
            <canvas style="display:none;" ref="canvas" :width="videoWidth" :height="videoHeight"></canvas>
            <!--图片展示-->
            <video ref="video" id="video" :width="videoWidth" :height="videoHeight" autoplay style="display: block;margin:0 auto;"></video>
            <canvas id="canvas"  :width="videoWidth" :height="videoHeight"></canvas>
            <!--确认-->
            <!--<Button  type="primary" @click="setImage">拍照</Button>-->
            <!--<img :src="imgSrc" alt="" class="tx_img">-->
        </div>



    </div>
</template>
<script>
    require("tracking/build/tracking-min.js");
    require("tracking/build/data/face-min.js");
    require("tracking/build/data/mouth-min.js");
    require("tracking/examples/assets/stats.min.js");
    export default {
        props:['src'],
        data () {
            return {
                videoWidth: 900,
                videoHeight: 700,
                videoArr:[],//所有的摄像头
                modelSel:'',//
                myInterval: null,
                imgSrc: '',
                isHasFace:false,//默认没有人脸
                tracker:null,
            }
        },
        created(){
        },
        mounted(){
            this.callCamera();
            this.changePhoto();
            this.checkFace();
            if(this.src!='user'){
                this.myInterval = setInterval(()=>{
                    this.setImage();
                },2000)
            }
        },
        methods: {
            // 调用摄像头
            callCamera () {
                // H5调用电脑摄像头API
                navigator.mediaDevices.getUserMedia({
                    video: true
                }).then(success => {
                    // 摄像头开启成功
                    this.$refs['video'].srcObject = success
                    // 实时拍照效果
                    this.$refs['video'].play()
                }).catch(error => {
                    console.error('摄像头开启失败,请检查摄像头是否可用!')
                })
            },
            // 拍照
            setImage () {
                console.log(this.isHasFace);
                if(!this.isHasFace){
                    return false;
                }
                let ctx = this.$refs['canvas'].getContext('2d')
                // 把当前视频帧内容渲染到canvas上
                ctx.drawImage(this.$refs['video'], 0, 0,  this.videoWidth, this.videoHeight)
                // 转base64格式、图片格式转换、图片质量压缩---支持两种格式image/jpeg+image/png
                let imgBase64 = this.$refs['canvas'].toDataURL('image/jpeg');
                this.imgSrc = imgBase64;
                this.$emit('refreshDataList', imgBase64)
                return true;
                /**------------到这里为止,就拿到了base64位置的地址,后面是下载功能----------*/

                    // 由字节转换为KB 判断大小
                // let str = imgBase64.replace('data:image/jpeg;base64,', '')
                // let strLength = str.length
                // let fileLength = parseInt(strLength - (strLength / 8) * 2)    // 图片尺寸  用于判断
                // let size = (fileLength / 1024).toFixed(2)
                // console.log(size)     // 上传拍照信息  调用接口上传图片 .........
                //
                // // 保存到本地
                // let ADOM = document.createElement('a')
                // ADOM.href = this.headImgSrc
                // ADOM.download = new Date().getTime() + '.jpeg'
                // ADOM.click()
            },
            // 关闭摄像头
            closeCamera () {
                if (!this.$refs['video'].srcObject) return
                let stream = this.$refs['video'].srcObject
                let tracks = stream.getTracks()
                tracks.forEach(track => {
                    track.stop()
                })
                this.$refs['video'].srcObject = null
            },


            //切换本地摄像头
            changePhoto(){
                /**得到所有的设备*/
                navigator.mediaDevices.enumerateDevices()
                    .then((devices)=> {
                        console.log(devices)
                        this.videoArr = [];
                        devices.forEach((device)=> {
                            if(device.kind == 'videoinput'){
                                this.videoArr.push({
                                    'label': device.label,
                                    'id': device.deviceId
                                })
                            }

                        });
                    })
                    .catch(function(err) {
                        layer.msg(err.name + ": " + err.message);
                    });
            },
            //切换下拉
            changeSel(val){
                const videoConstraints = {};
                if (val === '') {
                    videoConstraints.facingMode = 'environment';
                } else {
                    videoConstraints.deviceId = { exact: val };
                }
                var constraints = {
                    video: videoConstraints,
                };
                this.getUserMedia(constraints);

            },

            /**打开摄像头*/
           getUserMedia(constraints, success, error) {
                    if (navigator.mediaDevices.getUserMedia) {
                        //最新的标准API
                        navigator.mediaDevices.getUserMedia(constraints).then(success=>{
                            // 摄像头开启成功
                            this.$refs['video'].srcObject = success
                            // 实时拍照效果
                            this.$refs['video'].play()
                        }).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);
                    }
                },


            /**
             * 检查取景框是否有人脸
             * */
            checkFace() {
                var video = document.getElementById("video");
                var canvas = document.getElementById("canvas");
                var context = canvas.getContext("2d");

                this.tracker = new tracking.ObjectTracker("face");
                this.tracker.setInitialScale(4);
                this.tracker.setStepSize(2);
                this.tracker.setEdgesDensity(0.1);
                this.trackerTask = tracking.track("#video",  this.tracker, { camera: true });
                let self = this;
                this.tracker.on("track", event=> {
                    if (event.data.length <= 0) {
                        self.setFace(false);
                        return;
                    }
                    self.setFace(true);
                    context.clearRect(0, 0, canvas.width, canvas.height);
                    event.data.forEach(function (rect) {
                        context.strokeStyle = '#a64ceb';
                        context.strokeRect(rect.x, rect.y, rect.width, rect.height);
                        context.font = '11px Helvetica';
                        context.fillStyle = "#fff";
                        context.fillText('x: ' + rect.x + 'px', rect.x + rect.width + 5, rect.y + 11);
                        context.fillText('y: ' + rect.y + 'px', rect.x + rect.width + 5, rect.y + 22);
                    });
                });
            },
            setFace(data){
                this.isHasFace = data;
            }



        },

        beforeDestroy () {
            clearInterval(this.myInterval);
            // 停止侦测
            this.trackerTask.stop();
        }

    }
</script>
<style lang="less" scoped>
    .testTracking {
        min-height: 700px;
        width: 100%;
        position: relative;
        > * {
            position: absolute;
            left: 0;
            right: 0;
            margin: auto;
        }
        video,
        canvas {
            top: 0;
        }
        .buttonDiv {
            bottom: 10px;
        }
    }
</style>

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

vue实现拍照人脸识别功能带人脸选中框 的相关文章

随机推荐

  • mq的基本介绍和基本用法

    1 什么是MQ 有什么用 MQ 是message queue 消息队列 也叫消息中间件 遵守JMS java message service 规范的一种软件 同时还有另一个叫AMQP的应用层协议 语言无关性不受产品 语言等限制 rabbit
  • Java按顺序打印数字的每一位详解

    题目要求 输入一个数字 按顺序打印一个数字的每一位 例如 1234 打印出 1 2 3 4 用递归实现 实现代码 import java util Scanner public class blank40 public static voi
  • aarch64架构CPU的docker中ubuntu18.04,20.04,22.04等系统apt update均报错的原因

    宿主及环境为aarch64的CPU的Ubuntu18 04 docker版本为自带的19 03 6 对于Ubuntu14 04 16 04 18 04这个原因很乌龙 之前百度搜索结果也都不对 最终原因竟然只是因为网络问题 早上8点左右我到公
  • PySide2按钮传递参数以及*args,**kargs的含义

    1 PySide2按钮传递参数 lambda 表达式 self set priV on set clicked connect lambda self set priV con 1 def set priV con self valueV
  • Communications link failure问题解决方案摸索

    性能测试发现了Communications link failure错误 搜寻了网络上的好多种解决方案 记录总结一下 错误信息 Communications link failure The last packet sent success
  • 1037 在霍格沃茨找零钱

    1037 在霍格沃茨找零钱 20 20 分 如果你是哈利 波特迷 你会知道魔法世界有它自己的货币系统 就如海格告诉哈利的 十七个银西可 Sickle 兑一个加隆 Galleon 二十九个纳特 Knut 兑一个西可 很容易 现在 给定哈利应付
  • python读取文件时出现\ufeff非法字符的处理思路

    现象 系统环境 操作系统 Microsoft Windows 10 家庭中文版 10 0 1904 Python Python 3 8 8 问题 如下图所示 利用python读取文件后 在对字符串进行处理时 会出现 ufeff字符 这对基于
  • python读取excel成绩表,并设置柱状图

    目录 1 导入相关的包 2 读取excel文件 提取语文的数据 3 画柱状图的代码 4 完整代码 5 效果图 1 导入相关的包 import pandas as pd import matplotlib pyplot as plt 2 读取
  • 网管员牢记 10种较为常见的服务器管理错误

    网管员牢记 10种较为常见的服务器管理错误 网络管理阶层的工作就是保证网络的正常工作 从而使得职工们的工作不被打断 可问题在于事物并非总是按照理想状况发展 事实上经常会出现平地起风波的状况 其间有许多原因 这里我们只讨论10种较为常见的网管
  • angular 4 httpClient 数据访问

    服务里 是用来请求api的一个模块 使用httpClient服务请求数据常用方法如下 http get url subscribe export class ApiService 登录 一种是url是不变的 只需传参 login userN
  • VS项目属性的一些配置项的总结(important)

    以下内容为 原创 转载 首先 解决方案和项目文件夹包含关系 c 项目 VS解决方案和各个项目文件夹以及解决方案和各个项目对应的配置文件包含关系 假设新建一个项目ssyy 解决方案起名fangan 注意解决方案包括项目 此时生成的最外层目录为
  • 性能诊断定位之内存问题排查(四):CentOS7系统中,JVM内存诊断

    目录 1 要求 2 处理思路 3 示例演示 CentOS7 环境中 3 1 环境工具 3 2 操作步骤 3 2 1 JForum环境配置 配置在tomcat中 启动Tomcat 3 2 2 编写JMeter脚本 脚本的编写和运行 在win1
  • C#实现FTP文件夹下载功能【转载】

    网上有很多FTP单个文件下载的方法 前段时间需要用到一个FTP文件夹下载的功能 于是找了下网上的相关资料结合MSDN实现了一段FTP文件夹下载的代码 实现的思路主要是通过遍历获得文件夹下的所有文件 当然 文件夹下可能仍然存在文件夹 这样就需
  • 禁用CEF跟随系统的DPI缩放

    方法1 为程序添加启动参数 high dpi support 1 force device scale factor 1 1 在桌面上右键Chrome图标 选择属性 2 在目标一栏中增加自定义参数 force device scale fa
  • 文字图像转换的创新技术

    随着科技的快速发展 人工智能 AI 已经逐渐融入我们的日常生活 而 生成式 AI 更是引领着 AI 领域的新一轮革命 生成式 AI 是一种能够从文字描述中提取信息 并将其转化为图像或其他形式内容的技术 如今 这种技术正在逐渐改变我们与计算机
  • 线程生命周期(状态)

    1 线程生命周期 状态 当线程被创建并启动以后 它既不是一启动就进入了执行状态 也不是一直处于执行状态 在线程的生命周期中 它要经过新建 New 就绪 Runnable 运行 Running 阻塞 Blocked 和死亡 Dead 5 种状
  • python 字符串大小写转换 其它不变_ython字符串大小写转换(3种)函数及用法

    Python 中 为了方便对字符串中的字母进行大小写转换 字符串变量提供了 3 种方法 分别是 title lower 和 upper https www furuihua cn shenzhen longhua Python title
  • springboot注解--基础--01--注解

    springboot注解 基础 01 注解 https blog csdn net zhou920786312 article details 130844305 https blog csdn net zhou920786312 arti
  • vue启动报错vue-cli-service: command not found

    要配置环境变量以便能够在任意位置使用 Vue CLI 你可以按照以下步骤操作 确保已经全局安装了 Vue CLI 如果尚未安装 请使用以下命令进行全局安装 Copy Code npm install g vue cli 打开命令行终端 并输
  • vue实现拍照人脸识别功能带人脸选中框

    前言 实现打开摄像头 并识别人脸 实现效果 实现步骤 一 安装 1 官网下载 tracking js 的代码包官网入口 2 npm下载 执行命令 cnpm install tracking save 二 demo案例代码