OpenCV实战——OpenCV.js介绍

OpenCV实战——OpenCV.js介绍

    • 0. 前言
    • 1. OpenCV.js 简介
    • 2. 网页编写
    • 3. 调用 OpenCV.js 库
    • 4. 完整代码
    • 相关链接

0. 前言

本节介绍如何使用 JavaScript 通过 OpenCV 开发计算机视觉算法。在 OpenCV.js 之前,如果想要在 Web 上执行一些计算机视觉任务,必须在服务器使用 C++ 进行开发,但在 OpenCV.js 中,使用 Web 浏览器的客户端拥有了直接使用计算机视觉应用的可能性。在本节中,我们将编写一个非常简单的应用,将图像加载到 HTML img 标签中,转换图像色彩空间并在 canvas 元素中绘制。

1. OpenCV.js 简介

OpenCV.jsOpenCV 函数的端口,将 C++ 代码编译为 JavaScriptOpenCV 使用 EmscriptenC++ 函数编译为 Asm.jsWebAssembly 目标

  • Asm.js 是经过高度优化的,其接近本机代码,但速度比相同的本机可执行应用程序大约慢 2 倍(具体取决于浏览器和计算机性能)
  • WebAssembly 是一种新 Web 标准,它定义了一种用于在网页中执行代码的二进制格式。旨在补充 JavaScript,加速代码运行速度以接近本机代码执行速度。该技术是提高计算机视觉性能和将 OpenCV 移植到 JavaScript 的最佳选择

WebAssembly 针对速度进行了高度优化,并实现了速度接近本机的代码。接下来,我们构建一个简单的网页结构,通过一个简单的按钮,可以将图像加载到用作输入图像的 img 元素中。读取 img 元素内容,可以将其加载到 cv::Mat 中并应用 OpenCV 可以提供的所有计算机视觉函数。在示例代码中,我们将彩色图像转换为灰度图像。OpenCV.js 修改了 imshow 函数,允许我们在 canvas 元素而不是新窗口中显示 cv::Mat,使我们能够与网页进行交互。

2. 网页编写

在使用 OpenCV.js 之前,我们需要编写一个网页作为用户界面。使用 imgcanvasbutton 元素创建一个 HTML 页面:

<!doctype html>
<html lang="en">
<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <style>
    #container {min-height:300px;}
    #canvasOutput, #imageSrc{
        background:#ccc;
        min-width:300px;
        min-height:300px;
        display:block;
        float:left;	
        margin-left:20px;
    }
    </style>
    <title>OpenCV Computer vision on Web. Packt Publishing.</title>
</head>
<body>
    <div id="status" class="alert alert-primary" role="alert">Loading OpenCV...</div>
    <div id="container">        
        <img id="imageSrc" alt="No Image" class="small" src="img/gray.png">
            <canvas id="canvasOutput" class="small" height="300px"></canvas>
    </div>        
    <input type="file" id="fileInput" name="file" accept="image/*">

3. 调用 OpenCV.js 库

(1) 在网页中加载 OpenCV JavaScript 库:

    <!-- OPENCV -->
    <script async="" src="data/opencv.js" type="text/javascript" onload="onOpenCvReady();" onerror="onOpenCvError();"></script>

(2)script 包装器中创建应用程序,我们需要获取输入按钮和图像元素的变量:

    <script type="text/javascript">
        let imgElement = document.getElementById('imageSrc');
        let inputElement = document.getElementById('fileInput');

(3) 点击按钮时,将选中的图片加载到 img 元素中:

        inputElement.addEventListener('change', (e) => {
            imgElement.src = URL.createObjectURL(e.target.files[0]);
        }, false);

(4) 当图像加载到 img 元素中时,使用 OpenCV 函数应用所需操作。在本节中,我们将 RGB 图像转换为灰度图像,使用 imshow 函数通过将结果传递给函数 canvasIDcanvas 元素中显示结果:

        imgElement.onload = function() {
            let mat = cv.imread(imgElement);
            cv.cvtColor(mat, mat, cv.COLOR_BGR2GRAY);
            cv.imshow('canvasOutput', mat);estimateF
            mat.delete();
        };

应用 OpenCV.js 结果

4. 完整代码

完整代码 opencvjs_example.html 如下所示:

<!doctype html>
<html lang="en">
<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <style>
    #container {min-height:300px;}
    #canvasOutput, #imageSrc{
        background:#ccc;
        min-width:300px;
        min-height:300px;
        display:block;
        float:left;	
        margin-left:20px;
    }
    </style>
    <title>OpenCV Computer vision on Web. Packt Publishing.</title>
</head>
<body>
    <div id="status" class="alert alert-primary" role="alert">Loading OpenCV...</div>
    <div id="container">        
        <img id="imageSrc" alt="No Image" class="small" src="img/gray.png">
            <canvas id="canvasOutput" class="small" height="300px"></canvas>
    </div>        
    <input type="file" id="fileInput" name="file" accept="image/*">

    <!-- Optional JavaScript -->
    <script src="data/common.js"></script>
    <!-- OPENCV -->
    <script async="" src="data/opencv.js" type="text/javascript" onload="onOpenCvReady();" onerror="onOpenCvError();"></script>

    <script type="text/javascript">
        let imgElement = document.getElementById('imageSrc');
        let inputElement = document.getElementById('fileInput');
        
        inputElement.addEventListener('change', (e) => {
            imgElement.src = URL.createObjectURL(e.target.files[0]);
        }, false);
        
        imgElement.onload = function() {
            let mat = cv.imread(imgElement);
            cv.cvtColor(mat, mat, cv.COLOR_BGR2GRAY);
            cv.imshow('canvasOutput', mat);
            mat.delete();
        };
        
        function onOpenCvReady() { // eslint-disable-line no-unused-vars
            document.getElementById('status').innerHTML = '<b>OpenCV.js is ready</b>.' +
                'You can upload an image.<br>' +
                'The <b>imageSrc</b> is a &lt;img&gt; element used as cv.Mat input. ' +
                'The <b>canvasOutput</b> is a &lt;canvas&gt; element used as cv.Mat output.';
        }
        
        function onOpenCvError() { // eslint-disable-line no-unused-vars
            let element = document.getElementById('status');
            element.setAttribute('class', 'err');
            element.innerHTML = 'Failed to load opencv.js';
        }
        </script>
</body>
</html>

相关链接

OpenCV实战(1)——OpenCV与图像处理基础
OpenCV实战(2)——OpenCV核心数据结构
OpenCV实战(3)——图像感兴趣区域
OpenCV实战(4)——像素操作
OpenCV实战(5)——图像运算详解
OpenCV实战(6)——OpenCV策略设计模式
OpenCV实战(7)——OpenCV色彩空间转换
OpenCV实战(8)——直方图详解
OpenCV实战(9)——基于反向投影直方图检测图像内容
OpenCV实战(10)——积分图像详解
OpenCV实战(11)——形态学变换详解
OpenCV实战(12)——图像滤波详解
OpenCV实战(13)——高通滤波器及其应用
OpenCV实战(14)——图像线条提取
OpenCV实战(15)——轮廓检测详解
OpenCV实战(16)——角点检测详解
OpenCV实战(17)——FAST特征点检测
OpenCV实战(18)——特征匹配
OpenCV实战(19)——特征描述符
OpenCV实战(20)——图像投影关系
OpenCV实战(21)——基于随机样本一致匹配图像
OpenCV实战(22)——单应性及其应用
OpenCV实战(23)——相机标定
OpenCV实战(24)——相机姿态估计
OpenCV实战(25)——3D场景重建
OpenCV实战(26)——视频序列处理
OpenCV实战(27)——追踪视频中的特征点
OpenCV实战(28)——光流估计
OpenCV实战(29)——视频对象追踪
OpenCV实战(30)——OpenCV与机器学习的碰撞
OpenCV实战(31)——基于级联Haar特征的目标检测
OpenCV实战(32)——使用SVM和定向梯度直方图执行目标检测
OpenCV实战(33)——OpenCV与深度学习的碰撞

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

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

相关文章

【实战Flask API项目指南】之七 用JWT进行用户认证与授权

实战Flask API项目指南之 用JWT进行用户认证与授权 本系列文章将带你深入探索实战Flask API项目指南&#xff0c;通过跟随小菜的学习之旅&#xff0c;你将逐步掌握 Flask 在实际项目中的应用。让我们一起踏上这个精彩的学习之旅吧&#xff01; 前言 当小菜踏入Flask后端开发…

【卷积神经网络】YOLO 算法原理

在计算机视觉领域中&#xff0c;目标检测&#xff08;Object Detection&#xff09;是一个具有挑战性且重要的新兴研究方向。目标检测不仅要预测图片中是否包含待检测的目标&#xff0c;还需要在图片中指出它们的位置。2015 年&#xff0c;Joseph Redmon, Santosh Divvala 等人…

防火墙日志记录和分析

防火墙监控进出网络的流量&#xff0c;并保护部署防火墙的网络免受恶意流量的侵害。它是一个网络安全系统&#xff0c;它根据一些预定义的规则监控传入和传出的流量&#xff0c;它以日志的形式记录有关如何管理流量的信息&#xff0c;日志数据包含流量的源和目标 IP 地址、端口…

Everything结合内网穿透搭建在线资料库,一秒实现随时随地访问

Everythingcpolar搭建在线资料库&#xff0c;实现随时随地访问 文章目录 Everythingcpolar搭建在线资料库&#xff0c;实现随时随地访问前言1.软件安装完成后&#xff0c;打开Everything2.登录cpolar官网 设置空白数据隧道3.将空白数据隧道与本地Everything软件结合起来总结 前…

在Ubuntu上安装Redis并学习使用get、set和keys命令

目录 安装Redis切换到root用户搜索redis相关软件包安装redis修改配置文件重启服务器使用redis客户端连接服务器 get与set命令keys 安装Redis 我们在Ubuntu20.04上进行Redis的安装 切换到root用户 使用su命令&#xff1a; 在终端中&#xff0c;输入su并按回车键。然后输入roo…

C++ 输入输出流

iostream库&#xff0c;包含两个基础类型istream(输入流)和ostream(输出流)。一个流就是一个字符序列。 流 输入输出产生的字符串称为流。 被称为流的原因&#xff1a;所有的字符都在缓冲区中&#xff0c;从缓冲区拿/放都是顺序进行的&#xff0c;字符串的消耗&#xff0c;像…

恒驰服务 | 华为云数据使能专家服务offering之大数据建设

恒驰大数据服务主要针对客户在进行智能数据迁移的过程中&#xff0c;存在业务停机、数据丢失、迁移周期紧张、运维成本高等问题&#xff0c;通过为客户提供迁移调研、方案设计、迁移实施、迁移验收等服务内容&#xff0c;支撑客户实现快速稳定上云&#xff0c;有效降低时间成本…

vue封装独立组件:实现分格密码输入框/验证码输入框

目录 第一章 实现效果 第二章 核心实现思路 第三章 封装组件代码实现 第一章 实现效果 为了方便小编的父组件随便找了个页面演示的通过点击按钮&#xff0c;展示子组件密码输入的输入框通过点击子组件输入框获取焦点&#xff0c;然后输入验证码数字即可子组件的确定按钮是验…

MySQL Error 1215: Cannot add foreign key constraint

首先确保中介表中被设置外键的字段不能被设置为主键 第二步确保外键字段的属性与要连接的表的字段属性相同 第三步&#xff0c;设置表的选项 修改引擎为 InnoDB 三个表的引擎都要修改 最后就是运行代码 SET OLD_FOREIGN_KEY_CHECKSFOREIGN_KEY_CHECKS; SET FOREIGN_KEY_…

Android Icon 添加水印 Python脚本

源代码 # -*- coding: utf-8 -*- from PIL import Image 图片合成def mergePictureLXJ():commonIcon Image.open("icon.png")markIcon Image.open("领现金.png")markLayer Image.new(RGBA, commonIcon.size, (0, 0, 0, 0))markLayer.paste(markIcon, (0…

魔术般的速度,焕然一新的磁盘空间 - Magic Disk Cleaner for Mac 2023

在当今这个信息时代&#xff0c;我们的磁盘空间无时无刻不在被各种文件和数据所填满。无论是工作文件&#xff0c;还是日常生活的照片、视频&#xff0c;亦或是下载的各种应用程序&#xff0c;都在不断地蚕食着我们的磁盘空间。面对这种情况&#xff0c;一款高效、便捷的磁盘垃…

大厂面试题-为什么Netty线程池默认大小为CPU核数的2倍

目录 1、分析原因 2、如何衡量性能指标 3、总结与使用建议 1、分析原因 我们都知道使用多线程的本质是为了提升程序的性能&#xff0c;总体来说有两个最核心的指标&#xff0c;一个延迟&#xff0c;一个吞吐量。延迟指的是发出请求到收到响应的时间&#xff0c;吞吐量指的是…

Cannot resolve class ‘DruidDataSource‘

无法配置 DataSource&#xff1a;未指定“url”属性&#xff0c;并且无法配置嵌入数据源。 原因&#xff1a;无法确定合适的驱动程序类 原因是数据库没有配置或者没事错误 1配置配置文件报错 没有依赖 pom.xml加入 <dependency><groupId>com.alibaba</grou…

Oracle-执行计划生成及查看的几种方法

1. EXPLAIN FOR 语法&#xff1a; EXPLAIN PLAN FOR SQL语句SELECT * FROM TABLE(dbms_xplan.display());优点&#xff1a; 无需真正执行SQL 缺点&#xff1a; 没有输出相关的统计信息&#xff0c;例如产生了多少逻辑读、物理读、递归调用等情况无法判断处理了多少行无法判断…

单元测试反射注解

单元测试 就是针对最小的功能单元(方法)&#xff0c;编写测试代码对其进行正确性测试。 咱们之前是如何进行单元测试的&#xff1f;有啥问题 &#xff1f; Junit单元测试框架 可以用来对方法进行测试&#xff0c;它是由Junit公司开源出来的 具体步骤 Junit框架的常见注解…

前端埋点方式

前言&#xff1a; 想要了解用户在系统中所做的操作&#xff0c;从而得出用户在本系统中最常用的模块、在系统中停留的时间。对于了解用户的行为、分析用户的需求有很大的帮助&#xff0c;想实现这种需求可以通过前端埋点的方式。 埋点方式&#xff1a; 1.什么是埋点&#xff1f…

批量发送邮件时怎么使用蜂邮EDM与Outlook?

批量发送邮件时使用蜂邮EDM和Outlook的方法&#xff1f;群发电子邮件的技巧有哪些&#xff1f; 电子邮件仍然是最常用的沟通工具之一&#xff0c;无论是企业还是个人用户&#xff0c;都希望能够高效地一次性将邮件发送给多个收件人。在本文中&#xff0c;将深入探讨蜂邮EDM和O…

无限上下文,多级内存管理!突破ChatGPT等大语言模型上下文限制

目前&#xff0c;ChatGPT、Llama 2、文心一言等主流大语言模型&#xff0c;因技术架构的问题上下文输入一直受到限制&#xff0c;即便是Claude 最多只支持10万token输入&#xff0c;这对于解读上百页报告、书籍、论文来说非常不方便。 为了解决这一难题&#xff0c;加州伯克利…

循环神经网络(RNN)与长短期记忆网络(LSTM)

前言&#xff1a; 通过前面的学习&#xff0c;我们以BP神经网络为基础&#xff0c;认识到了损失函数&#xff0c;激活函数&#xff0c;以及梯度下降法的原理&#xff1b;而后学习了卷积神经网络&#xff0c;知道图像识别是如何实现的。今天这篇文章&#xff0c;讲述的就是计算机…

OSPF复习(2)

目录 一、LSA的头部 二、6种类型的LSA&#xff08;课堂演示&#xff09; 1、type1-LSA&#xff1a;----重要且复杂 2、type2-LSA&#xff1a; 3、type3-LSA&#xff1a; 4、type4-LSA&#xff1a; 5、type5-LSA&#xff1a; 6、type7-LSA&#xff1a; 三、OSPF的网络类…