当前位置: 首页 > news >正文

canvas实现图片标注,绘制区域

使用canvas绘制通过多边形标注区域

AI视频项目中需要分析图片,需要前台绘制区域,后端获取坐标然后识别图像,通过canvas

获取点然后连线绘图

 HEML代码段
   <div class="areaDrawing"><img src="@/assets/images/snapPhotos.png" /><canvas ref="canvas" style="position: absolute; top: 0; left: 0;" :width="canvasWidth":height="canvasHeight"></canvas></div>
 CSS代码段
.areaDrawing {position: relative;width: 400px; // 绘图区域宽度height: 300px; // 绘图区域高度img {position: absolute;top: 0;left: 0;height: 100%;width: 100%;}
}
 script代码段
<script>
// 脚本开始
export default {data() {return {canvasWidth: 400, // 画布的宽度canvasHeight: 300, // 画布的高度imageSrc: 'your_image_url_here', // 图像的URL地址context: null, // 画布上下文points: [], // 用于存储点的数组isDragging: false, // 是否正在拖拽draggingIndex: -1, // 当前拖拽的点的索引Drawing: false,//控制绘制};},methods: {// 处理点击事件,用于添加新点handleCanvasClick(event) {console.log(this.points.length, 'this.points.length');// 检查是否开启绘制if (!this.Drawing || this.points.length >= 4) {return;}// 获取点击点的坐标const rect = this.$refs.canvas.getBoundingClientRect();const x = event.clientX - rect.left;const y = event.clientY - rect.top;// 检查是否有重复点const isDuplicate = this.points.some(point => {return Math.abs(point.x - x) < 5 && Math.abs(point.y - y) < 5;});// 如果没有重复点,则添加新点并重新绘制if (!isDuplicate) {this.points.push({ x, y });this.redraw();}// 如果点的数量大于等于4个,则绘制多边形if (this.points.length >= 4) {this.drawPolygon(this.points);}},// 处理鼠标按下事件handleMouseDown(event) {if (this.Drawing) {return}// 获取鼠标按下点的坐标const rect = this.$refs.canvas.getBoundingClientRect();const x = event.clientX - rect.left;const y = event.clientY - rect.top;// 查找当前拖拽的点的索引this.draggingIndex = this.points.findIndex(point => {return Math.abs(point.x - x) < 5 && Math.abs(point.y - y) < 5;});// 如果存在拖拽的点,则设置拖拽状态为trueif (this.draggingIndex !== -1) {this.isDragging = true;}},// 处理鼠标移动事件handleMouseMove(event) {// 如果正在拖拽,则更新当前拖拽点的坐标并重新绘制if (this.isDragging) {const rect = this.$refs.canvas.getBoundingClientRect();const x = event.clientX - rect.left;const y = event.clientY - rect.top;this.points[this.draggingIndex].x = x;this.points[this.draggingIndex].y = y;this.redraw();}},// 处理鼠标释放事件handleMouseUp() {// 重置拖拽状态和拖拽点的索引this.isDragging = false;this.draggingIndex = -1;},// 绘制点drawPoint(x, y) {this.context.beginPath();this.context.arc(x, y, 5, 0, 2 * Math.PI, false);this.context.fillStyle = 'blue';this.context.fill();this.context.lineWidth = 1;this.context.strokeStyle = 'blue';this.context.stroke();},// 重新绘制画布redraw() {// 清空画布this.context.clearRect(0, 0, this.canvasWidth, this.canvasHeight);// 绘制多边形this.drawPolygon(this.points);// 绘制所有点,并连接相邻点this.points.forEach((point, index) => {this.drawPoint(point.x, point.y);if (index > 0) {this.context.beginPath();this.context.moveTo(this.points[index - 1].x, this.points[index - 1].y);this.context.lineTo(point.x, point.y);this.context.strokeStyle = 'blue';this.context.lineWidth = 1;this.context.stroke();}});// 连接第一个点和最后一个点,形成闭合的多边形if (this.points.length > 3) {this.context.beginPath();this.context.moveTo(this.points[this.points.length - 1].x, this.points[this.points.length - 1].y);this.context.lineTo(this.points[0].x, this.points[0].y);this.context.strokeStyle = 'blue';this.context.lineWidth = 1;this.context.stroke();}},// 绘制多边形drawPolygon(points) {if (points.length >= 2) {this.context.beginPath();this.context.moveTo(points[0].x, points[0].y);for (let i = 1; i < points.length; i++) {this.context.lineTo(points[i].x, points[i].y);}if (points.length === 4) {this.context.closePath();this.context.strokeStyle = 'red';this.context.lineWidth = 2;this.context.stroke();}}},// 动画方法,用于拖拽时重新绘制画布animate() {if (this.isDragging) {this.redraw();requestAnimationFrame(this.animate);}},//开始绘制handleDrawing() {this.Drawing = true;},//绘制微调resetDrawing() {this.Drawing = false;},//清除绘制clearDrawing() {this.points.length = 0;this.redraw()},},mounted() {// 获取画布上下文this.context = this.$refs.canvas.getContext('2d');// 添加事件监听器this.$refs.canvas.addEventListener('click', this.handleCanvasClick);this.$refs.canvas.addEventListener('mousedown', this.handleMouseDown);this.$refs.canvas.addEventListener('mousemove', this.handleMouseMove);this.$refs.canvas.addEventListener('mouseup', this.handleMouseUp);this.$refs.canvas.addEventListener('mouseleave', this.handleMouseUp);// 绑定动画方法的上下文this.animate = this.animate.bind(this);},
};
// 脚本结束
</script>

 

 

 

 

相关文章:

canvas实现图片标注,绘制区域

使用canvas绘制通过多边形标注区域 AI视频项目中需要分析图片&#xff0c;需要前台绘制区域&#xff0c;后端获取坐标然后识别图像&#xff0c;通过canvas 获取点然后连线绘图 HEML代码段 <div class"areaDrawing"><img src"/assets/images/snapPhotos…...

SELECT COUNT(*) 会造成全表扫描吗?

前言 SELECT COUNT(*)会不会导致全表扫描引起慢查询呢&#xff1f; SELECT COUNT(*) FROM SomeTable 网上有一种说法&#xff0c;针对无 where_clause 的 COUNT(*)&#xff0c;MySQL 是有优化的&#xff0c;优化器会选择成本最小的辅助索引查询计数&#xff0c;其实反而性能…...

python考前复习(90题)

文章目录 1.Python特性的是( )。 A. 面向对象 B. 高可移植性 C. 开源、免费 2.临时改变Python语言安装源应当使用的选项是 –index-url 3.Python脚本文件的扩展名为( ) .py 4.安装Python语言的软件包使用的命令是&#xff08; &#xff09; pip install 5 . (单选题)以下哪项是…...

根据SpringBoot Guides完成进行示例学习(详细步骤)

目录 1.打开Spring | Guides官网&#xff0c;或者直接搜索springboot都可 2.选择要学习的内容 3.根据提示的网址&#xff0c;Git到本地 4.将文件用IDEA打开&#xff0c;根据教程完成示例&#xff0c;这里不做细致讲解 5.运行项目 6.在终端查看运行结果 以Scheduling Task…...

waf、yakit和ssh免密登录

WAF安全狗 脏数据适用于所有漏洞绕过waf&#xff0c;但是前提条件垃圾信息必须放在危险信息前&#xff0c;是不能打断原有数据包的结构&#xff0c;不能影响后端对数据包的解析。 以DVWA靶场文件上传为例 新建php文件 上传文件被安全狗拦截 使用bp抓包查看 在数据包Content-…...

【AIGC核心技术剖析】大型语言和视觉助手——LLaVA(论文+源码)

🔥 [新!LLaVA-1.5 在 11 个基准测试上实现了 SoTA,只需对原始 LLaVA 进行简单的修改,利用所有公共数据,在单个 1-A8 节点上在 ~100 天内完成训练,并超越使用数十亿级数据的方法。 LLaVA代表了一种新颖的端到端训练大型多模态模型,结合了视觉编码器和骆马 对于通用的视…...

IBM的WAS简介与基本使用手册

IBM的WAS简介与基本使用手册 1. 基本介绍 WebSphereApplication Server(简称WAS)是IBM的应用服务器 基本结构:单元(cell) ——> 多个节点(node) ——> 多个服务(server) ——> 多个应用(app) 单元是整个分布式网络中一个或多个节点的逻辑分组单元是一个配置概念, 是…...

Deno 快速入门

目录 1、简介 2、安装Deno MacOS下安装 Windows下安装 Linux 下安装 3、创建并运行TypeScript程序 4、内置Web API和Deno命名空间 5、运行时安全 6、导入JavaScript模块 7、远程模块和Deno标准库 8、使用deno.json配置您的项目 9、Node.js API和npm包 10、配置IDE…...

【计算机网络笔记】OSI参考模型基本概念

系列文章目录 什么是计算机网络&#xff1f; 什么是网络协议&#xff1f; 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能&#xff08;1&#xff09;——速率、带宽、延迟 计算机网络性能&#xff08;2&#xff09;…...

ConnectTimeout和ReadTimeout所代表的意义

ConnectTimeout和ReadTimeout所代表的意义 ConnectTimeout 指的是建立连接所用的时间&#xff0c;适用于网络状况正常的情况下&#xff0c;两端连接所用的时间。在java中&#xff0c;网络状况正常的情况下&#xff0c;例如使用HttpClient或者HttpURLConnetion连接时设置参数c…...

使用Python计算平面多边形间最短距离,数据需要从excel表格中导入

使用Python计算平面多边形间最短距离&#xff0c;数据需要从excel表格中导入&#xff0c; * 多边形种类包括&#xff08;圆形、矩形、六边形、五边形、跑道形/胶囊形&#xff09;&#xff0c; * Python代码需要使用gjk算法进行判断两个多边形间是否重叠&#xff0c; * 如果未重…...

华为数通方向HCIP-DataCom H12-831题库(多选题:1-20)

第01题 如图所示,路由器所有的接口开启OSPF,图中标识的ip地址为设备的Loopback0接口的IP地址,R1、R2,R3的Loopback0通告在区域1,R4的Loopback0通告在区域0、R5的Lopback0通告在区域2,下列哪些IP地址之间可以相互Ping通? A、10.0.3.3和10.0.5.5 B、10.0.4.4和10.0.2.2 …...

CCC数字钥匙设计【NFC】--通过NFC进行车主配对Phase3

1、车主配对流程介绍 车主配对可以通过车内NFC进行&#xff0c;若支持UWB测距&#xff0c;也可以通过蓝牙/UWB进行。通过NFC进行车主配对总共有5个Phase。本文档主要对Phase3进行介绍。 1) Phase0&#xff1a;准备阶段&#xff1b; 2) Phase1&#xff1a;启动流程&#xff1…...

开源OA协同办公系统,集成Flowable流程引擎 可拖拽创建个性表单

源码下载&#xff1a;https://download.csdn.net/download/m0_66047725/88403340 源码下载2&#xff1a; 关注我留言 开源OA协同办公系统&#xff0c;集成Flowable流程引擎 可拖拽创建个性表单。基于RuoYi-VUE版本开发。 1、使用RuoYi-Vue的基础上开发。 2、集成flowable&a…...

为什么嵌入通常优于TF-IDF:探索NLP的力量

塔曼纳 一、说明 自然语言处理&#xff08;NLP&#xff09;是计算机科学的一个领域&#xff0c;涉及人类语言的处理和分析。它用于各种应用程序&#xff0c;例如聊天机器人、情绪分析、语音识别等。NLP 中的重要任务之一是文本分类&#xff0c;我们根据文本的内容将文本分类为不…...

oracle-AWR报告生成方法

AWR报告生成方法 1. 以oracle用户登陆服务器 2. 进入到要保存awr报告的目录 3. 以sysdba身份连接数据库 sqlplus / as sysdba4. 执行生成AWR报告命令 ?/rdbms/admin/awrrpt.sql5. 选择AWR报告的文件格式 6. 选择生成多少天的AWR报告 7. 选择报告的快照起始和结束ID 8. 输入生…...

笙默考试管理系统-MyExamTest----codemirror(37)

笙默考试管理系统-MyExamTest----codemirror&#xff08;36&#xff09; 目录 一、 笙默考试管理系统-MyExamTest 二、 笙默考试管理系统-MyExamTest 三、 笙默考试管理系统-MyExamTest 四、 笙默考试管理系统-MyExamTest 五、 笙默考试管理系统-MyExamTest 笙默考试…...

【Unity3D编辑器拓展】Unity3D的IMGUI、GUI、GUILayout、EditorGUI、EditorGUILayout、OnGUI【全面总结】

推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址我的个人博客 大家好&#xff0c;我是佛系工程师☆恬静的小魔龙☆&#xff0c;不定时更新Unity开发技巧&#xff0c;觉得有用记得一键三连哦。 一、前言 在开发中&#xff0c;常常会遇到要使用OnGUI的地方。 也会遇到…...

11. 机器学习 - 评价指标2

文章目录 混淆矩阵F-scoreAUC-ROC 更多内容&#xff1a; 茶桁的AI秘籍 Hi, 你好。我是茶桁。 上一节课&#xff0c;咱们讲到了评测指标&#xff0c;并且在文章的最后提到了一个矩阵&#xff0c;我们就从这里开始。 混淆矩阵 在我们实际的工作中&#xff0c;会有一个矩阵&am…...

Nginx的代理和负载均衡

一、nginx的代理方式 1.1 七层代理 七层代理&#xff1a;基于http协议&#xff0c;对请求的内容进行处理&#xff0c;然后转发到后端服务器 七层代理是客户端请求代理服务器&#xff0c;由代理服务器转发客户端的http请求&#xff0c;转发到内部的服务器进行处理(服务器可以是…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》

引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

大型活动交通拥堵治理的视觉算法应用

大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动&#xff08;如演唱会、马拉松赛事、高考中考等&#xff09;期间&#xff0c;城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例&#xff0c;暖城商圈曾因观众集中离场导致周边…...

Java如何权衡是使用无序的数组还是有序的数组

在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat&#xff08;I/O Statistics&#xff09;是Linux系统下用于监视系统输入输出设备和CPU使…...

跨链模式:多链互操作架构与性能扩展方案

跨链模式&#xff1a;多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈&#xff1a;模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展&#xff08;H2Cross架构&#xff09;&#xff1a; 适配层&#xf…...

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...

算法岗面试经验分享-大模型篇

文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer &#xff08;1&#xff09;资源 论文&a…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档&#xff09;&#xff0c;如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下&#xff0c;风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...