H5人脸识别(tracking.js),并保存人脸为图片(也可保存人脸部分)

编程入门 行业动态 更新时间:2024-10-24 19:14:45

H5人脸识别(tracking.js),并保存人脸为图片(<a href=https://www.elefans.com/category/jswz/34/1765339.html style=也可保存人脸部分)"/>

H5人脸识别(tracking.js),并保存人脸为图片(也可保存人脸部分)

目录

  • 1. H5人脸识别功能
    • 1.第三方库 tracking.js
    • 2. 判断有无摄像头权限
    • 3. 打开摄像头,并开始监听
    • 4. 监听到人脸后自动截取当前帧并保存为图片-tackPhoto()
    • 5.计算图片裁剪或者摆放位置(如果不需要不写)
    • 所有内容
  • 2. 微信小程序人脸识别功能-附带扫脸动画

1. H5人脸识别功能

1.第三方库 tracking.js

前端人脸识别框架:
下载zip包获取里面的 face.min.js 及 tracking-min.js

<script src="./js/tracking-min.js"></script>
<script src="./js/face-min.js"></script>

2. 判断有无摄像头权限

			if (navigator.mediaDevices === undefined) {navigator.mediaDevices = {}}if (navigator.mediaDevices.getUserMedia === undefined) {navigator.mediaDevices.getUserMedia = function(constraints) {var getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia;if (!getUserMedia) {return Promise.reject(new Error("getUserMedia is not implemented in this browser"));}return new Promise(function(resolve, reject) {getUserMedia.call(navigator, constraints, resolve, reject);})}}navigator.mediaDevices.getUserMedia({audio: false,video: {facingMode: "environment"}}).then(function(stream) {})

3. 打开摄像头,并开始监听

			navigator.mediaDevices.getUserMedia({audio: false,video: {facingMode: "environment"}}).then(function(stream) {// 使用监听人脸的包tracker.setInitialScale(4);tracker.setStepSize(2);tracker.setEdgesDensity(0.1);//打开摄像头var tra = tracking.track('#video_bind', tracker, {camera: true});var timer = null;// 创建监听 每帧都会触发tracker.on('track', function(event) {if (!tipFlag) {facecontext.clearRect(0, 0, facecanvas.width, facecanvas.height);if (event.data.length === 0) {//未检测到人脸if (!faceflag && !timer) {timer = setTimeout(() => {informationTitle.innerHTML = '未检测到人脸'}, 500)}} else if (event.data.length === 1) { // 长度为多少代表检测到几张人脸window.clearTimeout(timer);timer = null;informationTitle.innerHTML = '请将脸部置于屏幕中央';//检测到一张人脸if (!tipFlag) {// 给检测到的人脸绘制矩形event.data.forEach(function(rect) {facecontext.strokeStyle = '#a64ceb';facecontext.strokeRect(rect.x, rect.y, rect.width, rect.height);});let rect = event.data[0];//判断脸部是否在屏幕中间if (!faceflag && rect.x > facevideo.clientWidth * 0.3 && rect.x < facevideo.clientWidth * 0.7) { // 检测到人脸进行拍照,延迟0.5秒informationTitle.innerHTML = '识别中,请勿乱动~';faceflag = true;tipFlag = true;setTimeout(() => {tackPhoto() // 拍照}, 500);}}} else {//检测到多张人脸if (!faceflag) {informationTitle.innerHTML = '只可一人进行人脸识别!'}}}});}).catch(function(err) {informationTitle.innerHTML = '打开摄像头失败'})

4. 监听到人脸后自动截取当前帧并保存为图片-tackPhoto()

function tackPhoto() {// 为什么调用getObjectFitSize,因为摄像头获取的图片和绘制的图片大小和区域可能不一致// 所以需要把人脸置于屏幕中间,绘制中间部分图片,如果不需要直接调用第二种方式	const {sx,sy,swidth,sheight,x,y,width,height} = getObjectFitSize('cover', facevideo.clientWidth, facevideo.clientHeight, videoWidth, videoHeight)facecontext.drawImage(facevideo, sx, sy, swidth, sheight, x, y, width, height);// 第二种方式	// facecontext.drawImage(facevideo, 0, 0, facevideo.clientWidth, facevideo.clientHeight);var snapData = facecanvas.toDataURL('image/png');var imgSrc = "data:image/png;" + snapData;// document.querySelector("img").src = imgSrc;sessionStorage.setItem("faceImage", imgSrc);// history.go(-1);history.back()facevideo.srcObject.getTracks().forEach(track => track.stop());// 取消监听tra.stop();}

5.计算图片裁剪或者摆放位置(如果不需要不写)

/*** 计算图片裁剪或者摆放位置* @param {*} type  contain, cover 暂时只兼容这两个模式* @param {*} containerWidth  容器宽度* @param {*} containerHeight  容器高度* @param {*} imgWidth   图片宽度* @param {*} imgHeight  图片高度* @return {*} canvas drawImage的所有入参*/function getObjectFitSize(type = "cover",containerWidth,containerHeight,imgWidth,imgHeight) {let radio = 1, // 容器与图片的比例sx = 0, // 开始剪切的 x 坐标位置。sy = 0, // 开始剪切的 y 坐标位置。swidth = imgWidth, // 被剪切图像的宽度。sheight = imgHeight, // 被剪切图像的高度。x = 0, // 在画布上放置图像的 x 坐标位置。y = 0, // 在画布上放置图像的 y 坐标位置。width = containerWidth, // 要使用的图像的宽度(伸展或缩小图像)。height = containerHeight; // 要使用的图像的高度(伸展或缩小图像)。let cWHRatio = containerWidth / containerHeight;let iWHRatio = imgWidth / imgHeight;if (type === "cover") {// cover模式,需要裁剪if (iWHRatio >= cWHRatio) {// 横图,高先匹配,裁剪宽度radio = containerHeight / imgHeight;sx = (imgWidth - containerWidth / radio) / 2;swidth = containerWidth / radio;sheight = imgHeight;} else {// 竖图,宽先匹配,裁剪高度radio = containerWidth / imgWidth;sy = (imgHeight - containerHeight / radio) / 2;swidth = imgWidth;sheight = containerHeight / radio;}} else if (type === "contain") {if (iWHRatio >= cWHRatio) {// 横图,宽先匹配,高度自适应radio = containerWidth / imgWidth;y = (containerHeight - imgHeight * radio) / 2;height = imgHeight * radio;} else {// 竖图,高先匹配,宽度自适应radio = containerHeight / imgHeight;x = (containerWidth - imgWidth * radio) / 2;width = imgWidth * radio;}}return {sx,sy,swidth,sheight,x,y,width,height,};}

所有内容

		<style>#video_bind,#canvas_bind {width: 375rem;height: 486rem;object-fit: cover;}#canvas_bind {position: absolute;top: 0;z-index: 2;/* z-index: -1; */}.tip-box {margin-top: 32rem;font-size: 24rem;}</style><div><video width="375" height="486" id="video_bind" autoplay playsinline webkit-playsinline="true"></video><div class="tip-box text-center"></div><canvas id="canvas_bind"></canvas></div><script src="./js/tracking-min.js"></script><script src="./js/face-min.js"></script><script type="text/javascript">var tipFlag = false // 是否检测var faceflag = false // 是否进行拍照var informationTitle = document.querySelector(".tip-box") //人脸提示// 获取video、canvas实例var facevideo = document.getElementById('video_bind');var facecanvas = document.getElementById('canvas_bind');facecanvas.width = facecanvas.clientWidth;facecanvas.height = facecanvas.clientHeight;var videoWidth = videoHeight = 0facevideo.addEventListener('canplay', function() {videoWidth = this.videoWidth;videoHeight = this.videoHeight;});var facecontext = facecanvas.getContext('2d');var tracker = new tracking.ObjectTracker('face');// 每次打开弹框先清除canvas没拍的照片facecontext.clearRect(0, 0, facecanvas.width, facecanvas.height);if (navigator.mediaDevices === undefined) {navigator.mediaDevices = {}}if (navigator.mediaDevices.getUserMedia === undefined) {navigator.mediaDevices.getUserMedia = function(constraints) {var getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia;if (!getUserMedia) {return Promise.reject(new Error("getUserMedia is not implemented in this browser"));}return new Promise(function(resolve, reject) {getUserMedia.call(navigator, constraints, resolve, reject);})}}navigator.mediaDevices.getUserMedia({audio: false,video: {facingMode: "environment"}}).then(function(stream) {// 使用监听人脸的包tracker.setInitialScale(4);tracker.setStepSize(2);tracker.setEdgesDensity(0.1);//打开摄像头var tra = tracking.track('#video_bind', tracker, {camera: true});var timer = null;// 创建监听 每帧都会触发tracker.on('track', function(event) {if (!tipFlag) {facecontext.clearRect(0, 0, facecanvas.width, facecanvas.height);if (event.data.length === 0) {//未检测到人脸if (!faceflag && !timer) {timer = setTimeout(() => {informationTitle.innerHTML = '未检测到人脸'}, 500)}} else if (event.data.length === 1) { // 长度为多少代表检测到几张人脸window.clearTimeout(timer);timer = null;informationTitle.innerHTML = '请将脸部置于屏幕中央';//检测到一张人脸if (!tipFlag) {// 给检测到的人脸绘制矩形event.data.forEach(function(rect) {facecontext.strokeStyle = '#a64ceb';facecontext.strokeRect(rect.x, rect.y, rect.width, rect.height);});let rect = event.data[0];//判断脸部是否在屏幕中间if (!faceflag && rect.x > facevideo.clientWidth * 0.3 && rect.x < facevideo.clientWidth * 0.7) { // 检测到人脸进行拍照,延迟0.5秒informationTitle.innerHTML = '识别中,请勿乱动~';faceflag = true;tipFlag = true;setTimeout(() => {tackPhoto() // 拍照}, 500);}}} else {//检测到多张人脸if (!faceflag) {informationTitle.innerHTML = '只可一人进行人脸识别!'}}}});function tackPhoto() {// 为什么调用getObjectFitSize,因为摄像头获取的图片和绘制的图片大小和区域可能不一致// 所以需要把人脸置于屏幕中间,绘制中间部分图片,如果不需要直接调用第二种方式	const {sx,sy,swidth,sheight,x,y,width,height} = getObjectFitSize('cover', facevideo.clientWidth, facevideo.clientHeight, videoWidth, videoHeight)facecontext.drawImage(facevideo, sx, sy, swidth, sheight, x, y, width, height);// 第二种方式	// facecontext.drawImage(facevideo, 0, 0, facevideo.clientWidth, facevideo.clientHeight);var snapData = facecanvas.toDataURL('image/png');var imgSrc = "data:image/png;" + snapData;// document.querySelector("img").src = imgSrc;sessionStorage.setItem("faceImage", imgSrc);// history.go(-1);history.back()facevideo.srcObject.getTracks().forEach(track => track.stop());// 取消监听tra.stop();}}).catch(function(err) {informationTitle.innerHTML = '打开摄像头失败'})/*** 计算图片裁剪或者摆放位置* @param {*} type  contain, cover 暂时只兼容这两个模式* @param {*} containerWidth  容器宽度* @param {*} containerHeight  容器高度* @param {*} imgWidth   图片宽度* @param {*} imgHeight  图片高度* @return {*} canvas drawImage的所有入参*/function getObjectFitSize(type = "cover",containerWidth,containerHeight,imgWidth,imgHeight) {let radio = 1, // 容器与图片的比例sx = 0, // 开始剪切的 x 坐标位置。sy = 0, // 开始剪切的 y 坐标位置。swidth = imgWidth, // 被剪切图像的宽度。sheight = imgHeight, // 被剪切图像的高度。x = 0, // 在画布上放置图像的 x 坐标位置。y = 0, // 在画布上放置图像的 y 坐标位置。width = containerWidth, // 要使用的图像的宽度(伸展或缩小图像)。height = containerHeight; // 要使用的图像的高度(伸展或缩小图像)。let cWHRatio = containerWidth / containerHeight;let iWHRatio = imgWidth / imgHeight;if (type === "cover") {// cover模式,需要裁剪if (iWHRatio >= cWHRatio) {// 横图,高先匹配,裁剪宽度radio = containerHeight / imgHeight;sx = (imgWidth - containerWidth / radio) / 2;swidth = containerWidth / radio;sheight = imgHeight;} else {// 竖图,宽先匹配,裁剪高度radio = containerWidth / imgWidth;sy = (imgHeight - containerHeight / radio) / 2;swidth = imgWidth;sheight = containerHeight / radio;}} else if (type === "contain") {if (iWHRatio >= cWHRatio) {// 横图,宽先匹配,高度自适应radio = containerWidth / imgWidth;y = (containerHeight - imgHeight * radio) / 2;height = imgHeight * radio;} else {// 竖图,高先匹配,宽度自适应radio = containerHeight / imgHeight;x = (containerWidth - imgWidth * radio) / 2;width = imgWidth * radio;}}return {sx,sy,swidth,sheight,x,y,width,height,};}</script>

2. 微信小程序人脸识别功能-附带扫脸动画

详见:微信小程序人脸识别功能

更多推荐

H5人脸识别(tracking.js),并保存人脸为图片(也可保存人脸部分)

本文发布于:2024-03-04 21:07:23,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1710420.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:也可   脸部   并保存   图片   tracking

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!