• js摄像头动态检测


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

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

    1. var video = document.getElementsByClassName('inputvideo')[0];
    2. video.innerHTML = "";
    3. const videoElement = document.getElementById('camera');
    4. // 获取用户媒体设备(摄像头)
    5. navigator.mediaDevices.getUserMedia({ video: true })
    6. .then(function (stream) {
    7. videoElement.srcObject = stream;
    8. })
    9. .catch(function (error) {
    10. console.error('获取摄像头失败:', error);
    11. });
    12. var canvas = document.getElementsByClassName('outputcanvas')[0];
    13. canvas.innerHTML = "";
    14. var canvasElement = document.getElementsByClassName('output_canvas')[0];
    15. var canvasCtx = canvasElement.getContext('2d');
    16. // 设置 canvas 尺寸与视频流尺寸一致
    17. canvasElement.width = 64;
    18. canvasElement.height = 64;
    19. var last = 0
    20. function captureFrame() {
    21. // 捕获图像并绘制到画布
    22. canvasCtx.drawImage(videoElement, 0, 0, canvasElement.width, canvasElement.height);
    23. // 获取绘制后的图像数据
    24. const imageData = canvasCtx.getImageData(0, 0, canvasElement.width, canvasElement.height);
    25. // 压缩图像并将其绘制到目标画布上
    26. const compressedImageDataPromise = compressImgFromImageData(imageData);
    27. // 处理压缩后的图像数据
    28. compressedImageDataPromise.then(function (compressedData) {
    29. // 在这里可以使用 compressedData 进行进一步的操作,例如上传或显示在页面上
    30. // 清空画布
    31. canvasCtx.clearRect(0, 0, canvasElement.width, canvasElement.height);
    32. // 转换为灰度图像
    33. const grayscaleImageData = createGrayscale(compressedData);
    34. // 获取哈希指纹
    35. const hashFingerprint = getHashFingerprint(grayscaleImageData);
    36. // 判断 last 是否等于 hashFingerprint
    37. if (last !== 0) {
    38. if (last === hashFingerprint) {
    39. console.log('你没动');
    40. } else {
    41. // console.log('你动了' + last);// 计算汉明距离
    42. const distance = hammingDistance(last, hashFingerprint);
    43. // 计算相似度百分比
    44. const similarityPercentage = (1 - distance / (hashFingerprint.length * 2)) * 100;
    45. // console.log('汉明距离:', distance);
    46. const baifenbi=similarityPercentage.toFixed(2);
    47. console.log('相似度百分比:', baifenbi + '%');
    48. if (baifenbi<98){
    49. _funcCb (true, {param1: true})
    50. }
    51. _funcCb (true, {param2: baifenbi})
    52. }
    53. }
    54. last = hashFingerprint
    55. // console.log('哈希指纹:', hashFingerprint);
    56. // 在画布上绘制灰度图像
    57. canvasCtx.putImageData(grayscaleImageData, 0, 0);
    58. });
    59. }
    60. // 每隔一段时间捕获一帧
    61. setInterval(captureFrame, 1000); // 1 帧每秒
    62. // 定义压缩图像的函数
    63. function compressImgFromImageData(imageData) {
    64. const canvas = document.createElement('canvas');
    65. const ctx = canvas.getContext('2d');
    66. const imgWidth = 64; // 设置压缩后的宽度
    67. canvas.width = imgWidth;
    68. canvas.height = imgWidth;
    69. // 将图像数据绘制到临时 canvas 上
    70. ctx.putImageData(imageData, 0, 0);
    71. // 获取压缩后的图像数据
    72. return new Promise((resolve, reject) => {
    73. const imgData = ctx.getImageData(0, 0, imgWidth, imgWidth);
    74. resolve(imgData);
    75. });
    76. }
    77. // createGrayscale 函数已经在之前的代码中定义
    78. // 根据 RGBA 数组生成 ImageData
    79. function createImgData(dataDetail) {
    80. const canvas = document.createElement('canvas');
    81. const ctx = canvas.getContext('2d');
    82. const imgWidth = Math.sqrt(dataDetail.length / 4);
    83. const newImageData = ctx.createImageData(imgWidth, imgWidth);
    84. for (let i = 0; i < dataDetail.length; i += 4) {
    85. let R = dataDetail[i];
    86. let G = dataDetail[i + 1];
    87. let B = dataDetail[i + 2];
    88. let Alpha = dataDetail[i + 3];
    89. newImageData.data[i] = R;
    90. newImageData.data[i + 1] = G;
    91. newImageData.data[i + 2] = B;
    92. newImageData.data[i + 3] = Alpha;
    93. }
    94. return newImageData;
    95. }
    96. // 创建灰度图像
    97. function createGrayscale(imgData) {
    98. const newData = Array(imgData.data.length).fill(0);
    99. imgData.data.forEach((_data, index) => {
    100. if ((index + 1) % 4 === 0) {
    101. const R = imgData.data[index - 3];
    102. const G = imgData.data[index - 2];
    103. const B = imgData.data[index - 1];
    104. const gray = ~~((R + G + B) / 3);
    105. newData[index - 3] = gray;
    106. newData[index - 2] = gray;
    107. newData[index - 1] = gray;
    108. newData[index] = 255; // Alpha 值固定为255
    109. }
    110. });
    111. return createImgData(newData);
    112. }
    113. // 获取图像的哈希指纹
    114. function getHashFingerprint(imgData) {
    115. const grayList = imgData.data.reduce((pre, cur, index) => {
    116. if ((index + 1) % 4 === 0) {
    117. pre.push(imgData.data[index - 1]);
    118. }
    119. return pre;
    120. }, []);
    121. const length = grayList.length;
    122. const grayAverage = grayList.reduce((pre, next) => pre + next, 0) / length;
    123. return grayList.map(gray => (gray >= grayAverage ? 1 : 0)).join('');
    124. }
    125. // 计算汉明距离
    126. function hammingDistance(hash1, hash2) {
    127. if (hash1.length !== hash2.length) {
    128. throw new Error('Hashes must have the same length');
    129. }
    130. let distance = 0;
    131. for (let i = 0; i < hash1.length; i++) {
    132. if (hash1[i] !== hash2[i]) {
    133. distance++;
    134. }
    135. }
    136. return distance;
    137. }

    原理是看了有一篇文章

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

    首先降低图片分辨率

    然后使用指纹提取

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

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

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

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

    例如:

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

    体验地址

    不许动 

  • 相关阅读:
    8、MyBatis核心配置文件之typeAliases(mybatis-config.xml)
    四边形不等式
    buuctf web [极客大挑战 2019]Http
    C++ SLT中的容器学习与函数谓词
    LLMs Python解释器程序辅助语言模型(PAL)Program-aided language models (PAL)
    【区块链技术与应用】(八)
    猫狗图像数据集上的深度学习模型性能对比
    哥斯拉加密WebShell过杀软
    scrcpy macos 编译安装最新版 1.2.4
    记一次线上bug:crontab 被意外清空
  • 原文地址:https://blog.csdn.net/shuishen49/article/details/132747350