vue实现图片框选标注

前言

前端有一个需求,对上传的图片进行检测识别,通过返回的接口坐标数据,对图片的某些区域进行框选并标注。如图:

在这里插入图片描述

开始

1、上传功能使用elementui的upload插件;
2、在图片上进行标注功能是元素定位在图片上层,通过坐标进行框选;

代码:

<template><div class="container"><!-- form表单 --><div><el-form ref="form" :model="form" label-width="80px" style="width:500px;"><el-form-item label="模型目录"><el-input v-model="form.trainId" disabled></el-input></el-form-item><el-form-item label="设备名称"><el-input v-model="form.deviceName" disabled></el-input></el-form-item><el-form-item label="图片"><el-uploadaction="#"list-type="picture-card":auto-upload="false":on-change="handleImgChange":file-list="fileList":limit="1":on-exceed="handleExceed"><i slot="default" class="el-icon-plus"></i><div slot="file" slot-scope="{file}"><imgclass="el-upload-list__item-thumbnail":src="file.url" alt=""><span class="el-upload-list__item-actions"><spanv-if="!disabled"class="el-upload-list__item-delete"@click="handleRemove(file)"><i class="el-icon-delete"></i></span></span></div></el-upload></el-form-item><el-form-item><el-button type="primary" @click="onSubmit" :loading = "loading">立即检测</el-button><el-button type="default" @click="reset">重置</el-button></el-form-item></el-form></div><!-- 结果显示区域 --><div class="title">图像检测结果</div><div class="imgContainer"><img :src="imgUrl" alt="" v-if="imgUrl" @load="imageLoad"><div class="mask" v-if="imgUrl"><div class="ltBox"  v-for="(item,idx) in imgData" :key="idx" :style="{left: Number(item.bbox[0])/ratio +'px', top: item.bbox[1]/ratio+'px', width: item.bbox[2]/ratio+'px', height: item.bbox[3]/ratio+'px' }"><span class="boxTitle">{{item.category_name}}</span></div></div></div></div>
</template><script>export default {name: "HomeView",data() {return {form: {trainId: 'model_39164_cpu', deviceName: 'cpu', pic01: {},},imgUrl: '', // 图片url,用于检测完显示用fileList: [], // 上传的图片列表disabled: false,imgData: [], // 图片标注数据ratio: 1, // 图片显示到框里时的缩放比值loading: false,};},mounted() {},methods: {handleImgChange(res, file) {this.fileList = file;// this.imgUrl = file[0].url;this.form.pic01 = file[0].raw;console.log(file);		},handleRemove(file) {this.fileList = [];// this.imgUrl = '';this.form.pic01 = {};this.imgUrl = '';this.imgData = [];},onSubmit(){		let _self = this;if (JSON.stringify(this.form.pic01) == "{}") {this.$message.error("请上传图片");return;}this.loading = true;let formData = new FormData();formData.append("trainId", this.form.trainId);formData.append("device_name", this.form.deviceName);formData.append("pic01", this.form.pic01);this.$axios({method: 'POST',url: '/api/prediction',data: formData,headers: {'Content-Type': 'multipart/form-data','charset': 'UTF-8'}}).then(function(res) {console.log(res);if (res.data.code === 200) {_self.loading = false;// 检测框显示图片_self.imgUrl = _self.fileList[0].url;// 获取标注数据let name = _self.fileList[0].name; // 键名为上传图片名称_self.imgData = res.data[name].result;} else {_self.$message({message: res.data.errorMsg,type: 'error',duration: 5 * 1000})}});},imageLoad() {console.log('图片加载完毕');// 计算检测框与实际图片大小的比值// this.imgUrl = file[0].url;let image = new Image();image.src = this.imgUrl;let imgWidth = image.width;if (imgWidth <= 1000) { // 框大于图片真实尺寸,不用缩放,按照正常偏移数据this.ratio = 1;} else { // 图片真实尺寸大于框宽度,算出缩放比例。模版里:正常偏移数据/缩放比例ratiothis.ratio = image.width / 1000;}console.log(image.width);},reset() {this.fileList = [];this.imgUrl = '';this.form.pic01 = {};this.imgData = [];},handleExceed(files, fileList) {this.$message.warning("只能选择一张图片");},}};
</script><style scope>.container{width: 1000px;box-sizing: border-box;margin: 80px auto;}.title{font-size: 16px;margin: 60px 0 20px;font-weight: bold;}.imgContainer{position: relative;/* box-sizing: border-box; */border: 1px dashed #000;width: 100%;min-height: 300px;}.imgContainer img{width: 100%;}.mask{width: 100%;height: 100%;position: absolute;top: 0;left: 0;    }.mask .ltBox{position: absolute;border: 1px solid red;/* width: 100px;height:100px;      left: 100px;top: 100px;      */}.mask .ltBox span{display: inline-block;font-size: 14px;padding-left: 2px;color: #fff;width: 16px;height: 20px;background: rgba(0,0,0,.4);}
</style>

返回数据格式为:

{"03.png":{"result":[{"angle":0,"bbox":[909.2269287109375,357.05908203125,86.85955810546875,130.1535034179688],"category_id":"0","category_name":"d","pointsArr":null,"res_num":36,"scores":0.9995452761650085,"type":"resultRect"},{"angle":0,"bbox":[909.5748901367188,190.1406097412109,86.5870361328125,132.7530364990234],"category_id":"0","category_name":"d","pointsArr":null,"res_num":36,"scores":0.9995043277740479,"type":"resultRect"},{"angle":0,"bbox":[427.7415161132813,599.2159423828125,108.297607421875,105.1603393554688],"category_id":"0","category_name":"d","pointsArr":null,"res_num":36,"scores":0.9994520545005798,"type":"resultRect"},{"angle":0,"bbox":[910.0458984375,46.47737503051758,86.25689697265625,130.2275543212891],"category_id":"0","category_name":"d","pointsArr":null,"res_num":36,"scores":0.9993937015533447,"type":"resultRect"},{"angle":0,"bbox":[427.6333923339844,863.2357177734375,108.3089904785156,99.88446044921875],"category_id":"0","category_name":"d","pointsArr":null,"res_num":36,"scores":0.9991784691810608,"type":"resultRect"},{"angle":0,"bbox":[790.2532958984375,191.2887725830078,93.9698486328125,129.5539703369141],"category_id":"0","category_name":"d","pointsArr":null,"res_num":36,"scores":0.9990857839584351,"type":"resultRect"},{"angle":0,"bbox":[544.385498046875,602.537841796875,98.578125,98.70477294921875],"category_id":"0","category_name":"d","pointsArr":null,"res_num":36,"scores":0.9990641474723816,"type":"resultRect"},{"angle":0,"bbox":[428.9845275878906,739.2496337890625,106.2877502441406,95.54400634765625],"category_id":"0","category_name":"d","pointsArr":null,"res_num":36,"scores":0.9990469813346863,"type":"resultRect"},{"angle":0,"bbox":[546.028076171875,739.0665893554688,97.27117919921875,96.72930908203125],"category_id":"0","category_name":"d","pointsArr":null,"res_num":36,"scores":0.9989651441574097,"type":"resultRect"},{"angle":0,"bbox":[549.2886352539063,866.919677734375,92.69256591796875,99.43603515625],"category_id":"0","category_name":"d","pointsArr":null,"res_num":36,"scores":0.9987188577651978,"type":"resultRect"},{"angle":0,"bbox":[791.1380004882813,48.05636215209961,95.0599365234375,126.0226898193359],"category_id":"0","category_name":"d","pointsArr":null,"res_num":36,"scores":0.9986415505409241,"type":"resultRect"},{"angle":0,"bbox":[791.9155883789063,358.5489501953125,91.2598876953125,125.5012512207031],"category_id":"0","category_name":"d","pointsArr":null,"res_num":36,"scores":0.9971223473548889,"type":"resultRect"},{"angle":0,"bbox":[425.3143310546875,47.26962661743164,109.3796997070313,127.9037933349609],"category_id":"1","category_name":"l","pointsArr":null,"res_num":36,"scores":0.9970883727073669,"type":"resultRect"},{"angle":0,"bbox":[911.8796997070313,736.1849365234375,83.3861083984375,104.4035034179688],"category_id":"1","category_name":"l","pointsArr":null,"res_num":36,"scores":0.9966270923614502,"type":"resultRect"},{"angle":0,"bbox":[330.7501220703125,600.6314086914063,74.79995727539063,102.3368530273438],"category_id":"0","category_name":"d","pointsArr":null,"res_num":36,"scores":0.9962628483772278,"type":"resultRect"},{"angle":0,"bbox":[911.684814453125,598.4668579101563,83.82977294921875,107.4171752929688],"category_id":"1","category_name":"l","pointsArr":null,"res_num":36,"scores":0.9958639144897461,"type":"resultRect"},{"angle":0,"bbox":[332.485107421875,738.0242309570313,73.73397827148438,98.7982177734375],"category_id":"0","category_name":"d","pointsArr":null,"res_num":36,"scores":0.9956913590431213,"type":"resultRect"},{"angle":0,"bbox":[678.7830200195313,192.1672668457031,88.1395263671875,131.537109375],"category_id":"0","category_name":"d","pointsArr":null,"res_num":36,"scores":0.995394229888916,"type":"resultRect"},{"angle":0,"bbox":[680.2387084960938,358.936767578125,86.17327880859375,126.4320983886719],"category_id":"0","category_name":"d","pointsArr":null,"res_num":36,"scores":0.9953811168670654,"type":"resultRect"},{"angle":0,"bbox":[427.2458190917969,356.8890380859375,105.9344787597656,126.5965881347656],"category_id":"1","category_name":"l","pointsArr":null,"res_num":36,"scores":0.9953643083572388,"type":"resultRect"},{"angle":0,"bbox":[426.9499206542969,193.8685760498047,107.8788757324219,123.8152008056641],"category_id":"1","category_name":"l","pointsArr":null,"res_num":36,"scores":0.9953345656394958,"type":"resultRect"},{"angle":0,"bbox":[911.595703125,862.9237060546875,84.64520263671875,108.9039916992188],"category_id":"1","category_name":"l","pointsArr":null,"res_num":36,"scores":0.9952036142349243,"type":"resultRect"},{"angle":0,"bbox":[792.5260009765625,859.0792236328125,93.56689453125,111.516845703125],"category_id":"1","category_name":"l","pointsArr":null,"res_num":36,"scores":0.9951752424240112,"type":"resultRect"},{"angle":0,"bbox":[542.8145751953125,44.25643539428711,97.0166015625,130.5228576660156],"category_id":"1","category_name":"l","pointsArr":null,"res_num":36,"scores":0.9950712919235229,"type":"resultRect"},{"angle":0,"bbox":[328.7076110839844,45.84556579589844,79.90731811523438,130.7186737060547],"category_id":"1","category_name":"l","pointsArr":null,"res_num":36,"scores":0.9948970675468445,"type":"resultRect"},{"angle":0,"bbox":[328.0628662109375,865.086181640625,80.9405517578125,99.62249755859375],"category_id":"0","category_name":"d","pointsArr":null,"res_num":36,"scores":0.9948451519012451,"type":"resultRect"},{"angle":0,"bbox":[329.5053405761719,356.4360046386719,77.6827392578125,129.4084167480469],"category_id":"1","category_name":"l","pointsArr":null,"res_num":36,"scores":0.9946455955505371,"type":"resultRect"},{"angle":0,"bbox":[329.6501770019531,192.0917816162109,79.248291015625,129.7602996826172],"category_id":"1","category_name":"l","pointsArr":null,"res_num":36,"scores":0.9944493770599365,"type":"resultRect"},{"angle":0,"bbox":[546.0228271484375,192.6796722412109,94.2720947265625,126.7196197509766],"category_id":"1","category_name":"l","pointsArr":null,"res_num":36,"scores":0.9937253594398499,"type":"resultRect"},{"angle":0,"bbox":[679.3350830078125,45.87873077392578,86.26666259765625,129.9478454589844],"category_id":"0","category_name":"d","pointsArr":null,"res_num":36,"scores":0.9934400916099548,"type":"resultRect"},{"angle":0,"bbox":[794.0667114257813,736.28662109375,92.5123291015625,106.004150390625],"category_id":"1","category_name":"l","pointsArr":null,"res_num":36,"scores":0.9919258952140808,"type":"resultRect"},{"angle":0,"bbox":[544.1696166992188,356.3648986816406,96.20233154296875,126.95068359375],"category_id":"1","category_name":"l","pointsArr":null,"res_num":36,"scores":0.9917498230934143,"type":"resultRect"},{"angle":0,"bbox":[678.4888305664063,863.577392578125,92.967529296875,106.4488525390625],"category_id":"1","category_name":"l","pointsArr":null,"res_num":36,"scores":0.9908513426780701,"type":"resultRect"},{"angle":0,"bbox":[681.7239379882813,736.389404296875,87.13897705078125,107.5022583007813],"category_id":"1","category_name":"l","pointsArr":null,"res_num":36,"scores":0.9900141954421997,"type":"resultRect"},{"angle":0,"bbox":[679.4708251953125,599.4293212890625,90.96051025390625,106.7920532226563],"category_id":"1","category_name":"l","pointsArr":null,"res_num":36,"scores":0.9883459210395813,"type":"resultRect"},{"angle":0,"bbox":[793.232177734375,599.1714477539063,93.35357666015625,106.982421875],"category_id":"1","category_name":"l","pointsArr":null,"res_num":36,"scores":0.986026406288147,"type":"resultRect"}]},"code":200,"errorCode":0,"errorMsg":"ok"}

需要注意的是:

1、上传图片时候,后台需要formData格式。

打印upload插件的file参数,

 	 handleImgChange(res, file) {this.fileList = file;this.form.pic01 = file[0].raw;console.log(file);		},

结果为:在这里插入图片描述

这里需要把’raw’拿出来,放到formData里面,传给后台。有其他参数,一并传送。例如:

	let formData = new FormData();formData.append("trainId", this.form.trainId);formData.append("device_name", this.form.deviceName);formData.append("pic01", file.raw);

2、监听图片加载完成事件,获取图片真实宽高。

由于我们需要在一个固定宽度的区域中显示图片(图片宽度充满区域,也就是说宽度为区域的百分之百)并框选标注,涉及到选框的偏移位置信息,所以必须拿到图片的真实宽度,算出比值,再进行偏移量的计算。

模版字符串里面:

<img :src="imgUrl" alt="" @load="imageLoad">

js里面:

	imageLoad() {console.log('图片加载完毕');let image = new Image();image.src = this.imgUrl;let imgWidth = image.width;if (imgWidth <= 1000) { // 框大于图片真实尺寸,不用缩放,按照正常偏移数据this.ratio = 1;} else { // 图片真实尺寸大于框宽度,算出缩放比例。模版里:正常偏移数据/缩放比例ratiothis.ratio = image.width / 1000;}console.log(image.width);},

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

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

相关文章

Java - 探究Java优雅退出的两种机制

文章目录 概述Java优雅停机_ ShutdownHook 机制步骤Code Java优雅停机_ 信号量机制SignalHandler 工作原理使用步骤Linux支持的信号量根据操作系统选择信号量Code 注意事项 概述 在Linux上通过kill -9 pid方式强制终止进程的副作用&#xff0c;这种方式虽然简单高效&#xff0…

小红书素人投放计划怎么做?

小红书素人投放是很多品牌在小红书推广打响的第一枪&#xff0c;素人铺量在小红书投放&#xff0c;可以奠定品牌在小红书的声量&#xff0c;小红书素人投放计划怎么做&#xff1f;前期规划好一切&#xff0c;才能在后期让我们的推广爆发出更好的效果。接下来伯乐网络传媒就来给…

【压缩包技巧】如何把rar文件压缩为zip格式?

想要将rar文件压缩为zip格式&#xff0c;其实就是压缩包格式进行转换&#xff0c;今天和大家分享三个rar压缩包改成zip格式的方法&#xff0c;希望能够帮助到大家&#xff01; 方法一&#xff1a; 直接修改rar压缩包的后缀名变为zip&#xff0c;就可以修改压缩包文件格式了 …

揭秘Google Gemini:AI界的多模态革命者与ChatGPT-4的较量

在人工智能的快速发展浪潮中&#xff0c;Google DeepMind的最新力作——Gemini&#xff0c;以其多模态的超凡能力&#xff0c;正引领着AI技术的新一轮革命。本文将深入探讨Gemini的核心特性、不同版本的特点&#xff0c;以及它与ChatGPT-4的对比优势和差异。 一、Gemini简介 A…

float32 float16 bfloat16 推理训练GPU速度和内存调研

概念&#xff1a; 参考&#xff1a;Accelerating Large Language Models with Mixed-Precision Techniques - Lightning AI 3种数量类型表示的数据范围不一样&#xff0c;以float32为例其中有1个符号位&#xff0c;8位表示指数&#xff0c;23位表示尾数 标准训练推理是用的fl…

eclipse maven 项目导入报错

错误&#xff1a;Internal compiler error: java.lang.NullPointerException at org.eclipse.jdt.internal.compiler.apt.dispatch.AnnotationDiscoveryVisitor 环境&#xff1a;eclipse Kepler Service Release 2 ,JDK1.7 解决办法&#xff1a;编码不对&#xff0c;修改

指令调用模板

也就是这边指令通过id和map会定位到一个结构体&#xff0c;然后这个结构再赋值两个成员&#xff0c;一个是函数一个是指令类型&#xff0c;然后这个函数是模板的实例化 使用的时候就传进去&#xff0c;这只是参数&#xff0c;最开始初始化的时候模板就已经实例化了。然后关于模…

为什么美国硅谷作为服务器托管的首选地?

在数字化时代&#xff0c;服务器托管已成为企业运营不可或缺的一部分。而美国硅谷作为全球科技创新的摇篮&#xff0c;其服务器托管服务备受全球企业青睐。那么&#xff0c;为什么众多企业选择美国硅谷作为服务器托管的首选地呢? 硅谷拥有得天独厚的地理位置和网络基础设施。硅…

[HackMyVM]Quick 2

kali:192.168.56.104 主机发现 arp-scan -l # arp-scan -l Interface: eth0, type: EN10MB, MAC: 00:0c:29:d2:e0:49, IPv4: 192.168.56.104 Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan) 192.168.56.1 0a:00:27:00:00:05 (Un…

若依框架的使用

文章目录 1,前端2,后端3,数据库4,测试 1,前端 2,后端 3,数据库 4,测试

Vision Transformers的注意力层概念解释和代码实现

2017年推出《Attention is All You Need》以来&#xff0c;transformers 已经成为自然语言处理(NLP)的最新技术。2021年&#xff0c;《An Image is Worth 16x16 Words》&#xff0c;成功地将transformers 用于计算机视觉任务。从那时起&#xff0c;许多基于transformers的计算机…

刘敏:楼氏动铁和麦克风助力听力健康技术发展 | 演讲嘉宾公布

一、助辅听器材Ⅱ专题论坛 助辅听器材Ⅱ专题论坛将于3月28日同期举办&#xff01; 听力贯穿人的一生&#xff0c;听觉在生命的各个阶段都是至关重要的功能&#xff0c;听力问题一旦出现&#xff0c;会严重影响生活质量。助辅听器材能有效提高生活品质。在这里&#xff0c;我们将…

Redis哨兵模式(Sentinel)的搭建与配置

创建三个Redis实例所需的目录,生产环境需独立部署在不同主机上,提高稳定性。 Redis 哨兵模式(Sentinel)是一个自动监控处理 redis 间故障节点转移工作的一个redis服务端实例,它不提供数据存储服务,只进行普通 redis 节点监控管理,使用redis哨兵模式可以实现redis服务端故…

八、软考-系统架构设计师笔记-系统质量属性和架构评估

1、软件系统质量属性 软件架构的定义 软件架构是指在一定的设计原则基础上&#xff0c;从不同角度对组成系统的各部分进行搭配和安排&#xff0c;形成系统的多个结构而组成架构&#xff0c;它包括该系统的各个构件&#xff0c;构件的外部可见属性及构件之间的相互关系。 软件架…

STM32串口:DMA空闲中断实现接收不定长数据(基于HAL库)

STM32串口&#xff1a;DMA空闲中断实现接收不定长数据&#xff08;基于HAL库&#xff09;&#xff1a; 第一步&#xff1a;设置rcc&#xff0c;时钟频率&#xff0c;下载方式 设置system core->RCC如图所示&#xff1a;&#xff08;即High Speed Clock和Low Speed Clock都选…

ansible基础与基础命令模块

一Ansible 1. ansible 的概念 Ansible是一个基于Python开发的配置管理和应用部署工具&#xff0c;现在也在自动化管理领域大放异彩。它融合了众多老牌运维工具的优点&#xff0c;Pubbet和Saltstack能实现的功能&#xff0c;Ansible基本上都可以实现。 Ansible能批量配置、部署、…

手机群控软件开发必备源代码分享!

随着移动互联网的飞速发展&#xff0c;手机群控技术在市场推广、自动化测试、应用管理等领域的应用越来越广泛&#xff0c;手机群控软件作为一种能够同时控制多台手机设备的工具&#xff0c;其开发过程中&#xff0c;源代码的编写显得尤为重要。 1、设备连接与识别模块 设备连…

java Day7 正则表达式|异常

文章目录 1、正则表达式1.1 常用1.2 字符串匹配&#xff0c;提取&#xff0c;分割 2、异常2.1 运行时异常2.2 编译时异常2.3 自定义异常2.3.1 自定义编译时异常2.3.2 自定义运行时异常 1、正则表达式 就是由一些特定的字符组成&#xff0c;完成一个特定的规则 可以用来校验数据…

AHU 汇编 实验二

一、实验名称&#xff1a;实验二 不同寻址方式的灵活运用 二、实验内容&#xff1a;定义数组a[6]&#xff0c;用多种寻址方式访问对应元素&#xff0c;实现&#xff08;a[0]a[1]&#xff09;*(a[2]-a[3])/a[4],将结果保存在内存a[5]中&#xff0c;用debug查询结果。 实验过程&a…

压缩自定义格式压缩包<2>:python使用DEFLATE 算法打包并解压成功,但是解压后的文件格式是固定后缀。

打包 import zlib import osdef compress_folder(input_folder, output_filename):"""使用 DEFLATE 算法压缩文件夹下的所有文件。Parameters:input_folder: str要压缩的文件夹路径。output_filename: str输出压缩文件名。"""# 创建一个空的字节…