当前位置: 首页 > wzjs >正文

国外 设计师 网站深圳方维网站建设

国外 设计师 网站,深圳方维网站建设,图片 网站源码,域名不变 网站改版1.前言 手势识别与检测的介绍: 手势识别与检测是计算机视觉和人工智能领域的重要研究方向,通过算法让计算机理解人类手势的含义,手势检测(Gesture Detection)表示定位图像与视频中手部的位置,手势识别(GestureRecognition)表示将检测到的手势氛围特定的语言,例如张开手掌,握拳…

1.前言

  • 手势识别与检测的介绍: 手势识别与检测是计算机视觉和人工智能领域的重要研究方向,通过算法让计算机理解人类手势的含义,手势检测(Gesture Detection)表示定位图像与视频中手部的位置,手势识别(GestureRecognition)表示将检测到的手势氛围特定的语言,例如张开手掌,握拳,点赞等手势
  • 前端实现手势的检测与识别的作用: 前端的本质就是用户与计算机的交互行为,手势的检测与识别可以拓展传统的点击行为交互方式

2.实现所使用的技术栈

  • Vue3+Vite+@mediapipe

@mediapipe是由 Google 开发的一个开源跨平台框架,专为​​实时多媒体处理​​(如手势识别、人脸检测、姿态估计等)设计,具有高效、轻量化和多硬件支持的特点,所以可以使用@mediapipe来在前端实现手势识别

3.源码讲解

  • 静态页面搭建
<template><div id="liveView" class="videoView"><video id="webcam" autoplay playsinline></video><canvas class="output_canvas" id="output_canvas"></canvas></div><div class="imgInfo"><p>识别到的手势:{{ videoGestureInfo.categoryName }}</p><p>相似度:{{ videoGestureInfo.categoryScore }}</p><p>左右手:{{ videoGestureInfo.handedness }}</p></div>
</template><style lang="scss" scoped>
video {clear: both;display: block;transform: rotateY(180deg);-webkit-transform: rotateY(180deg);-moz-transform: rotateY(180deg);width: 100vw;height: 100vh;
}.imgInfo {position: fixed;top: 0;left: 0;color: #fff;p {margin: 10px 0;}
}.videoView {display: flex;justify-content: center;width: 100vw;height: 100vh;background-color: #000;#webcam {margin: 0 auto;width: 1250px;height: 100%;}
}.canvas {z-index: 1;position: absolute;pointer-events: none;
}.output_canvas {position: absolute;top: 0;margin: 0 auto;transform: rotateY(180deg);-webkit-transform: rotateY(180deg);-moz-transform: rotateY(180deg);
}.output {display: none;width: 100%;font-size: calc(8px + 1.2vw);
}
</style>
  • 辅助方法
// 判断是否可以使用摄像头
function hasGetUserMedia() {return !!(navigator.mediaDevices && navigator.mediaDevices.getUserMedia);
}
  • 创建手势识别器
// 创建手势识别器
const createGestureRecognizer = async () => {// 加载指定版本的MediaPipe视觉任务WebAssembly模块const vision = await FilesetResolver.forVisionTasks('https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@0.10.3/wasm');// 创建了一个手势识别器实例(这个手势识别器实例使用的是指定版本的MediaPipe视觉任务WebAssembly模块)gestureRecognizer = await GestureRecognizer.createFromOptions(vision, {// 识别器配置baseOptions: {// 指向手势识别模型的路径modelAssetPath: './gesture_recognizer.task',// 设置为GPU以尝试利用图形处理单元进行加速,提高模型推理的速度delegate: 'GPU',},// 检测手掌的数量numHands: 2,});console.log('手势识别器加载完毕');// 识别视频中的手势predictWebcam();
};
  • 识别视频中的手势
// 识别视频中的手势
const predictWebcam = async () => {// 判断是否可以使用摄像头if (!hasGetUserMedia()) return alert('此设备不允许使用摄像头!');// 判断手势识别器是否加载完成if (!gestureRecognizer) return alert('手势识别器未加载完成');if (runningMode.value !== 'VIDEO') {// 设置识别器识别的类型为视频runningMode.value = 'VIDEO';await gestureRecognizer.setOptions({ runningMode: runningMode.value });}await gestureRecognizer.setOptions({ numHands: 2 });nextTick(() => {// 获取video元素const video = document.getElementById('webcam');// 获取视频手势节点绘制的canvas元素const canvasElement = document.getElementById('output_canvas');// 设置canvas的宽度和高度为video的宽度和高度canvasElement.width = video.clientWidth;canvasElement.height = video.clientHeight;// 获取canvas的上下文const canvasCtx = canvasElement.getContext('2d');// 设置上次识别视频手势的时间let lastVideoTime = -1;// 识别视频中的手势const predictWebcam = () => {// 获取当前视频的时间let nowInMs = Date.now();let results = {};// 如果视频的时间发生变化,则识别视频中的手势if (video.currentTime !== lastVideoTime) {// 替换上次识别视频手势的时间lastVideoTime = video.currentTime;results = gestureRecognizer.recognizeForVideo(video, nowInMs);}// 保存当前的canvas状态canvasCtx.save();// 清除canvas的内容canvasCtx.clearRect(0, 0, canvasElement.width, canvasElement.height);// 创建drawingUtils实例,用于可视化MediaPipeVision任务的结果const drawingUtils = new DrawingUtils(canvasCtx);// 判断是否识别到手势if (results.landmarks) {// 循环绘制手势的节点for (const landmarks of results.landmarks) {// 绘制手势连接线drawingUtils.drawConnectors(landmarks, GestureRecognizer.HAND_CONNECTIONS, {// 连接线的颜色color: '#00FF00',// 连接线的宽度lineWidth: 3,});// 绘制手势关节点drawingUtils.drawLandmarks(landmarks, {// 关节点的颜色color: '#FF0000',// 关节点的半径radius: 2.5,});}}// 恢复canvas的状态canvasCtx.restore();// 判断是否识别到手势数据if (results?.gestures?.length > 0) {videoGestureInfo.value.categoryName = enumGesture[results.gestures[0][0].categoryName];videoGestureInfo.value.categoryScore = parseFloat(results.gestures[0][0].score * 100).toFixed(2);videoGestureInfo.value.handedness = results.handednesses[0][0].displayName;} else {videoGestureInfo.value.categoryName = '';videoGestureInfo.value.categoryScore = '';videoGestureInfo.value.handedness = '';}// 递归调用,继续识别视频中的手势requestAnimationFrame(predictWebcam);};// 打开摄像头navigator.mediaDevices.getUserMedia({ video: true }).then(stream => {// 视频流添加到video元素中video.srcObject = stream;// 绑定视频加载完成事件,开始识别视频中的手势video.addEventListener('loadeddata', predictWebcam);});});
};
  • 整体js代码
import { GestureRecognizer, FilesetResolver, DrawingUtils } from './tasks-version@0.10.3.js';// 手势识别器实例
let gestureRecognizer;// 识别器识别的类型(图片/视频)
const runningMode = ref();// 视频手势信息
const videoGestureInfo = ref({});// 手势枚举
const enumGesture = {Closed_Fist: '握紧拳头',Open_Palm: '张开手掌',Thumb_Up: '竖起大拇指',Thumb_Down: '拇指朝下',Pointing_Up: '指向上',Victory: '胜利',None: '未识别',
};// 创建手势识别器
const createGestureRecognizer = async () => {// 加载指定版本的MediaPipe视觉任务WebAssembly模块const vision = await FilesetResolver.forVisionTasks('https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@0.10.3/wasm');// 创建了一个手势识别器实例(这个手势识别器实例使用的是指定版本的MediaPipe视觉任务WebAssembly模块)gestureRecognizer = await GestureRecognizer.createFromOptions(vision, {// 识别器配置baseOptions: {// 指向手势识别模型的路径modelAssetPath: './gesture_recognizer.task',// 设置为GPU以尝试利用图形处理单元进行加速,提高模型推理的速度delegate: 'GPU',},// 检测手掌的数量numHands: 2,});console.log('手势识别器加载完毕');// 识别视频中的手势predictWebcam();
};// 识别视频中的手势
const predictWebcam = async () => {// 判断是否可以使用摄像头if (!hasGetUserMedia()) return alert('此设备不允许使用摄像头!');// 判断手势识别器是否加载完成if (!gestureRecognizer) return alert('手势识别器未加载完成');if (runningMode.value !== 'VIDEO') {// 设置识别器识别的类型为视频runningMode.value = 'VIDEO';await gestureRecognizer.setOptions({ runningMode: runningMode.value });}await gestureRecognizer.setOptions({ numHands: 2 });nextTick(() => {// 获取video元素const video = document.getElementById('webcam');// 获取视频手势节点绘制的canvas元素const canvasElement = document.getElementById('output_canvas');// 设置canvas的宽度和高度为video的宽度和高度canvasElement.width = video.clientWidth;canvasElement.height = video.clientHeight;// 获取canvas的上下文const canvasCtx = canvasElement.getContext('2d');// 设置上次识别视频手势的时间let lastVideoTime = -1;// 识别视频中的手势const predictWebcam = () => {// 获取当前视频的时间let nowInMs = Date.now();let results = {};// 如果视频的时间发生变化,则识别视频中的手势if (video.currentTime !== lastVideoTime) {// 替换上次识别视频手势的时间lastVideoTime = video.currentTime;results = gestureRecognizer.recognizeForVideo(video, nowInMs);}// 保存当前的canvas状态canvasCtx.save();// 清除canvas的内容canvasCtx.clearRect(0, 0, canvasElement.width, canvasElement.height);// 创建drawingUtils实例,用于可视化MediaPipeVision任务的结果const drawingUtils = new DrawingUtils(canvasCtx);// 判断是否识别到手势if (results.landmarks) {// 循环绘制手势的节点for (const landmarks of results.landmarks) {// 绘制手势连接线drawingUtils.drawConnectors(landmarks, GestureRecognizer.HAND_CONNECTIONS, {// 连接线的颜色color: '#00FF00',// 连接线的宽度lineWidth: 3,});// 绘制手势关节点drawingUtils.drawLandmarks(landmarks, {// 关节点的颜色color: '#FF0000',// 关节点的半径radius: 2.5,});}}// 恢复canvas的状态canvasCtx.restore();// 判断是否识别到手势数据if (results?.gestures?.length > 0) {videoGestureInfo.value.categoryName = enumGesture[results.gestures[0][0].categoryName];videoGestureInfo.value.categoryScore = parseFloat(results.gestures[0][0].score * 100).toFixed(2);videoGestureInfo.value.handedness = results.handednesses[0][0].displayName;} else {videoGestureInfo.value.categoryName = '';videoGestureInfo.value.categoryScore = '';videoGestureInfo.value.handedness = '';}// 递归调用,继续识别视频中的手势requestAnimationFrame(predictWebcam);};// 打开摄像头navigator.mediaDevices.getUserMedia({ video: true }).then(stream => {// 视频流添加到video元素中video.srcObject = stream;// 绑定视频加载完成事件,开始识别视频中的手势video.addEventListener('loadeddata', predictWebcam);});});
};// 判断是否可以使用摄像头
function hasGetUserMedia() {return !!(navigator.mediaDevices && navigator.mediaDevices.getUserMedia);
}onMounted(() => {// 加载手势识别器createGestureRecognizer();
});

4.效果图展示

效果图展示

5.总结

本文简单介绍了手势检测与识别的概念,以及如何在前端中实现手势的识别与检测,大致流程就是通过Google@mediapipe开源框架实现,先创建手势识别器,之后再将视频的图像传入识别器,得到识别的结果即可


文章转载自:

http://Cbnv7NlO.wfspn.cn
http://czoeP7zG.wfspn.cn
http://jXIa1Crl.wfspn.cn
http://RALMCZvF.wfspn.cn
http://3xQKr5hZ.wfspn.cn
http://BSEQD7sK.wfspn.cn
http://aSXegP8V.wfspn.cn
http://s9c7Krp6.wfspn.cn
http://pLanKTcv.wfspn.cn
http://3vlEtZ1t.wfspn.cn
http://aIVAdf2Y.wfspn.cn
http://H1uWkRMQ.wfspn.cn
http://eg1uW8NX.wfspn.cn
http://YCTzj2pI.wfspn.cn
http://mm7XgSAI.wfspn.cn
http://1uU1sOal.wfspn.cn
http://sDaJcctG.wfspn.cn
http://kw5vyovX.wfspn.cn
http://fwpqtUaY.wfspn.cn
http://UDrfgG3D.wfspn.cn
http://TArlmsBQ.wfspn.cn
http://H7cZBVpY.wfspn.cn
http://lgOCgm6l.wfspn.cn
http://s998eOQ8.wfspn.cn
http://Dq8S9Sbf.wfspn.cn
http://WT8WTdkX.wfspn.cn
http://gF6pU7EZ.wfspn.cn
http://PJoAVhtj.wfspn.cn
http://ipEGuXPZ.wfspn.cn
http://dD8tRQV9.wfspn.cn
http://www.dtcms.com/wzjs/704561.html

相关文章:

  • 网站空间哪里便宜wordpress手机上传图片失败
  • 长治哪家公司做网站好ps网页设计论文
  • 网站建设便宜公司买虚机送网站建设
  • 怎么自己做网站app上海个体工商户如何注册
  • 甜点网站要怎么做凡客诚品是什么平台
  • 番禺微网站建设成都市城乡和住房建设局
  • wordpress 网站域名域名申请成功后怎么做网站
  • 服务器做网站上传快好还是下载快好注销网站 取消接入
  • 德州加盟网站建设wordpress名片模板下载
  • wordpress建立手机网站竞价网站制作
  • 公司高端网站设计公司长沙做电商网站设计
  • 设计之家官方网站内蒙古建设协会网站
  • 郑州的做网站公司哪家好广州番禺区邮政编码
  • 网站怎么做推广和优化广州建站模板厂家
  • 广东省交通建设监理检测协会网站网赌网站怎么建设
  • 网站开发设计工程师岗位职责企业vi设计公司有哪些
  • 成都网站建设网站制作公司来个黑黑的网站
  • 关于英文网站建设的请示静态网站添加到织梦
  • 如何做一张图片的网站西安进一步优化近期防疫措施
  • 山东君天建设工程有限公司网站用火车采集器发布信息时 如何获取网站栏目id
  • 品牌商城网站制作直通车怎么开效果最佳
  • 做网站公司不给源代码保定seo博客
  • 温州做网站掌熊号网站的空间价格
  • 卖水果网站建设的策划书网站建设咨询电话
  • 自贡网站设计请拿笔记记下新域名
  • 有限公司网站建设 互成网络地址 四川汕头网站制作流程
  • 安装wordpress建站程序企业电子商务网站
  • intitle 无线网站制作北京网页制作专业服务
  • 音乐网站建设目标营销型网站维护费用
  • 373网站怎么做这样的网站网站的二维码怎么做的