欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

如何使用VUE+faceApi.js實(shí)現(xiàn)攝像頭拍攝人臉識(shí)別

 更新時(shí)間:2023年05月04日 11:59:27   作者:BarryKerrigan  
Face-api.js是一個(gè)JavaScript API,是基于tensorflow.js核心API 的人臉檢測(cè)和人臉識(shí)別的瀏覽器實(shí)現(xiàn),這篇文章主要給大家介紹了關(guān)于如何使用VUE+faceApi.js實(shí)現(xiàn)攝像頭拍攝人臉識(shí)別的相關(guān)資料,需要的朋友可以參考下

需求:

前端獲取到攝像頭信息,通過模型來(lái)進(jìn)行判斷人像是否在鏡頭中,鏡頭是否有被遮擋。

實(shí)現(xiàn)步驟:

1、通過video標(biāo)簽來(lái)展示攝像頭中的內(nèi)容

2、通過canvas來(lái)繪制視頻中信息進(jìn)行展示

3、在拍照時(shí)候?qū)anvas的當(dāng)前幀轉(zhuǎn)成圖片

第一步:下載引入必要包

下載依賴

face-api.js是核心依賴必須要下

npm install face-api.js

element-ui為了按鈕好看一點(diǎn)(可以不下) ,axios用于請(qǐng)求發(fā)送

npm istall element-ui axios -S

 element-ui根據(jù)官方文檔進(jìn)行引入使用

import Vue from 'vue';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import App from './App.vue';
Vue.use(ElementUI);
new Vue({
  el: '#app',
  render: h => h(App)
});

下載model

下載地址: 模板地址

將項(xiàng)目中的model放入VUE中的public文件加下

第二步:先把HTML寫上去 

<template>
    <div>
        <el-button type="primary" @click="useCamera">打開攝像頭</el-button>
        <el-button type="plain" @click="photoShoot">拍照</el-button>
        <el-alert
            :title="httpsAlert"
            type="info"
            :closable="false"
            v-show="httpsAlert !== ''">
        </el-alert>
        <div class="videoImage" ref="faceBox">
            <video ref="video" style="display: none;"></video>
            <canvas ref="canvas" width="400" height="400" v-show="videoShow"></canvas>
            <img ref="image" :src="picture" alt="" v-show="pictureShow">
        </div>
    </div>
</template>

第三步 可以開始代碼了

首先引入下載好的face-api.js包

import * as faceApi from 'face-api.js'

 以下是需要用到的屬性

1、視頻和圖片不同時(shí)出現(xiàn)

videoShow: false,
pictureShow: false,

2、生成圖片后用于保存圖片路徑

picture: '',

3、因?yàn)樵诓僮鲿r(shí)會(huì)用到DOM所以將要用到虛擬DOM保存在data中

canvas: null,
video: null,
image: null,

 4、模型識(shí)別時(shí)直接傳入此屬性,在初始化時(shí)賦值(可省略,直接卸載邏輯代碼中)

options: ''

 5、在人臉識(shí)別時(shí)對(duì)結(jié)果進(jìn)行反饋(識(shí)別出人像數(shù)量大于1或小于1時(shí)給出提示)

noOne: '',
moreThanOne: '',

6、如果用戶不是在https下進(jìn)行使用攝像頭調(diào)用給出提示

httpsAlert: ''

屬性準(zhǔn)備好之后就可以開始初始化了

1、初始化模型

2、獲取需要用到的虛擬DOM

async init() {
    await faceApi.nets.ssdMobilenetv1.loadFromUri("/models");
    await faceApi.loadFaceLandmarkModel("/models");
    this.options = new faceApi.SsdMobilenetv1Options({
        minConfidence: 0.5, // 0.1 ~ 0.9
    });
    // 視頻中識(shí)別使用的節(jié)點(diǎn)
    this.video = this.$refs.video
    this.canvas = this.$refs.canvas
    this.image = this.$refs.image
}

調(diào)用攝像頭

通過navigator.mediaDevices.getUserMedia()

useCamera(){
    this.videoShow = true
    this.pictureShow = false
    this.cameraOptions()
},
cameraOptions(){
    let constraints = {
        video: {
            width: 400,
            height: 400
        }
    }
    // 如果不是通過loacalhost或者通過https訪問會(huì)將報(bào)錯(cuò)捕獲并提示
    try{
        let promise = navigator.mediaDevices.getUserMedia(constraints);
        promise.then((MediaStream) => {
            // 返回參數(shù)
            this.video.srcObject = MediaStream;
            this.video.play();
            this.recognizeFace()
        }).catch((error) => {
            console.log(error);
        });
    }catch(err){
        this.httpsAlert = `您現(xiàn)在在使用非Https訪問,
        請(qǐng)先在chrome://flags/#unsafely-treat-insecure-origin-as-secure中修改配置,
        添將當(dāng)前鏈接${window.location.href}添加到列表,
        并且將Insecure origins treated as secure修改為enabled,
        修改完成后請(qǐng)重啟瀏覽器后再次訪問!`
    }
}

識(shí)別視頻中的人像

這里通過遞歸的方式將視頻中的內(nèi)容用canvas顯示

將canvas的節(jié)點(diǎn)傳入到faceApi的方法中進(jìn)行識(shí)別

通過faceApi返回的數(shù)組可以得到當(dāng)前人臉的識(shí)別狀況(數(shù)組長(zhǎng)度0沒有識(shí)別到人臉,長(zhǎng)度1識(shí)別到一個(gè)人臉...以此類推)

async recognizeFace(){
    if (this.video.paused) return clearTimeout(this.timeout);
    this.canvas.getContext('2d', { willReadFrequently: true }).drawImage(this.video, 0, 0, 400, 400);
    const results = await faceApi.detectAllFaces(this.canvas, this.options).withFaceLandmarks();
    if(results.length === 0){
        if(this.moreThanOne !== ''){
            this.moreThanOne.close()
            this.moreThanOne = ''
        }
        if(this.noOne === ''){
            this.noOne = this.$message({
                message: '未識(shí)別到人臉',
                type: 'warning',
                duration: 0
            });
        }
    }else if(results.length > 1){
        if(this.noOne !== ''){
            this.noOne.close()
            this.noOne = ''
        }
        if(this.moreThanOne === ''){
            this.moreThanOne = this.$message({
                message: '檢測(cè)到鏡頭中有多個(gè)人',
                type: 'warning',
                duration: 0
            });
        }
    }else{
        if(this.noOne !== ''){
            this.noOne.close()
            this.noOne = ''
        }
        if(this.moreThanOne !== ''){
            this.moreThanOne.close()
            this.moreThanOne = ''
        }
    }
    this.timeout = setTimeout(() => {
        return this.recognizeFace()
    });
},

拍照上傳 

async photoShoot(){
    // 拿到圖片的base64
    let canvas = this.canvas.toDataURL("image/png");
    // 拍照以后將video隱藏
    this.videoShow = false
    this.pictureShow = true
    // 停止攝像頭成像
    this.video.srcObject.getTracks()[0].stop()
    this.video.pause()
    if(canvas) {
        // 拍照將base64轉(zhuǎn)為file流文件
        let blob = this.dataURLtoBlob(canvas);
        let file = this.blobToFile(blob, "imgName");
        // 將blob圖片轉(zhuǎn)化路徑圖片
        let image = window.URL.createObjectURL(file)
        this.picture = image
        return
        let formData = new FormData()
        formData.append('file', this.picture)
        axios({
            method: 'post',
            url: '/user/12345',
            data: formData
        }).then(res => {
            console.log(res)
        }).catch(err => {
            console.log(err)
        })
    } else {
        console.log('canvas生成失敗')
    }
},

需要用到的圖片格式轉(zhuǎn)換方法 

方法1:先將base64轉(zhuǎn)為文件

方法2:設(shè)置新的文件中的參數(shù)信息

dataURLtoBlob(dataurl) {
    let arr = dataurl.split(','),
        mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]),
        n = bstr.length,
        u8arr = new Uint8Array(n);
    while(n--) {
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new Blob([u8arr], {
        type: mime
    });
},
blobToFile(theBlob, fileName) {
    theBlob.lastModifiedDate = new Date().toLocaleDateString();
    theBlob.name = fileName;
    return theBlob;
},

完整代碼

import bingImage from '@/assets/bbt1.jpg';
import BingWallpaper from '@/assets/BingWallpaper.jpg';
import * as faceApi from 'face-api.js'
export default {
    name: 'Recognize',
    data(){
        return{
            videoShow: false,
            pictureShow: false,
            // 圖片地址
            picture: '',
            // 用于視頻識(shí)別的節(jié)點(diǎn)
            canvas: null,
            video: null,
            image: null,
            timeout: 0,
            // 模型識(shí)別的條件
            options: '',
            // 提示控制
            noOne: '',
            moreThanOne: '',
            // 不是通過Https訪問提示
            httpsAlert: '',
        }
    },
    mounted() {
        // 初始化
        this.init()
    },
    beforeDestroy() {
        clearTimeout(this.timeout);
    },
    methods: {
        async init() {
            await faceApi.nets.ssdMobilenetv1.loadFromUri("/models");
            await faceApi.loadFaceLandmarkModel("/models");
            this.options = new faceApi.SsdMobilenetv1Options({
                minConfidence: 0.5, // 0.1 ~ 0.9
            });
            // 視頻中識(shí)別使用的節(jié)點(diǎn)
            this.video = this.$refs.video
            this.canvas = this.$refs.canvas
            this.image = this.$refs.image
        },
        /**
         * 使用視頻來(lái)成像攝像頭
         */
        useCamera(){
            this.videoShow = true
            this.pictureShow = false
            this.cameraOptions()
        },
        /**
         * 使用攝像頭
         */
        cameraOptions(){
            let constraints = {
                video: {
                    width: 400,
                    height: 400
                }
            }
            // 如果不是通過loacalhost或者通過https訪問會(huì)將報(bào)錯(cuò)捕獲并提示
            try{
                let promise = navigator.mediaDevices.getUserMedia(constraints);
                promise.then((MediaStream) => {
                    // 返回參數(shù)
                    this.video.srcObject = MediaStream;
                    this.video.play();
                    this.recognizeFace()
                }).catch((error) => {
                    console.log(error);
                });
            }catch(err){
                this.httpsAlert = `您現(xiàn)在在使用非Https訪問,
                請(qǐng)先在chrome://flags/#unsafely-treat-insecure-origin-as-secure中修改配置,
                添將當(dāng)前鏈接${window.location.href}添加到列表,
                并且將Insecure origins treated as secure修改為enabled,
                修改完成后請(qǐng)重啟瀏覽器后再次訪問!`
            }
        },
        /**
         * 人臉識(shí)別方法
         * 通過canvas節(jié)點(diǎn)識(shí)別
         * 節(jié)點(diǎn)對(duì)象執(zhí)行遞歸識(shí)別繪制
         */
        async recognizeFace(){
            if (this.video.paused) return clearTimeout(this.timeout);
            this.canvas.getContext('2d', { willReadFrequently: true }).drawImage(this.video, 0, 0, 400, 400);
            const results = await faceApi.detectAllFaces(this.canvas, this.options).withFaceLandmarks();
            if(results.length === 0){
                if(this.moreThanOne !== ''){
                    this.moreThanOne.close()
                    this.moreThanOne = ''
                }
                if(this.noOne === ''){
                    this.noOne = this.$message({
                        message: '未識(shí)別到人臉',
                        type: 'warning',
                        duration: 0
                    });
                }
            }else if(results.length > 1){
                if(this.noOne !== ''){
                    this.noOne.close()
                    this.noOne = ''
                }
                if(this.moreThanOne === ''){
                    this.moreThanOne = this.$message({
                        message: '檢測(cè)到鏡頭中有多個(gè)人',
                        type: 'warning',
                        duration: 0
                    });
                }
            }else{
                if(this.noOne !== ''){
                    this.noOne.close()
                    this.noOne = ''
                }
                if(this.moreThanOne !== ''){
                    this.moreThanOne.close()
                    this.moreThanOne = ''
                }
            }
            // 通過canvas顯示video信息
            this.timeout = setTimeout(() => {
                return this.recognizeFace()
            });
        },
        /**
         * 拍照上傳
         */
        async photoShoot(){
            // 拿到圖片的base64
            let canvas = this.canvas.toDataURL("image/png");
            // 拍照以后將video隱藏
            this.videoShow = false
            this.pictureShow = true
            // 停止攝像頭成像
            this.video.srcObject.getTracks()[0].stop()
            this.video.pause()
            if(canvas) {
                // 拍照將base64轉(zhuǎn)為file流文件
                let blob = this.dataURLtoBlob(canvas);
                console.log(blob)
                let file = this.blobToFile(blob, "imgName");
                console.info(file);
                // 將blob圖片轉(zhuǎn)化路徑圖片
                let image = window.URL.createObjectURL(file)
                this.picture = image
                // 將拍照后的圖片發(fā)送給后端
                let formData = new FormData()
                formData.append('file', this.picture)
                axios({
                    method: 'post',
                    url: '/user/12345',
                    data: formData
                }).then(res => {
                    console.log(res)
                }).catch(err => {
                    console.log(err)
                })
            } else {
                console.log('canvas生成失敗')
            }
        },
        /**
         * 將圖片轉(zhuǎn)為blob格式
         * dataurl 拿到的base64的數(shù)據(jù)
         */
        dataURLtoBlob(dataurl) {
            let arr = dataurl.split(','),
                mime = arr[0].match(/:(.*?);/)[1],
                bstr = atob(arr[1]),
                n = bstr.length,
                u8arr = new Uint8Array(n);
            while(n--) {
                u8arr[n] = bstr.charCodeAt(n);
            }
            return new Blob([u8arr], {
                type: mime
            });
        },
        /**
         * 生成文件信息
         * theBlob 文件
         * fileName 文件名字
         */
        blobToFile(theBlob, fileName) {
            theBlob.lastModifiedDate = new Date().toLocaleDateString();
            theBlob.name = fileName;
            return theBlob;
        },
    }
}

總結(jié)

到此這篇關(guān)于如何使用VUE+faceApi.js實(shí)現(xiàn)攝像頭拍攝人臉識(shí)別的文章就介紹到這了,更多相關(guān)VUE faceApi.js攝像頭拍攝人臉識(shí)別內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue父子組件的通信方法(實(shí)例詳解)

    vue父子組件的通信方法(實(shí)例詳解)

    這篇文章主要介紹了vue父子組件的通信的方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-11-11
  • vue頁(yè)面切換項(xiàng)目實(shí)現(xiàn)轉(zhuǎn)場(chǎng)動(dòng)畫的方法

    vue頁(yè)面切換項(xiàng)目實(shí)現(xiàn)轉(zhuǎn)場(chǎng)動(dòng)畫的方法

    這篇文章主要介紹了vue頁(yè)面切換項(xiàng)目實(shí)現(xiàn)轉(zhuǎn)場(chǎng)動(dòng)畫的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • Vue顯示圖片的幾種方式小結(jié)

    Vue顯示圖片的幾種方式小結(jié)

    本文主要介紹了Vue顯示圖片的幾種方式小結(jié),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • Element Input組件分析小結(jié)

    Element Input組件分析小結(jié)

    這篇文章主要介紹了Element Input組件分析小結(jié),詳細(xì)的介紹了Input組件的使用,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧
    2018-10-10
  • 一文徹底教會(huì)你在vue中寫jsx

    一文徹底教會(huì)你在vue中寫jsx

    以前我們經(jīng)常在react中使用jsx,現(xiàn)在我們?cè)趘ue中也是用jsx,下面這篇文章主要給大家介紹了關(guān)于在vue中寫jsx的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-06-06
  • 如何根據(jù)業(yè)務(wù)封裝自己的功能組件

    如何根據(jù)業(yè)務(wù)封裝自己的功能組件

    這篇文章主要介紹了Vue封裝功能組件,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • VueAwesomeSwiper在VUE中的使用以及遇到的一些問題

    VueAwesomeSwiper在VUE中的使用以及遇到的一些問題

    這篇文章主要介紹了VueAwesomeSwiper在VUE中的使用以及遇到的一些問題,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧
    2018-01-01
  • vue中v-model失效原因以及解決方案

    vue中v-model失效原因以及解決方案

    這篇文章主要給大家介紹了關(guān)于vue中v-model失效原因以及解決方案的相關(guān)資料,vue的v-model是一個(gè)雙向綁定的數(shù)據(jù)流,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-07-07
  • unplugin-vue-components解決命名沖突問題

    unplugin-vue-components解決命名沖突問題

    這篇文章主要介紹了unplugin-vue-components解決命名沖突問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • vue3?自定義指令控制按鈕權(quán)限的操作代碼

    vue3?自定義指令控制按鈕權(quán)限的操作代碼

    這篇文章主要介紹了vue3?自定義指令控制按鈕權(quán)限,為了提高用戶體驗(yàn),當(dāng)該按鈕無(wú)權(quán)使用時(shí),使用el-tooltip功能進(jìn)行提醒,結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-10-10

最新評(píng)論