js摄像头动态检测

利用摄像头每一秒截图一次图像。然后计算2次图像之间的相似度。

如果相似度低于98%就会报警。

var video = document.getElementsByClassName('inputvideo')[0];
video.innerHTML = "<video class='input_video' id='camera' autoplay width='640px' height='380px'></video>";const videoElement = document.getElementById('camera');// 获取用户媒体设备(摄像头)
navigator.mediaDevices.getUserMedia({ video: true }).then(function (stream) {videoElement.srcObject = stream;}).catch(function (error) {console.error('获取摄像头失败:', error);});var canvas = document.getElementsByClassName('outputcanvas')[0];
canvas.innerHTML = "<canvas class='output_canvas' width='640px' height='480px'></canvas>";var canvasElement = document.getElementsByClassName('output_canvas')[0];
var canvasCtx = canvasElement.getContext('2d');// 设置 canvas 尺寸与视频流尺寸一致
canvasElement.width = 64;
canvasElement.height = 64;
var last = 0function captureFrame() {// 捕获图像并绘制到画布canvasCtx.drawImage(videoElement, 0, 0, canvasElement.width, canvasElement.height);// 获取绘制后的图像数据const imageData = canvasCtx.getImageData(0, 0, canvasElement.width, canvasElement.height);// 压缩图像并将其绘制到目标画布上const compressedImageDataPromise = compressImgFromImageData(imageData);// 处理压缩后的图像数据compressedImageDataPromise.then(function (compressedData) {// 在这里可以使用 compressedData 进行进一步的操作,例如上传或显示在页面上// 清空画布canvasCtx.clearRect(0, 0, canvasElement.width, canvasElement.height);// 转换为灰度图像const grayscaleImageData = createGrayscale(compressedData);// 获取哈希指纹const hashFingerprint = getHashFingerprint(grayscaleImageData);// 判断 last 是否等于 hashFingerprintif (last !== 0) {if (last === hashFingerprint) {console.log('你没动');} else {// console.log('你动了' + last);// 计算汉明距离const distance = hammingDistance(last, hashFingerprint);// 计算相似度百分比const similarityPercentage = (1 - distance / (hashFingerprint.length * 2)) * 100;// console.log('汉明距离:', distance);const baifenbi=similarityPercentage.toFixed(2);console.log('相似度百分比:', baifenbi + '%');if (baifenbi<98){_funcCb (true, {param1: true})}_funcCb (true, {param2: baifenbi})}}last = hashFingerprint// console.log('哈希指纹:', hashFingerprint);// 在画布上绘制灰度图像canvasCtx.putImageData(grayscaleImageData, 0, 0);});
}// 每隔一段时间捕获一帧
setInterval(captureFrame, 1000); // 1 帧每秒// 定义压缩图像的函数
function compressImgFromImageData(imageData) {const canvas = document.createElement('canvas');const ctx = canvas.getContext('2d');const imgWidth = 64; // 设置压缩后的宽度canvas.width = imgWidth;canvas.height = imgWidth;// 将图像数据绘制到临时 canvas 上ctx.putImageData(imageData, 0, 0);// 获取压缩后的图像数据return new Promise((resolve, reject) => {const imgData = ctx.getImageData(0, 0, imgWidth, imgWidth);resolve(imgData);});
}// createGrayscale 函数已经在之前的代码中定义
// 根据 RGBA 数组生成 ImageData
function createImgData(dataDetail) {const canvas = document.createElement('canvas');const ctx = canvas.getContext('2d');const imgWidth = Math.sqrt(dataDetail.length / 4);const newImageData = ctx.createImageData(imgWidth, imgWidth);for (let i = 0; i < dataDetail.length; i += 4) {let R = dataDetail[i];let G = dataDetail[i + 1];let B = dataDetail[i + 2];let Alpha = dataDetail[i + 3];newImageData.data[i] = R;newImageData.data[i + 1] = G;newImageData.data[i + 2] = B;newImageData.data[i + 3] = Alpha;}return newImageData;
}// 创建灰度图像
function createGrayscale(imgData) {const newData = Array(imgData.data.length).fill(0);imgData.data.forEach((_data, index) => {if ((index + 1) % 4 === 0) {const R = imgData.data[index - 3];const G = imgData.data[index - 2];const B = imgData.data[index - 1];const gray = ~~((R + G + B) / 3);newData[index - 3] = gray;newData[index - 2] = gray;newData[index - 1] = gray;newData[index] = 255; // Alpha 值固定为255}});return createImgData(newData);
}// 获取图像的哈希指纹
function getHashFingerprint(imgData) {const grayList = imgData.data.reduce((pre, cur, index) => {if ((index + 1) % 4 === 0) {pre.push(imgData.data[index - 1]);}return pre;}, []);const length = grayList.length;const grayAverage = grayList.reduce((pre, next) => pre + next, 0) / length;return grayList.map(gray => (gray >= grayAverage ? 1 : 0)).join('');
}// 计算汉明距离
function hammingDistance(hash1, hash2) {if (hash1.length !== hash2.length) {throw new Error('Hashes must have the same length');}let distance = 0;for (let i = 0; i < hash1.length; i++) {if (hash1[i] !== hash2[i]) {distance++;}}return distance;
}

原理是看了有一篇文章

利用 JS 实现多种图片相似度算法

首先降低图片分辨率

然后使用指纹提取

在“平均哈希算法”中,若灰度图的某个像素的灰度值大于平均值,则视为1,否则为0。把这部分信息组合起来就是图片的指纹。由于我们已经拿到了灰度图的 ImageData 对象,要提取指纹也就变得很容易了:

最后用汉明距离计算相似度

摘一段维基百科关于“汉明距离”的描述:

在信息论中,两个等长字符串之间的汉明距离(英语:Hamming distance)是两个字符串对应位置的不同字符的个数。换句话说,它就是将一个字符串变换成另外一个字符串所需要替换的字符个数。

例如:

  • 1011101与1001001之间的汉明距离是2。
  • 2143896与2233796之间的汉明距离是3。
  • "toned"与"roses"之间的汉明距离是3。

体验地址

不许动 

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

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

相关文章

自动驾驶——估计预瞄轨迹YawRate

1.Introduction 在ADAS控制系统中&#xff0c;通常根据预瞄距离x去估计横向距离y&#xff0c;有如下关系&#xff1a; y a0 a1 x a2 * x^2 a3 * x^3 &#xff0c;那么现在有个需求&#xff0c;希望根据上述x和y的关系&#xff0c;去估计规划预瞄轨迹yawRate 2.How to es…

【Linux】Qt Remote之Remote开发环境搭建填坑小记

总体思路 基于WSL2&#xff08;Ubuntu 22.04 LTS&#xff09;原子Alpha开发板进行Qt开发实验&#xff0c;基于Win11通过vscode remote到WSL2&#xff0c;再基于WSL2通过Qt 交叉编译&#xff0c;并通过sshrsync远程到开发板&#xff0c;构建起开发工具链。 Step1 基于Win11通过…

Macs Fan Control 1.5.16 Pro for mac风扇调节软件

Macs Fan Control是一款专门为 Mac 用户设计的软件&#xff0c;它可以帮助用户控制和监控 Mac 设备的风扇速度和温度。这款软件允许用户手动调整风扇速度&#xff0c;以提高设备的散热效果&#xff0c;减少过热造成的风险。 Macs Fan Control 可以在菜单栏上显示当前系统温度和…

容器编排学习(二)镜像制作和私有仓库介绍

一 Dockerfile 1 概述 commit的局限 很容易制作简单的镜像&#xff0c;但碰到复杂的情况就十分不方便例如碰到下面的情况需要设置默认的启动命令需要设置环境变量需要指定镜像开放某些特定的端口 Dockerfile就是解决这些问题的方法 Dockerfile是一种更强大的镜像制作方式…

如何基于国标GB28181视频平台EasyGBS国标云服务平台建设智慧环保在线监测系统

EasyGBS平台可提供流媒体接入、处理、转发等服务&#xff0c;支持内网、公网的安防视频监控设备通过国标GB/T28181协议进行视频监控直播。基于视频图像的环保监督管理智能监控系统&#xff0c;结合了计算机技术、AI、云计算、网络传输技术和网络存储技术等先进技术&#xff0c;…

数据分析面试题(2023.09.08)

数据分析流程 总体分为四层&#xff1a;需求层、数据层、分析层和结论层 一、统计学问题 1、贝叶斯公式复述并解释应用场景 公式&#xff1a;P(A|B) P(B|A)*P(A) / P(B)应用场景&#xff1a;如搜索query纠错&#xff0c;设A为正确的词&#xff0c;B为输入的词&#xff0c;那…

Hugging News #0904: 登陆 AWS Marketplace

每一周&#xff0c;我们的同事都会向社区的成员们发布一些关于 Hugging Face 相关的更新&#xff0c;包括我们的产品和平台更新、社区活动、学习资源和内容更新、开源库和模型更新等&#xff0c;我们将其称之为「Hugging News」。本期 Hugging News 有哪些有趣的消息&#xff0…

Pytorch从零开始实战01

Pytorch从零开始实战——MNIST手写数字识别 本系列来源于365天深度学习训练营 原作者K同学 文章目录 Pytorch从零开始实战——MNIST手写数字识别环境准备数据集模型选择模型训练可视化展示 环境准备 本系列基于Jupyter notebook&#xff0c;使用Python3.7.12&#xff0c;Py…

CH06_第一组重构(下)

封装变量&#xff08;Encapsulate Variable | 132&#xff09; 曾用名&#xff1a;自封装字段&#xff08;Self-Encapsulate Field&#xff09; 曾用名&#xff1a;封装字段&#xff08;Encapsulate Field&#xff09; let defaultOwner {firstName: "Martin", la…

用半天时间从零开始复习前端之html

目录 前言 科班生的标配&#xff1a;半天听完一门标记型语言 准备工作 webstorm2022 webstrom 第一个html页面 body h系列标签 行标签和块标签 列表标签 表格标签&#xff08;另起一篇&#xff09; 万能的input 1.快速生成多个标签 2.同时选中多个 前言 科班生的标…

系统报错“由于找不到msvcp140.dll无法继续执行代码”的处理方法

我在使用电脑时&#xff0c;突然发现了一个错误提示&#xff1a;“无法启动程序&#xff0c;因为找不到msvcp140.dll文件”。这让我非常困惑&#xff0c;因为我确定这个文件应该存在于我的电脑上。但是电脑依然报错“由于找不到msvcp140.dll无法继续执行代码”&#xff0c;这个…

【周末闲谈】如何利用AIGC为我们创造有利价值?

个人主页&#xff1a;【&#x1f60a;个人主页】 系列专栏&#xff1a;【❤️周末闲谈】 系列目录 ✨第一周 二进制VS三进制 ✨第二周 文心一言&#xff0c;模仿还是超越&#xff1f; ✨第二周 畅想AR 文章目录 系列目录前言AIGCAI写作AI绘画AI视频生成AI语音合成 前言 在此之…

Linux防火墙(iptables)

一、linux的防火墙组成 linux的防火墙由netfilter和iptables组成。用户空间的iptables制定防火墙规则&#xff0c;内核空间的netfilter实现防火墙功能。 netfilter&#xff08;内核空间&#xff09;位于Linux内核中的包过滤防火墙功能体系&#xff0c;称为Linux防火墙的“内核…

MHA高可用及故障切换

一、什么是 MHA MHA&#xff08;MasterHigh Availability&#xff09;是一套优秀的MySQL高可用环境下故障切换和主从复制的软件。 MHA 的出现就是解决MySQL 单点的问题。 MySQL故障切换过程中&#xff0c;MHA能做到0-30秒内自动完成故障切换操作。 MHA能在故障切换的过程中最大…

Vue中如何实现城市3D分布图

cityfenbu.vue <template><div ><el-card class"seriesmap-box-card"><div slot"header" class"clearfix"><span>城市分布图 (点击可下钻到县)</span></div><div><div class"series-ma…

c语言练习45:模拟实现内存函数memcpy

模拟实现内存函数memcpy 针对内存块&#xff0c;不在乎内存中的数据。 拷贝内容有重叠的话应用memmove 模拟实现&#xff1a; 代码&#xff1a; 模拟实现memcpy #include<stdio.h> #include<assert.h> void* my_memcpy(void* dest, const void* src, size_t num…

【Linux】网络编程网络基础(C++)

目录 一、计算机网络背景 二、认识 "协议" 三、网络协议初识 【3.1】协议分层 【3.2】OSI七层模型 【3.3】TCP/IP五层(或四层)模型 四、网络传输基本流程 【4.1】网络传输流程图 【4.2】数据包封装和分用 五、网络中的地址管理 一、计算机网络背景 【独立…

谷粒商城----缓存与分布式锁

1、缓存使用 为了系统性能的提升&#xff0c;我们一般都会将部分数据放入缓存中&#xff0c;加速访问。而 db 承担数据落盘工作。 哪些数据适合放入缓存&#xff1f;  即时性、数据一致性要求不高的  访问量大且更新频率不高的数据&#xff08;读多&#xff0c;写少&…

The WebSocket session [x] has been closed and no method (apart from close())

在向客户端发送消息时&#xff0c;session关闭了。 不管是单客户端发送消息还是多客户端发送消息&#xff0c;在发送消息之前判断session 是否关闭 使用 isOpen() 方法

Nginx 学习(九)集群概述与LVS工作模式的配置

一 集群 1 概述 通过高速网络将很多服务器集中起来一起提供同一种服务&#xff0c;在客户端看来就像是只有一个服务器可以在付出较低成本的情况下获得在性能、可靠性、灵活性方面的相对较高的收益任务调度是集群系统中的核心技术 2 目的 提高性能。如计算密集型应用&…