防止狗上沙发,写一个浏览器实时识别目标检测功能

news/2024/5/8 19:52:16/文章来源:https://blog.csdn.net/u012148903/article/details/137333171

家里有一条狗🐶,很喜欢乘人不备睡沙发🛋️,恰好最近刚搬家 + 狗迎来了掉毛期 不想让沙发上很多毛。所以希望能识别到狗,然后播放“gun 下去”的音频📣。

需求分析

  • 需要一个摄像头📷

    • 利用 chrome 浏览器可以调用手机摄像头,获取权限,然后利用 video 将摄像头的内容绘制到 video 上。

  • 通过摄像头实时识别画面中的狗🐶

    • 利用 tensorflow 和预训练的 COCO-SSD MobileNet V2 模型进行对象检测。

    • 将摄像头的视频流转化成视频帧图像传给模型进行识别

  • 录制一个音频

    • 识别到目标(狗)后播放音频📣

  • 需要部署在一个设备上

    • 找一个不用的旧手机📱,Android 系统

    • 安装 termux 来实现开启本地 http 服务🌐

技术要点

  1. 利用浏览器 API 调用手机摄像头,将视频流推给 video

 const stream = await navigator.mediaDevices.getUserMedia({// video: { facingMode: "environment" },  // 摄像头后置video: { facingMode: "user" },});const videoElement = document.getElementById("camera-stream");videoElement.srcObject = stream;

  2.加载模型,实现识别

 let dogDetector;async function loadDogDetector() {// 加载预训练的SSD MobileNet V2模型const model = await cocoSsd.load();dogDetector = model; // 将加载好的模型赋值给dogDetector变量}

 3.监听 video 的播放,将视频流转换成图像传入模型检测

 videoElement.addEventListener("play", async () => {requestAnimationFrame(processVideoFrame);});async function processVideoFrame() {if (!videoElement.paused && !videoElement.ended) {canvas.width = videoElement.videoWidth;canvas.height = videoElement.videoHeight;ctx.drawImage(videoElement, 0, 0, canvas.width, canvas.height);// 获取当前帧图像数据const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);// 对帧执行预测let predictionClasses = "";const predictions = await dogDetector.detect(imageData);// 处理预测结果,比如检查是否有狗被检测到for (const prediction of predictions) {predictionClasses += `${prediction.class}\n`; // 组装识别的物体名称if (prediction.class === "dog") {// 播放声音playDogBarkSound();}}nameContainer.innerText = predictionClasses.trim(); // 移除末尾的换行符requestAnimationFrame(processVideoFrame);}}

 4. 播放音频

 async function playDogBarkSound() {if (playing) return;playing = true;const audio = new Audio(dogBarkSound);audio.addEventListener("ended", () => {playing = false;});audio.volume = 0.5; // 调整音量大小await audio.play();}
  1. 手机开启本地 http 服务

    • 安装 termux

    • 安装 python3

    • 运行 python3 -m http.server 8000

  2. 将项目上传到 termux 的目录

    • 直接用 termux 打开文件

    • 访问 http://localhost:8000

项目代码(改为 html 文件后)

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Mobile Dog Detector</title><script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@4.17.0/dist/tf.min.js"></script><script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/coco-ssd@2.2.3/dist/coco-ssd.min.js"></script><style>#camera-stream {width: 200px;height: auto;}#name {height: 200px;overflow-y: auto;font-family: Arial, sans-serif;}</style></head><body><video id="camera-stream" autoplay playsinline></video><div id="name" style="height: 200px"></div><script>let playing = false;let dogDetector;async function loadDogDetector() {// 加载预训练的SSD MobileNet V2模型const model = await cocoSsd.load();dogDetector = model; // 将加载好的模型赋值给dogDetector变量console.log("dogDetector", dogDetector);startCamera();}// 调用函数加载模型loadDogDetector();async function startCamera() {const stream = await navigator.mediaDevices.getUserMedia({// video: { facingMode: "environment" },  // 摄像头后置video: { facingMode: "user" },});const nameContainer = document.getElementById("name");const videoElement = document.getElementById("camera-stream");videoElement.srcObject = stream;const canvas = document.createElement("canvas");const ctx = canvas.getContext("2d");videoElement.addEventListener("play", async () => {requestAnimationFrame(processVideoFrame);});async function processVideoFrame() {if (!videoElement.paused && !videoElement.ended) {canvas.width = videoElement.videoWidth;canvas.height = videoElement.videoHeight;ctx.drawImage(videoElement, 0, 0, canvas.width, canvas.height);const imageData = ctx.getImageData(0,0,canvas.width,canvas.height);let predictionClasses = "";const predictions = await dogDetector.detect(imageData);for (const prediction of predictions) {predictionClasses += `${prediction.class}\n`;if (prediction.class === "dog") {// 修改为检测到狗时播放声音playDogBarkSound();}}nameContainer.innerText = predictionClasses.trim();requestAnimationFrame(processVideoFrame);}}async function playDogBarkSound() {if (playing) return;playing = true;const audio = new Audio("./getout.mp3");audio.addEventListener("ended", () => {playing = false;});audio.volume = 0.5; // 调整音量大小await audio.play();}}</script></body>
</html>

实现效果

效果很好👍,用旧手机开启摄像头后,检测到狗就播放声音了。

实现总结

该方案通过以下步骤实现了一个基于网页的实时物体检测系统,专门用于识别画面中的狗并播放特定音频以驱赶它离开沙发。具体实现过程包括以下几个核心部分:

  • 调用摄像头:

使用浏览器提供的 navigator.mediaDevices.getUserMedia API 获取用户授权后调用手机摄像头,并将视频流设置给 video 元素展示。

  • 加载物体检测模型:

使用 TensorFlow.js 和预训练的 COCO-SSD MobileNet V2 模型进行对象检测,加载模型后赋值给 dogDetector 变量。处理视频流与图像识别:

监听 video 元素的播放事件,通过 requestAnimationFrame 循环逐帧处理视频。将当前视频帧绘制到 canvas 上,然后从 canvas 中提取图像数据传入模型进行预测。在模型返回的预测结果中,如果检测到“dog”,则触发播放音频函数。

  • 播放音频反馈:

定义一个异步函数 playDogBarkSound 来播放指定的音频文件,确保音频只在前一次播放结束后才开始新的播放。

  • 部署环境准备:

使用旧 Android 手机安装 Termux,创建本地 HTTP 服务器运行项目代码。上传项目文件至 Termux 目录下并通过访问 localhost:8000 启动应用。

通过以上技术整合,最终实现了在旧手机上部署一个能够实时检测画面中狗的网页应用,并在检测到狗时播放指定音频。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_1045812.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

openHarmony 如何从API9升级到API10

最近用从官方下载的DevEco Studio3.1开发小app, 需要用到第三方库&#xff0c;加载第三方库&#xff0c;并添加代码&#xff0c;编译时如下错误&#xff1a; hvigor Finished :entry:defaultGenerateMetadata… after 3 ms hvigor ERROR: Failed :entry:defaultMergeProfile… …

微信小程序页面交互综合练习 (重点:解决“setData of undefined”报错问题)

一、写一个注册表单&#xff0c;点击“注册”按钮将用户输入的数据带到服务器&#xff0c;并且能在控制台显示参数。 &#xff08;1&#xff09;首先&#xff0c;我需要在vscode里面创建一个简易的node.js服务器 //第一步:引入http模块 var http require(http); //第二步:创建…

算法刷题Day30 | 332.重新安排行程、51. N皇后、37. 解数独

目录 0 引言1 重新安排行程1.1 我的解题1.2 更好的解法 2 N皇后2.1 我的解题 3 解数独3.1 我的解题3.2 &#x1f64b;‍♂️ 作者&#xff1a;海码007&#x1f4dc; 专栏&#xff1a;算法专栏&#x1f4a5; 标题&#xff1a;算法刷题Day30 | 332.重新安排行程、51. N皇后、37. …

【图论】详解链式前向星存图法+遍历法

细说链式前向星存图法 首先要明白&#xff0c;链式前向星的原理是利用存边来进行模拟图。 推荐左神的视频–建图、链式前向星、拓扑排序 比方说有这样一张图&#xff0c;我们用链式前向星来进行模拟时&#xff0c;可以将每一条边都进行编号&#xff0c;其中&#xff0c;红色的…

刷题DAY49 | LeetCode 121-买卖股票的最佳时机 122-买卖股票的最佳时机II

121 买卖股票的最佳时机&#xff08;easy&#xff09; 给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票&#xff0c;并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取…

【前端面试3+1】10 npm run dev 发生了什么、vue的自定义指令如何实现、js的数据类型有哪些及其不同、【最长公共前缀】

一、npm run dev发生了什么 运行npm run dev时&#xff0c;通常是在一个基于Node.js的项目中&#xff0c;用来启动开发服务器或者执行一些开发环境相关的任务。下面是一般情况下npm run dev会执行的步骤&#xff1a; 1. 查找package.json中的scripts字段&#xff1a; npm会在项…

双指针,滑动窗口

今天也是闲来无事&#xff0c;想去做一下&#xff0c;之前学过的某个题型&#xff0c;但是在中间突然发现了这个题&#xff0c;那时候年少无知&#xff0c;做不出来&#xff0c;今天也是很轻松的用双指针轻松拿捏&#xff0c;因此发帖。 传送门&#xff1a;逛画展 题解&#x…

VRRP虚拟路由实验(华为)

思科设备参考&#xff1a;VRRP虚拟路由实验&#xff08;思科&#xff09; 一&#xff0c;技术简介 VRRP&#xff08;Virtual Router Redundancy Protocol&#xff09;是一种网络协议&#xff0c;用于实现路由器冗余&#xff0c;提高网络可靠性和容错能力。VRRP允许多台路由器…

官网下载IDE插件并导入IDE

官网下载IDEA插件并导入IDEA 1. 下载插件2. 导入插件 1. 下载插件 地址&#xff1a;https://plugins.jetbrains.com/plugin/21068-codearts-snap/versions 说明&#xff1a;本次演示以IDEA软件为例 操作&#xff1a; 等待下载完成 2. 导入插件 点击File->setting->Pl…

数据仓库与数据挖掘(第三版)陈文伟思维导图1-5章作业

第一章 概述 8.基于数据仓库的决策支持系统与传统决策支持系统有哪些区别&#xff1f; 决策支持系统经历了4个阶段。 1.基本决策支持系统 是在运筹学单模型辅助决策的基础上发展起来的&#xff0c;以模型库系统为核心&#xff0c;以多模型和数据库的组合形成方案辅助决策。 它…

2024年第八届人工智能与虚拟现实国际会议(AIVR 2024)即将召开!

2024年第八届人工智能与虚拟现实国际会议&#xff08;AIVR 2024&#xff09;将2024年7月19-21日在日本福冈举行。人工智能与虚拟现实的发展对推动科技进步、促进经济发展、提升人类生活质量等具有重要意义。AIVR 2024将携手各专家学者&#xff0c;共同挖掘智能与虚拟的无限可能…

利用Sentinel解决雪崩问题(二)隔离和降级

前言&#xff1a; 虽然限流可以尽量避免因高并发而引起的服务故障&#xff0c;但服务还会因为其它原因而故障。而要将这些故障控制在一定范围避免雪崩&#xff0c;就要靠线程隔离(舱壁模式)和熔断降级手段了&#xff0c;不管是线程隔离还是熔断降级&#xff0c;都是对客户端(调…

图片管理系统:原理、设计与实践

title: 图片管理系统&#xff1a;原理、设计与实践 date: 2024/4/9 20:04:25 updated: 2024/4/9 20:04:25 tags: 图片管理存储组织上传采集处理编辑搜索检索展示分享AI应用 第一章&#xff1a;图片管理系统概述 1.1 图片管理系统简介 图片管理系统是一种用于存储、组织、处理…

rocketmq和rabbitmq总是分不清?

1. 官方解答 摘自百度搜索&#xff1a; 2. 通俗易懂的回答

【unity】【C#】UGUI组件

文章目录 UI是什么对UI初步认识 UI是什么 UI是用户界面&#xff08;User Interface&#xff09;的缩写&#xff0c;它是用户与软件或系统进行交互的界面。UI设计旨在提供用户友好的界面&#xff0c;使用户能够轻松地使用软件或系统。UI设计包括界面的布局、颜色、字体、图标等…

爬虫逆向实战(40)-某江酒店登陆(AES、MD5)

一、数据接口分析 主页地址&#xff1a;某江酒店 1、抓包 通过抓包可以发现数据接口是/api/member/login 2、判断是否有加密参数 请求参数是否加密&#xff1f; 通过查看“载荷”模块可以发现&#xff0c;有TDFingerprint、blackBoxMd5、password和sw四个加密参数&#x…

Java快速入门系列-6(数据库编程与JDBC)

第六章:数据库编程与JDBC 6.1 SQL基础6.1.1 SQL基本结构与命令6.1.2 SQL高级查询6.1.3 SQL子查询与联接6.2 JDBC原理与使用6.2.1 JDBC驱动程序与URL6.2.2 Statement、PreparedStatement与CallableStatement6.2.3 数据库事务处理6.3 数据库连接池6.4 事务管理6.1 SQL基础 SQL(…

数据结构——线性表(链式存储结构)

语言&#xff1a;C语言软件&#xff1a;Visual Studio 2022笔记书籍&#xff1a;数据结构——用C语言描述如有错误&#xff0c;感谢指正。若有侵权请联系博主 一、线性表的逻辑结构 线性表是n个类型相同的数据元素的有限序列&#xff0c;对n>0&#xff0c;除第一元素无直接…

电商技术揭秘十八:电商平台的云计算与大数据应用小结

电商技术揭秘相关系列文章 电商技术揭秘一&#xff1a;电商架构设计与核心技术 电商技术揭秘二&#xff1a;电商平台推荐系统的实现与优化 电商技术揭秘三&#xff1a;电商平台的支付与结算系统 电商技术揭秘四&#xff1a;电商平台的物流管理系统 电商技术揭秘五&#xf…

Day:006(1) | Python爬虫:高效数据抓取的编程技术(爬虫工具)

selenium介绍与安装 Selenium是一个Web的自动化测试工具&#xff0c;最初是为网站自动化测试而开发的&#xff0c;类型像我们玩游戏用的按键精灵&#xff0c;可以按指定的命令自动操作&#xff0c;不同是Selenium 可以直接运行在浏览器上&#xff0c;它支持所有主流的浏览器&am…