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

家里有一条狗🐶,很喜欢乘人不备睡沙发🛋️,恰好最近刚搬家 + 狗迎来了掉毛期 不想让沙发上很多毛。所以希望能识别到狗,然后播放“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.rhkb.cn/news/308381.html

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

相关文章

Mapmost Alpha:开启三维城市场景创作新纪元

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

vue3中使用antv-S2表格(基础功能版)

先看展示效果&#xff1a; 可以调整行宽、列宽、自定义字段图标、表头图标、添加排序、显示总计、小计等 首先确保搭建一个vue3项目环境&#xff0c;从0开始的小伙伴着重看第一点&#xff1a; 一、搭建vue3项目环境 首先创建一个vue3vitets项目&#xff0c;可以查看下面相关…

头歌-机器学习实验 第8次实验 决策树

第1关&#xff1a;什么是决策树 任务描述 本关任务&#xff1a;根据本节课所学知识完成本关所设置的选择题。 相关知识 为了完成本关任务&#xff0c;你需要掌握决策树的相关基础知识。 引例 在炎热的夏天&#xff0c;没有什么比冰镇后的西瓜更能令人感到心旷神怡的了。现…

Spark-Scala语言实战(16)

在之前的文章中&#xff0c;我们学习了三道任务&#xff0c;运用之前学到的方法。想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请留下你宝贵的点赞&#xff0c;谢谢。 Spark-Scala语言实战&#x…

使用doop识别近commons text漏洞的污点信息流

一、doop静态分析框架简介 1. doop静态分析框架简介 doop静态分析框架由希腊雅典大学plast-lab Yannis Smaragdakis团队设计开发&#xff0c;目前看是一款开源领域的比较先进的程序静态分析框架&#xff0c;一些程序静态分析论文的理论也有通过doop的规则实现后实验。 doop整…

c 解数独(通用方法,适用于9×9 数独)

折腾了一周时间&#xff0c;终于搞定99数独通用方法 思路&#xff1a;1.生成每行空位的值&#xff0c;也就是1-9中除去非0的数。 2.用行&#xff0c;列&#xff0c;宫判断每行中每个空位的最小取值范围后再重新生成每行。 3.随机提取生成的9行&#xff0c;判断每列之和是否等…

【数据结构与算法】:二叉树经典OJ

目录 1. 二叉树的前序遍历 (中&#xff0c;后序类似)2. 二叉树的最大深度3. 平衡二叉树4. 二叉树遍历 1. 二叉树的前序遍历 (中&#xff0c;后序类似) 这道题的意思是对二叉树进行前序遍历&#xff0c;把每个结点的值都存入一个数组中&#xff0c;并且返回这个数组。 思路&…

解决 IDEA每次打开新的项目都要重新设置maven问题

目录 一、当前项目设置maven 如下图&#xff1a; 二、设置打开的新项目的maven 如下图&#xff1a;​ 一、当前项目设置maven 对于当前项目我们都知道设置maven的配置要在 File -- Settings -- Build -- Maven 中设置 如下图&#xff1a; 二、设置打开的新项目的maven F…

150个 HTML5 网站模版 量大慢选

HTML5 网站模版 No.1 HTML5 网站模版 No.1

linux下安装nacos2.2.0

1、获取下载地址并下载 1.1、打开nacos官网 1.2、找到对应版本&#xff0c;点进去 ## 1.3、复制地址 1.4下载 # 进入要安装的目录&#xff0c;cd /usr/local/src # 执行wget https://github.com/alibaba/nacos/releases/download/2.2.0/nacos-server-2.2.0.tar.gz2、 安装…

RTSP/Onvif安防视频EasyNVR平台 vs.多协议接入视频汇聚EasyCVR平台:设备分组的区别

EasyNVR安防视频云平台是旭帆科技TSINGSEE青犀旗下支持RTSP/Onvif协议接入的安防监控流媒体视频云平台。平台具备视频实时监控直播、云端录像、云存储、录像检索与回看、告警等视频能力&#xff0c;能对接入的视频流进行处理与多端分发&#xff0c;包括RTSP、RTMP、HTTP-FLV、W…

架构设计参考项目系列主题:新零售SaaS架构:客户管理系统架构设计

什么是客户管理系统? 客户管理系统,也称为CRM(Customer Relationship Management),主要目标是建立、发展和维护好客户关系。 CRM系统围绕客户全生命周期的管理,吸引和留存客户,实现缩短销售周期、降低销售成本、增加销售收入的目的,从而提高企业的盈利能力和竞争力。 …

【ARM 裸机】汇编 led 驱动之原理分析

1、我们为什么要学习汇编&#xff1f;&#xff1f;&#xff1f; 之前我们或许接触过 STM32 以及其他的 32 位的 MCU ,都是基于 C 语言环境进行编程的&#xff0c;都没怎么注意汇编&#xff0c;是因为 ST 公司早已将启动文件写好了&#xff0c;新建一个 STM32 工程的时候&#…

nexus搭建maven与docker镜像的私有仓库

引言 通过nexus搭建maven与docker镜像的私有仓库,实现jar包与镜像动态更新、共享、存储。 一、nexus部署 通过docker-compose部署nexus name: java services:#############################环境#############################env-nexus:restart: always## 3.58.1image: so…

Python十大最佳实践:高效Python编程的十个关键方法

在当今的软件开发世界中&#xff0c;Python是一种极其重要且广泛使用的编程语言。以下是Python编程的十大最佳实践&#xff0c;这些实践将帮助你提升编程效率&#xff0c;优化代码质量&#xff0c;以及更好地应用Python的强大功能。 1.理解Pythonic的方式 “Pythonic”是指遵循…

普乐蛙VR航天体验馆设备VR太空飞船VR元宇宙展厅

三天小长假就要来啦&#xff01;五一假期也即将到来。老板们想捉住人流量这个财富密码吗&#xff1f;那快快行动起来&#xff01;开启VR体验项目&#xff0c;假期赚翻天&#xff01;小编亲测&#xff01;&#xff01;这款设备刺激好玩&#xff0c;想必会吸引各位家长小孩、学生…

matlab使用教程(43)—二维曲线图绘制的基本方法

这个博客创建一个简单的曲线图并修改横纵坐标。通过更改线条颜色、线型和添加标记来自定义线图的外观。 1.创建曲线图 使用 plot 函数创建二维曲线图。例如&#xff0c;绘制从 0 到 2 π 之间的正弦函数值&#xff0c;并修改横纵坐标&#xff0c;添加图形标题。 x linspace…

ES6 关于Class类的继承 extends(2024-04-10)

1、简介 类Class 可以通过extends关键字实现继承&#xff0c;让子类继承父类的属性和方法。extends 的写法比 ES5 的原型链继承&#xff0c;要清晰和方便很多。 class Foo {constructor(x, y) {this.x x;this.y y;console.log(父类构造函数)}toString() {return ( this.x …

【算法】分治-快排

个人主页 &#xff1a; zxctscl 如有转载请先通知 题目 前言1. 75. 颜色分类1.1 分析1.2 代码 2. 912. 排序数组2.1 分析2.2 代码 3. 215. 数组中的第K个最大元素3.1 分析3.2 代码 4. LCR 159. 库存管理 III4.1 分析4.2 代码 前言 分治就是分而治之 1. 75. 颜色分类 1.1 分析…

GitHub repository - Pulse - Contributors - Network

GitHub repository - Pulse - Contributors - Network 1. Pulse2. Contributors3. NetworkReferences 1. Pulse 显示该仓库最近的活动信息。该仓库中的软件是无人问津&#xff0c;还是在火热地开发之中&#xff0c;从这里可以一目了然。 2. Contributors 显示对该仓库进行过…