tensorflow.js 视频图片多目标检测

news2024/12/26 0:53:47

前言:

Tensorflow.js 官方提供了很多常用模型库,涵盖了平时开发中大部分场景的模型。例如,前面提到的图片识别,除此之外还有人体姿态识别,目标物体识别,语音文字等识别。其中一些可能是 Python 转换而来,但都是开发人员用海量数据或资源训练的,个人觉得准确度能满足大部分功能开发要求。这里要介绍的是目标物体识别模型 ——CooSSD。

目标检测在机器视觉中已经很常见了,就是模型可以对图片或者视频中的物体进行识别,并预测其最大概率的名称和展示概率值。以下就先以 Github 上 Coo-SSD 图片目标检测为例,最后再弄一个视频的目标实时识别。

demo 运行:

tensorflow.js 提供的例子是通过 yarn,由于我本地环境原因,就以 npm 和 parcel 运行其效果。先本地创建项目文件夹,然后再分别创建 index.html, script.js, package.json 和添加几张图片。

1. 依赖包安装

(1). package.json 配置,安装 tfjs-backend-cpu, tfjs-backend-webgl 和模型

{
  "name": "tfjs-coco-ssd-demo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "dependencies": {
    "@tensorflow-models/coco-ssd": "^2.2.2",
    "@tensorflow/tfjs-backend-cpu": "^3.3.0",
    "@tensorflow/tfjs-backend-webgl": "^3.3.0",
    "@tensorflow/tfjs-converter": "^3.3.0",
    "@tensorflow/tfjs-core": "^3.3.0",
    "stats.js": "^0.17.0"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "browserslist": [
    "last 1 Chrome version"
  ]
}

(2). 命令切换到项目目录,运行 npm install

2. 代码:

(1). index.html

<h1>TensorFlow.js Object Detection</h1><selectid='base_model'>
	<optionvalue="lite_mobilenet_v2">SSD Lite Mobilenet V2</option>
	<optionvalue="mobilenet_v1">SSD Mobilenet v1</option>
	<optionvalue="mobilenet_v2">SSD Mobilenet v2</option></select><buttontype="button"id="run">Run</button><buttontype="button"id="toggle">Toggle Image</button><div><imgid="image" /><canvasid="canvas"width="600"height="399"></canvas></div><scriptsrc="script.js"></script>

(2). script.js

import'@tensorflow/tfjs-backend-cpu';
import'@tensorflow/tfjs-backend-webgl';

import * as cocoSsd from'@tensorflow-models/coco-ssd';

import imageURL from'./image3.jpg';
import image2URL from'./image5.jpg';

let modelPromise;

window.onload = () => modelPromise = cocoSsd.load();

const button = document.getElementById('toggle');
button.onclick = () => {
  image.src = image.src.endsWith(imageURL) ? image2URL : imageURL;
};

const select = document.getElementById('base_model');
select.onchange = async (event) => {
  const model = await modelPromise;
  model.dispose();
  modelPromise = cocoSsd.load(
      {base: event.srcElement.options[event.srcElement.selectedIndex].value});
};

const image = document.getElementById('image');
image.src = imageURL;

const runButton = document.getElementById('run');
runButton.onclick = async () => {
  const model = await modelPromise;
  console.log('model loaded');
  console.time('predict1');
  const result = await model.detect(image);
  console.timeEnd('predict1');


  const c = document.getElementById('canvas');
  const context = c.getContext('2d');
  context.drawImage(image, 0, 0);
  context.font = '10px Arial';

  console.log(result);

  console.log('number of detections: ', result.length);
  for (let i = 0; i < result.length; i++) {
    context.beginPath();
    context.rect(...result[i].bbox);
    context.lineWidth = 1;
    context.strokeStyle = 'green';
    context.fillStyle = 'green';
    context.stroke();
    context.fillText(
        result[i].score.toFixed(3) + ' ' + result[i].class, result[i].bbox[0],
        result[i].bbox[1] > 10 ? result[i].bbox[1] - 5 : 10);
  }
};

(3). 切换到项目目录,运行 parcel index.html

3. 运行效果

检测视频目标:

经过上面 demo 的图片检测发现,用于对某资源 (图片,视频) 进行检测的函数是 detect ()。查看该函数所处 Coco-SSD 文件发现,detect 函数接收三个参数,第一个参数可以是 tensorflow 张量,也可以分别是 DOM 里的图片,视频,画布等 HTML 元素,第二第三个参数分别用于过滤返回结果的最大识别目标数和最小概率目标,而返回自然就是一个 box, 按概率值降序排列。

1. 实现流程:

(1). 给视频标签添加播放监听

(2). 页面渲染完成加载 Coco-SSD 模型

(3). 模型加载成功轮询识别视频 (video 标签)

(4). 监听到视频播放停止关闭轮询检测

2. 编码:

(1). html 部分

<style>#big-box {
        position: relative;
    }

    #img-box {
        position: absolute;
        top: 0px;
        left: 0px;
    }

    #img-boxdiv {
        position: absolute;
        /*border: 2px solid #f00;*/pointer-events: none;
    }

    #img-boxdiv.className {
        position: absolute;
        top: 0;
        /* background: #f00; */color: #fff;
    }

    #myPlayer {
        max-width: 600px;
        width: 100%;
    }
</style><divid="showBox">等待模型加载...</div><br><divid="big-box"><videoid="myPlayer"muted="true"autoplaysrc="persons.mp4"controls=""playsinline=""webkit-playsinline=""></video><divid="img-box"></div></div><scriptsrc="persons.js"></script>

(2). js 部分

import'@tensorflow/tfjs-backend-cpu';
import'@tensorflow/tfjs-backend-webgl';

import * as cocoSsd from'@tensorflow-models/coco-ssd';

var myModel = null;
var V = null;

var requestAnimationFrameIndex = null;
var myPlayer = document.getElementById("myPlayer");

var videoHeight = 0;
var videoWidth = 0;
var clientHeight = 0;
var clientWidth = 0;

var modelLoad = false;
var videoLoad = false;

window.onload = function () {

    myPlayer.addEventListener("canplay", function () {
        videoHeight = myPlayer.videoHeight;
        videoWidth = myPlayer.videoWidth;
        clientHeight = myPlayer.clientHeight;
        clientWidth = myPlayer.clientWidth;
        V = this;
        videoLoad = true;
    })

    loadModel();
}

functionloadModel() {
    if (modelLoad) {
        return;
    }
    
    cocoSsd.load().then(model => {
        var showBox = document.getElementById("showBox");
        showBox.innerHTML = "载入成功";
        myModel = model;
        detectImage();
        modelLoad = true;
    });
}

functiondetectImage() {
    var showBox = document.getElementById("showBox");
    // 分类名var classList = [];
    // 分类颜色框var classColorMap = ["red", "green", "blue", "white"];
    // 颜色角标var colorCursor = 0;

    showBox.innerHTML = "检测中...";

    if (videoLoad) {
        myModel.detect(V).then(predictions => {

            showBox.innerHTML = "检测结束";

            const $imgbox = document.getElementById('img-box');

            $imgbox.innerHTML = ""

            predictions.forEach(box => {

            	if (classList.indexOf(box.class) != -1) {
            		classList.push(box.class);
            	}

            	console.log(box);

            	var borderColor = classColorMap[colorCursor%4];
// console.log(colorCursor);// console.log(borderColor);const $div = document.createElement('div')
                //$div.className = 'rect';
                $div.style.border = "2px solid "+borderColor;
                var heightScale = (clientHeight / videoHeight);
                var widthScale = (clientWidth / videoWidth)
                var transformTop = box.bbox[1] * heightScale;
                var transformLeft = box.bbox[0] * widthScale;
                var transformWidth = box.bbox[2] * widthScale;
                var transformHeight = box.bbox[3] * heightScale;
                var score = box.score.toFixed(3);
                $div.style.top = transformTop + 'px'
                $div.style.left = transformLeft + 'px'
                $div.style.width = transformWidth + 'px'
                $div.style.height = transformHeight + 'px'
                $div.innerHTML = `<span class='className'>${box.class}${score}</span>`

                $imgbox.appendChild($div)

                colorCursor++;
            })

            setTimeout(function () {
                detectImage();
            }, 10);

        });

    }
}

3. 演示效果

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

前后端RSA互相加解密、加签验签、密钥对生成(Java)

目录一、序言二、关于PKCS#1和PKCS#8格式密钥1、简介2、区别二、关于JSEncrypt三、关于jsrsasign四、前端RSA加解密、加验签示例1、相关依赖2、cryptoUtils工具类封装3、测试用例五、Java后端RSA加解密、加验签1、CryptoUtils工具类封装2、测试用例六、前后端加解密、加验签交互…

导数与微分总复习——“高等数学”

各位CSDN的uu们你们好呀&#xff0c;今天&#xff0c;小雅兰来复习一下之前学过的知识点&#xff0c;也就是导数与微分的总复习&#xff0c;依旧是高等数学的内容&#xff0c;主要是明天就要考高等数学了&#xff0c;哈哈哈&#xff0c;下面&#xff0c;让我们一起进入高等数学…

取电芯片全协议都可兼容

乐得瑞PD协议芯片/PD取电芯片/PD受电端协议芯片 支持5/9/12/15/20v定制 1、概述 LDR6328S 是乐得瑞科技有限公司开发的一款兼容 USB PD、QC 和 AFC 协议的 Sink 控制器。 LDR6328S 从支持 USB PD、QC 和 AFC 协议的适配器取电&#xff0c;然后供电给设备。比如可以配置适配器输…

二十九、异常处理

目录 ①前言: ②常见的运行时异常 ③常见的编译时异常 ④异常的处理机制 ⑤自定义异常 ①前言: 1.什么是异常&#xff1f; 异常是程序在“编译”或者“执行”的过程中可能出现的问题&#xff0c;注意&#xff1a;语法错误不算在异常体系中。 比如: 数据索引越界异常&…

C语言的程序环境和预处理详解

目录 一、程序的翻译环境和执行环境 二、编译和链接详解 2、1 翻译环境 2、2 编译过程详解 2、3 执行环境 三、预处理详解 3、1 预定义符号 3、2 #define 3、2、1 #define定义的符号 3、2、2 #define 定义宏 3、2、3 #define 替换规则 3、3 宏和函数的对比 3、4 条件编译 3、5…

CUDA中的底层驱动API

文章目录CUDA底层驱动API1. Context2. Module3. Kernel Execution4. Interoperability between Runtime and Driver APIs5. Driver Entry Point Access5.1. Introduction5.2. Driver Function Typedefs5.3. Driver Function Retrieval5.3.1. Using the driver API5.3.2. Using …

Springboot扩展点之BeanPostProcessor

前言 Springboot&#xff08;Spring&#xff09;的扩展点其实有很多&#xff0c;但是都有一个共同点&#xff0c;都是围绕着Bean和BeanFactory&#xff08;容器&#xff09;展开的&#xff0c;其实这也很好理解&#xff0c;Spring的核心是控制反转、依赖注入、面向切面编程&…

西湖论剑 2023 比赛复现

WEB real_ez_node 在 route/index.js 中&#xff1a; router.post(/copy,(req,res)>{res.setHeader(Content-type,text/html;charsetutf-8)var ip req.connection.remoteAddress;console.log(ip);var obj {msg: ,}if (!ip.includes(127.0.0.1)) {obj.msg"only for…

【设计模式之美 设计原则与思想:面向对象】13丨实战二(上):如何对接口鉴权这样一个功能开发做面向对象分析?

面向对象分析&#xff08;OOA&#xff09;、面向对象设计&#xff08;OOD&#xff09;、面向对象编程&#xff08;OOP&#xff09;&#xff0c;是面向对象开发的三个主要环节。在前面的章节中&#xff0c;我对三者的讲解比较偏理论、偏概括性&#xff0c;目的是让你先有一个宏观…

电脑重装系统注册表恢复方法

​今天讲关于大家的电脑在遇到一些故障的时候&#xff0c;以及电脑用久了之后会卡顿&#xff0c;那么这时候大家一般都会给电脑重装系统。重装系统之后却发现自己电脑里的注册表不见了&#xff0c;重装系统后怎么恢复注册表?小编就带着大家一起学习重装系统注册表恢复到底是怎…

【博客615】通过systemd设置cgroup来限制服务资源争抢

通过systemd设置cgroup来限制服务资源争抢 1、场景 我们的宿主机上通常会用systemctl来管理一些agent服务&#xff0c;此时我们需要限制服务的cpu&#xff0c;memory等资源用量&#xff0c;以防止服务之前互相争抢资源&#xff0c;导致某些核心agent运行异常 2、systemd与cgro…

生成树协议 — STP

目录 一、环路的出现 1、广播风暴&#xff1a; 2、MAC地址表翻滚&#xff1a; 二、生成树 1、定义&#xff1a; 2、生成树使用的算法&#xff1a; 三、802.1D 1、BPDU&#xff1a; 2、TCN—拓扑变更消息&#xff08;也是BPDU&#xff09;&#xff1a; 3、部分名词&am…

【Python小游戏】某程序员将套圈游戏玩儿到了巅峰,好嗨哟~Pygame代码版《牛牛套圈》已上线,大人的套圈游戏太嗨了,小孩勿进。

前言 世上选择那么多。 关注栗子同学会是您最明智的选择哦。 所有文章完整的素材源码都在&#x1f447;&#x1f447; 粉丝白嫖源码福利&#xff0c;请移步至CSDN社区或文末公众hao即可免费。 “幸运牛牛套圈圈”套住欢乐&#xff0c;圈住幸福&#xff0c;等你来挑战&#xf…

用OpeAI API打造ChatGPT桌面端应用

用OpeAI API打造ChatGPT桌面端应用 自从《如何用ChatGPT高效完成工作》这篇文章火了之后&#xff0c;我在公司内部分享了一下”摸鱼“的先进经验&#xff0c;激发起广大同事一起”摸鱼“的热情。但是注册ChatGPT账号非常麻烦&#xff0c;既要Science上网&#xff0c;又要海外手…

Spark环境搭建

文章目录Spark 概述Spark 发展历史使用现状官网介绍流行原因组成模块Spark环境搭建-Local模式(本地模式)Spark环境搭建-Standalone(独立集群)Spark环境搭建-Standalone-HA(高可用)Spark环境搭建-Spark-On-Yarn两种模式Spark 概述 Spark 发展历史 2009年诞生2014年成为Apache顶…

Java笔记-线程中断

线程的中断 1.应用场景&#xff1a; 假设从网络下载一个100M的文件&#xff0c;如果网速很慢&#xff0c;用户等得不耐烦&#xff0c;就可能在下载过程中点“取消”&#xff0c;这时&#xff0c;程序就需要中断下载线程的执行。 2.常用中断线程的方法&#xff1a; 1.使用标…

Canvas鼠标滚轮缩放以及画布拖动(图文并茂版)

Canvas鼠标滚轮缩放以及画布拖动 本文会带大家认识Canvas中常用的坐标变换方法 translate 和 scale&#xff0c;并结合这两个方法&#xff0c;实现鼠标滚轮缩放以及画布拖动功能。 Canvas的坐标变换 Canvas 绘图的缩放以及画布拖动主要通过 CanvasRenderingContext2D 提供的 …

C++设计模式(13)——装饰模式

亦称&#xff1a; 装饰者模式、装饰器模式、Wrapper、Decorator 意图 装饰模式是一种结构型设计模式&#xff0c; 允许你通过将对象放入包含行为的特殊封装对象中来为原对象绑定新的行为。 问题 假设你正在开发一个提供通知功能的库&#xff0c; 其他程序可使用它向用户发…

注册ChatGPT的辛酸血泪史,不能算教程的教程

注册ChatGPT的血泪史 2月份了&#xff0c;改论文降重了&#xff0c;所以想搞个ChatGPT玩玩&#xff0c;本以为有渠道能顺序上车&#xff0c;但是看了很多教程&#xff0c;也进了很多交流群&#xff0c;都喵的(要不是卖号&#xff0c;租体验&#xff0c;liar)&#xff0c;所以自…

java ssm高校教材管理平台 idea maven

设计并且实现一个基于JSP技术的高校教材管理平台的设计与实现。采用MYSQL为数据库开发平台&#xff0c;SSM框架&#xff0c;Tomcat网络信息服务作为应用服务器。高校教材管理平台的设计与实现的功能已基本实现&#xff0c;主要学生、教材管理、学习教材、教材入库、教材领取、缴…