您好,登錄后才能下訂單哦!
這篇文章主要講解了“怎么使用VUE+faceApi.js實現攝像頭拍攝人臉識別”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“怎么使用VUE+faceApi.js實現攝像頭拍攝人臉識別”吧!
前端獲取到攝像頭信息,通過模型來進行判斷人像是否在鏡頭中,鏡頭是否有被遮擋。
1、通過video標簽來展示攝像頭中的內容
2、通過canvas來繪制視頻中信息進行展示
3、在拍照時候將canvas的當前幀轉成圖片
face-api.js是核心依賴必須要下
npm install face-api.js
element-ui為了按鈕好看一點(可以不下) ,axios用于請求發送
npm istall element-ui axios -S
element-ui根據官方文檔進行引入使用
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) });
<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" ></video> <canvas ref="canvas" width="400" height="400" v-show="videoShow"></canvas> <img ref="image" :src="picture" alt="" v-show="pictureShow"> </div> </div> </template>
import * as faceApi from 'face-api.js'
1、視頻和圖片不同時出現
videoShow: false, pictureShow: false,
2、生成圖片后用于保存圖片路徑
picture: '',
3、因為在操作時會用到DOM所以將要用到虛擬DOM保存在data中
canvas: null, video: null, image: null,
4、模型識別時直接傳入此屬性,在初始化時賦值(可省略,直接卸載邏輯代碼中)
options: ''
5、在人臉識別時對結果進行反饋(識別出人像數量大于1或小于1時給出提示)
noOne: '', moreThanOne: '',
6、如果用戶不是在https下進行使用攝像頭調用給出提示
httpsAlert: ''
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 }); // 視頻中識別使用的節點 this.video = this.$refs.video this.canvas = this.$refs.canvas this.image = this.$refs.image }
通過navigator.mediaDevices.getUserMedia()
useCamera(){ this.videoShow = true this.pictureShow = false this.cameraOptions() }, cameraOptions(){ let constraints = { video: { width: 400, height: 400 } } // 如果不是通過loacalhost或者通過https訪問會將報錯捕獲并提示 try{ let promise = navigator.mediaDevices.getUserMedia(constraints); promise.then((MediaStream) => { // 返回參數 this.video.srcObject = MediaStream; this.video.play(); this.recognizeFace() }).catch((error) => { console.log(error); }); }catch(err){ this.httpsAlert = `您現在在使用非Https訪問, 請先在chrome://flags/#unsafely-treat-insecure-origin-as-secure中修改配置, 添將當前鏈接${window.location.href}添加到列表, 并且將Insecure origins treated as secure修改為enabled, 修改完成后請重啟瀏覽器后再次訪問!` } }
這里通過遞歸的方式將視頻中的內容用canvas顯示
將canvas的節點傳入到faceApi的方法中進行識別
通過faceApi返回的數組可以得到當前人臉的識別狀況(數組長度0沒有識別到人臉,長度1識別到一個人臉...以此類推)
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: '未識別到人臉', 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: '檢測到鏡頭中有多個人', 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轉為file流文件 let blob = this.dataURLtoBlob(canvas); let file = this.blobToFile(blob, "imgName"); // 將blob圖片轉化路徑圖片 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生成失敗') } },
方法1:先將base64轉為文件
方法2:設置新的文件中的參數信息
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: '', // 用于視頻識別的節點 canvas: null, video: null, image: null, timeout: 0, // 模型識別的條件 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 }); // 視頻中識別使用的節點 this.video = this.$refs.video this.canvas = this.$refs.canvas this.image = this.$refs.image }, /** * 使用視頻來成像攝像頭 */ useCamera(){ this.videoShow = true this.pictureShow = false this.cameraOptions() }, /** * 使用攝像頭 */ cameraOptions(){ let constraints = { video: { width: 400, height: 400 } } // 如果不是通過loacalhost或者通過https訪問會將報錯捕獲并提示 try{ let promise = navigator.mediaDevices.getUserMedia(constraints); promise.then((MediaStream) => { // 返回參數 this.video.srcObject = MediaStream; this.video.play(); this.recognizeFace() }).catch((error) => { console.log(error); }); }catch(err){ this.httpsAlert = `您現在在使用非Https訪問, 請先在chrome://flags/#unsafely-treat-insecure-origin-as-secure中修改配置, 添將當前鏈接${window.location.href}添加到列表, 并且將Insecure origins treated as secure修改為enabled, 修改完成后請重啟瀏覽器后再次訪問!` } }, /** * 人臉識別方法 * 通過canvas節點識別 * 節點對象執行遞歸識別繪制 */ 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: '未識別到人臉', 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: '檢測到鏡頭中有多個人', 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轉為file流文件 let blob = this.dataURLtoBlob(canvas); console.log(blob) let file = this.blobToFile(blob, "imgName"); console.info(file); // 將blob圖片轉化路徑圖片 let image = window.URL.createObjectURL(file) this.picture = image // 將拍照后的圖片發送給后端 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生成失敗') } }, /** * 將圖片轉為blob格式 * dataurl 拿到的base64的數據 */ 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; }, } }
感謝各位的閱讀,以上就是“怎么使用VUE+faceApi.js實現攝像頭拍攝人臉識別”的內容了,經過本文的學習后,相信大家對怎么使用VUE+faceApi.js實現攝像頭拍攝人臉識別這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。