武汉建站网站/个人网站源码免费下载
声明:我学习了b站:标注自己的语义分割数据集_哔哩哔哩_bilibili
并且复现了,记录了所思所得。
主要是说了:
做语义分割,数据集怎么用labelme标注成json文件,以及,json文件怎么转成mask
流程:
准备图片-用labelme标注-得到标注的json文件-把json文件转成mask文件
然后,先看看,单张图片,是怎么依次做到上面的事情的。
首先,知道一些基本的:
1、标注前:
工具:labelme
labelme软件配置
2、标注中
标注单张图像(现在做这个)
使用“分割一切”SAM视觉大模型辅助标注
标注多张图像
标注注意事项
3、标注后
划分训练集和测试集
讲labelme的json标注格式,转换为整数掩膜mask格式
下载西瓜语义分割样例数据集
下载labelme
下载labelme
https://github.com/labelmeai/labelme/releases?after=v3.22.1
注意:
文件-取消-同时保存图像(不然很大占用内存)
文件-勾选-自动保存
开始标注
labelme:编辑-创建多边形-开始描狗
label标注文件:json格式
存储的格式是右边的json格式,这就是刚刚画的labelme格式的标注文件
labelme格式标注文件,json文件,存放了什么?
这个shapes很重要,里面有我们自己画的标签的类别,比如“chaiquan1”和我们当时画标签的时候,描的每一个点。
json十分轻量化,9kb就能保存标注了
如果在单张图片上绘制了好几个物体,最后的标注都会汇集在一个json文件上
比如,第一个是“chaiquan”标签的信息;那第二个就是“zhangpeng”的标签信息;以此类推,一张图片上,你打了几个标签,就会在json文件里出现几个标签的信息
除了自己描,还能用AI辅助标注,但是我打开会闪退,这个问题待解决。
另外注意:标注过程中,不要切换目录;
要确认,json文件最后,imagePath的图像路径,只能是图像名字本身,不能有其他的路径和符号。
标注转换(手打json标签文件到mask掩码文件)
现在,labelme格式的标签文件,我们就做好了,但是labelme的json格式的文件,并不能够,直接用于,语义分割的模型训练,所以,我们要把json文件,转换为整数掩膜mask格式,在像素层面上做类别标注,并且划分成训练集和测试集,并且用于后续的训练。
语义分割的本质,就是给每个像素做分类,所以,语义分割的标注,就是给每个像素打上类别标签,这种格式,叫做整数掩膜格式,因为能够严丝合缝的盖在原来的图上,所以,叫做掩码:
使用代码将labelme的标注文件转换成掩码
链接:常见计算机视觉标注格式相互转换
https://github.com/TommyZihao/Label2Everything
【labelme转mask-单张图像】
为了好展示图像,直接在jupyter notebook上面运行,我的jupyter notebook安装在conda下的yes虚拟环境,cmd激活进入环境,但是py38_pytorch虚拟环境也是和yes环境共同用的jupyter notebook,所以,从cmd进入yes激活jupyternotebook后,进入py38_pytorch虚拟环境就行了;或者在云服务器处理也行。
先查下自己所在的工作路径,当然,在哪里也不影响对图片的读取
1、导入包
import os
import json
import numpy as np
import cv2
import matplotlib.pyplot as plt
%matplotlib inline
2、读取图片
注意:我在这一直报错,搞了半天,原因是,我用了中文路径,换了个英文就好了。。。。,是所以,以后都用英文路径吧
重新来:
img_path = 'E:/gettyimages.jpg'
img_bgr = cv2.imread(img_path)
img_bgr.shape
plt.imshow(img_bgr[:,:,::-1])
plt.show()
【为什么要plt.imshow(img_bgr[:,:,::-1])】
是为了让opencv和matplot适应,因为我们在jupyternotebook上,最开始用了%matplotlib,让他直接显示图片。
`plt.imshow(img_bgr[:,:,::-1])` 的部分是为了在matplotlib中正确显示通过OpenCV读取的图像。
- `plt.imshow()`: 这是matplotlib库中的函数,用于显示图像数据。
- `img_bgr[:,:,::-1]`: 这是numpy数组切片的用法,用于改变图像数组的通道顺序。让我们逐部分解析:
- 第一个和第二个冒号(`:`): 这两个冒号意味着选取图像的所有行和列,即不改变图像的高度和宽度。
- 第三个部分(`::-1`): 这里的`-1`是步长参数,它指示从结尾开始向前选取元素,即反转选取的元素。在这个上下文中,它被应用于通道轴,意味着通道的顺序将会被反转。
由于OpenCV读取图像时默认采用BGR(蓝色、绿色、红色)的通道顺序,而matplotlib期望的图像格式是RGB(红色、绿色、蓝色)。因此,通过`[:,:,::-1]`,你实际上是在对图像的通道轴进行反转,将BGR顺序转换为RGB顺序,这样图像在matplotlib中显示时颜色就会正确无误。
总结来说,`img_bgr[:,:,::-1]`这一操作是为了适配OpenCV和matplotlib之间不同的颜色通道顺序,确保图像能够以正确的颜色显示在matplotlib的画布上。
3、创建一个和原图大小一样,的背景图
注意,是和原图一模一样大!
img_mask = np.zeros(img_bgr.shape[:2])
img_mask
plt.imshow(img_mask)
plt.show()
【img_mask = np.zeros(img_bgr.shape[:2])】
这段代码创建了一个与`img_bgr`图像具有相同宽度和高度的二维numpy数组`img_mask`,并且这个数组的所有元素都被初始化为0。这里是逐步解析:
- `img_bgr.shape[:2]`:这里,`img_bgr.shape`返回一个包含图像尺寸的元组,通常是`(高度, 宽度, 通道数)`。使用切片操作`[:2]`选取前两个元素,即图像的高度和宽度,忽略通道数信息。这是因为掩码通常是对每个像素的位置进行标记,不需要颜色通道信息,所以是一个二维数组。
- `np.zeros(...)`:这个numpy函数用于创建一个指定形状的新数组,并将所有元素初始化为0。传入的参数是`(高度, 宽度)`,因此生成的数组尺寸与原图像的尺寸在宽度和高度上相匹配,但它是单通道的(灰度),每个元素都是0,代表一个全黑的“掩模”图像。
简而言之,`img_mask`是一个与`img_bgr`图像空间尺寸相同的全零数组,常用于后续的图像处理作为掩模,比如在图像分割、对象检测或特定区域的标记等场景中。
4、载入该图片labelme格式的json标注文件
labelme_json_path = 'E:\dog\gettyimages.json'
with open(labelme_json_path,'r',encoding='utf-8') as f:
labelme = json.load(f)
labelme.keys()
【with open(labelme_json_path,'r',encoding='utf-8') as f:
labelme = json.load(f)】
这段代码是用来读取并加载一个使用JSON格式存储的LabelMe标注文件的。以下是代码的逐行解释:
- `with open(labelme_json_path, 'r', encoding='utf-8') as f:`:这一行使用了Python中的`with`语句来打开一个文件。`labelme_json_path`是你要读取的LabelMe JSON文件的路径。文件被以只读模式(`'r'`)打开,并且指定了字符编码为`'utf-8'`来正确处理可能包含的非ASCII字符。`as f`部分创建了一个名为`f`的文件对象,让你能够读取文件内容。使用`with`语句的好处在于它能确保文件在操作完成后会被正确关闭,即使发生了异常也是如此。
- `labelme = json.load(f)`: 这一行使用了Python的内置`json`模块来从已经打开的文件对象`f`中读取数据,并将其解析为Python的数据结构(通常是字典或列表)。这意味着如果LabelMe的JSON文件中包含图像的标签、边界框、多边形等标注信息,这些信息会被转换成Python的数据类型,存储在变量`labelme`中,供后续的程序逻辑使用。
综上所述,这段代码的作用是从指定路径的LabelMe JSON文件中读取图像标注数据,并将其内容以Python数据结构的形式保存在变量`labelme`里,以便进一步处理或分析这些标注信息。
5、解析labelme的元数据
6、打印该图片中的所有标注信息
把labelme的每一个shape拿出来,打印每一个标签名字和画的类别(用什么线画的)
因为在前面,with open(labelme_json_path,'r',encoding='utf-8') as f:
labelme = json.load(f)
我们定义了,labelme是我们标注的json文件,然后这个labelme json文件里,包含了我们标注地所有信息,其中,比较重要的,就是,储存在里面的label标签信息和画这个标签时候我们用的什么线条,是多线段,还是圆圈,还是两点线段什么的
7、开始做绘制每个类别mask的准备
每个类别的信息,然后画mask的顺序是:(画的时候按照由大到小,由粗到精的顺序),比如,从大的天空到中等的建筑,再到小的人;颗粒度也是从粗到精;
# 0-背景,从1开始
class_info = [
{'label':'zhangpeng','type':'line','color':1,'thickness':5} ,# line 两点线段,填充线宽
{'label':'chaiquan','type':'polygon','color':2},
{'label':'line','type':'polygon','color':3}
]
因为当时,画的时候,我标注了3个标签,一个是柴犬,一个是帐篷,一个是一条线;那按照从大到小的顺序,就是先把,帐篷,柴犬,线,这三个,按照顺序,列出来,在这里,要给出label的名字,画label的线条类别,以及颜色,还有宽度等等。。。
顺序摆好以后,开始画mask
8、按顺序把mask绘制在空白图上
for one_class in class_info: # 按顺序遍历每一个类别
for each in labelme['shapes']: # 遍历所有标注,找到属于当前类别的标注
if each['label'] == one_class['label']:
if one_class['type'] == 'polygon': # polygon 多段线标注
# 获取点的坐标
points = [np.array(each['points'], dtype=np.int32).reshape((-1, 1, 2))]
# 在空白图上画 mask(闭合区域)
img_mask = cv2.fillPoly(img_mask, points, color=one_class['color'])
elif one_class['type'] == 'line' or one_class['type'] == 'linestrip': # line 或者 linestrip 线段标注
# 获取点的坐标
points = [np.array(each['points'], dtype=np.int32).reshape((-1, 1, 2))]
# 在空白图上画 mask(非闭合区域)
img_mask = cv2.polylines(img_mask, points, isClosed=False, color=one_class['color'], thickness=one_class['thickness'])
elif one_class['type'] == 'circle': # circle 圆形标注
points = np.array(each['points'], dtype=np.int32)
center_x, center_y = points[0][0], points[0][1] # 圆心点坐标
edge_x, edge_y = points[1][0], points[1][1] # 圆周点坐标
radius = np.linalg.norm(np.array([center_x, center_y] - np.array([edge_x, edge_y]))).astype('uint32') # 半径
img_mask = cv2.circle(img_mask, (center_x, center_y), radius, one_class['color'], one_class['thickness'])
else:
print('未知标注类型', one_class['type'])
plt.imshow(img_mask)
plt.show()
9、把刚刚画的mask保存下来
保存的mask必须是png格式
img_mask.shape # 可以看到mask和原图一样大
# img_path = 'E:/dog/gettyimages.jpg'
mask_path = img_path.split('.')[0]+'.png'
cv2.imwrite(mask_path,img_mask)
然后这时候,看到,原来放原图和标注label的json文件,还有刚刚生成的mask文件,都在一个文件夹下面,但是,如果直接打开是黑色的,因为,1,2,3,4这种像素在0-255里面是很小的像素,直接打开图片只会是黑色的。
所以,用cv2.imread载入图像
10、正确的载入和显示mask图像
mask_img = cv2.imread('E:/dog/gettyimages.png')
mask_img.shape
np.unique(mask_img) # 可以看到,一共是四个类别
plt.imshow(mask_img[:,:,0]) # 取单通道展示出来 ,所以最后是取0(取1,2也是一样的)
plt.show()
完整代码
http://localhost:8888/doc/tree/%E5%8D%95%E5%BC%A0%E5%9B%BE%E7%89%87label%E8%BD%ACmask.ipynb
相关文章:

【语义分割】1-标注数据集-【单张图片】labelme标注json文件转mask
声明:我学习了b站:标注自己的语义分割数据集_哔哩哔哩_bilibili 并且复现了,记录了所思所得。 主要是说了: 做语义分割,数据集怎么用labelme标注成json文件,以及,json文件怎么转成mask 流程…...

c++: 理解编译器在背后所做的工作-工具篇
理解C模板以及编译器的优化是深入掌握C编程的重要部分。有一些其他工具和技术可以帮助你更好地理解编译器在背后所做的工作,特别是优化方面。以下是一些有用的工具和技术: 1. Compiler Explorer (Godbolt) Compiler Explorer 是一个非常流行的在线工具…...

Verilog HDL语法入门系列(三):Verilog的语言操作符规则(上)
目录 1.操作符优先级2.Verilog中的大小(size)与符号3.算术操作符4.按位操作符5.逻辑操作符6.逻辑反与位反的对比 微信公众号获取更多FPGA相关源码: 1.操作符优先级 下表以优先级顺序列出了Verilog操作符。 2.Verilog中的大小(size)与符号 Verilog根据表达式中变…...

IT营大地老师是谁,怎么什么都会?
很多学员都很好奇大地老师到底是谁,怎么什么都会?每过一段时间就会出一门新课程,涉足深耕不同的领域。经反馈常有童鞋私聊IT营官网客服咨询这个问题,也有很多人在b站大地老师的免费课程里私信,有好奇也有崇拜ÿ…...

【python013】pyinstaller打包PDF提取脚本为exe工具
1.在日常工作和学习中,遇到类似问题处理场景,如pdf文件核心内容截取,这里将文件打包成exe可执行文件,实现功能简便使用。 2.欢迎点赞、关注、批评、指正,互三走起来,小手动起来! 3.欢迎点赞、关…...

VUE div的右上角的角标/标签
一、效果图 二、代码 <div class"comp-overview"><div class"overview-item" v-for"(item,index) in overviewInfoList" :key"index"><div class"angle_mark"><span>{{item.label}}</span>&…...

WPS复制后转置粘贴
1. WPS复制后转置粘贴 复制-》右键-》顶部第一行-》粘贴行列转置,如下图: 2. Excel office365 本地版 2. Excel office365 在线版...

Shell编程之正则表达式与文本处理器
一,正则表达式 1:正则表达式概述 1.正则表达式的定义 正则表达式(Regular Expression,RegEx)是一种高度灵活的文本处理工具,它结合了字符序列、特殊控制字符(称为元字符)、以及特定…...

linux文本粘贴格式错乱的问题
vi/vim :set paste然后再 insert, 粘贴...

第二节课 6月13日 ssh密钥登陆方式
centos和ubuntu openssh服务的初始安装 一、实验:ubuntu系统激活root用户 ubuntu系统如何激活root用户,允许root用户ssh登陆? 1、ubuntu默认root用户未设置密码,未激活 激活root用户,设置root密码 sudo passwd roo…...

图书馆借阅表
DDL 用户表 (Users) 图书表 (Books) 图书类别表 (BookCategories) 图书与类别关联表 (BookCategoryRelations) 借阅记录表 (BorrowRecords) 供应商表 (Suppliers) 采购记录表 (PurchaseRecords) CREATE TABLE Users (user_id INT PRIMARY KEY AUTO_INCREMENT,username …...

云动态摘要 2024-06-25
给您带来云厂商的最新动态,最新产品资讯和最新优惠更新。 最新产品更新 Web应用防火墙 - 验证码支持微信小程序接入 阿里云 2024-06-25 支持客户从微信小程序场景下接入,提供人机识别的安全防护。 工业数字模型驱动引擎 - iDME控制台换新升级 华为云…...

Docker编译nanopc-t4源码流程介绍
官方文档 Android系统编译 vnc加环境变量配置 https://github.com/friendlyarm/docker-cross-compiler-novnc 下载 git clone https://github.com/friendlyarm/docker-ubuntu-lxde-novnc cd docker-ubuntu-lxde-novnc docker build --no-cache -t docker-ubuntu-lxde-novnc …...

Redis八股文目录
Redis缓存穿透-CSDN博客 Redis缓存击穿-CSDN博客 Redis缓存雪崩(主从复制、哨兵模式(脑裂)、分片集群)-CSDN博客 Redis双写一致性-CSDN博客 Redis持久化-CSDN博客 Redis数据过期、淘汰策略-CSDN博客 分布式锁(Re…...

Ext JS+Spring Boot 使用Ajax方式上传文件
实现方式 使用 Ext JS 进行 AJAX 调用以传递文件通常涉及到创建一个 FormData 对象,将文件附加到这个对象中,然后通过 Ext JS 的 AJAX API 发送这个对象。 基本步骤 以下是使用 Ext JS 发送文件的基本步骤: 准备文件和数据: 首先需要获取到要传递的文件 创建 FormData 对…...

windows桌面运维----第九天
1、新的电脑需要安装哪些驱动: 显卡驱动、声卡驱动、主板驱动、网卡驱动、打印机驱动、外设驱动、 2、网络打印机如何开启打印机共享核客户端连接共享打印机: 一、打开控制面板并定位到设备和打印机: 首先,我们在电脑桌面上找…...

【Docker】安装和加速
目录 1.安装 2.了解 docker 信息 3.查询状态 4. 重新启动Docker 1.安装 yum install –y docker 2.了解 docker 信息 cat /etc/redhat-release 3.查询状态 systemctl status docker 4.支持 1.12 的 docker 镜像加速 sudo mkdir -p /etc/docker sudo tee /etc/docke…...

如何关闭win10音量调节时 左上角出现的黑框
目录 1.谷歌浏览器: 2.edge浏览器: 3.没得办法的办法: 4.官方回复: 1.谷歌浏览器: 把这行地址chrome://flags/#hardware-media-key-handling 输入到chrome的地址栏里,回车,把黄色里的Hardwa…...

准确率(accuracy)、召回率(recall)的意义和区别
准确率(accuracy)、召回率(recall)的意义和区别 对于准确率和召回率:一句话,准确率就是“找的对”,召回率就是“找的全” (精确率:正样本中找对的准确率) 注…...

分享5个卫星影像查看网站
我们在《分享5个图源二维码及使用方法》一文中,为你分享了5个图源二维码。 现在再为你为分享5种在线卫星影像,如果你需要更多的图源二维码,请在文末查看领取方式。 MapBox卫星影像 可能很多人都知道MapBox的地名路网地图,但可能…...

37岁,被裁员,失业三个月,被面试官嫌弃“太水”:就这也叫10年以上工作经验?
今年部门要招两个自动化测试,这几个月我面试了几十位候选人。发现一个很奇怪的现象,面试中一问到元素定位、框架api、脚本编写之类的,很多候选人都对答如流。但是一问到实际项目,比如“项目中UI自动化和接口自动化如何搭配使用&am…...

如何选择一款优质的酱香酒?
很多人在评价一款酒的好坏时,往往只关注一个标准:口感是否顺滑。然而,真正品鉴一款酒的品质,首要的是香味,其次是味道,最后才是岁月带来的柔和。这种由岁月赋予的柔和,才能展现出酒的力量感和层…...

SQL Server数据库安装
原文:https://blog.c12th.cn/archives/26.html SQL Server数据库安装 测试:笔记本原装操作系统:Windows 10 家庭中文版 资源分享链接:提取码:qbt2 注意事项: 请严格按照步骤安装,SQL软件安装较…...

Hadoop 面试题(十)
1. 简述下列关于Hadoop命令中,命令执行成功返回0,执行失败返回-1,下列命令返回-1的是 ? A:hadoop fs -mv /user/hadoop/file1 /user/hadoop/file2 B:hdfs dfs -mv hdfs:///testData file:///tmp/testData …...

Python网络安全项目开发实战,如何看清Web攻击
注意:本文的下载教程,与以下文章的思路有相同点,也有不同点,最终目标只是让读者从多维度去熟练掌握本知识点。 下载教程: Python网络安全项目开发实战_看清Web攻击_编程案例解析实例详解课程教程.pdf 一、引言 在网络安全领域,Web攻击一直是一个严峻的问题。攻击者通过各…...

持续总结中!2024年面试必问的操作系统面试题(三)
上一篇地址:持续总结中!2024年面试必问的操作系统面试题(二)-CSDN博客 五、什么是分页和分段?它们之间有什么区别? 分页和分段是操作系统中用于内存管理的两种不同技术,它们都旨在允许操作系统…...

请说明Thread类中run和start的区别,从方法的区别,及运行结果的区别分别说明
方法本身的区别 start() 方法: run()方法是Thread类的一个普通方法,它包含了线程要执行的代码。当你直接调用一个线程的run()方法(如myThread.run()),你实际上是在当前线程(通常是主线程)中执行…...

MySQL:概念、逻辑与物理结构设计详解
MySQL:概念、逻辑与物理结构设计详解 一、引言 MySQL是一个流行的开源关系型数据库管理系统(RDBMS),广泛应用于各种规模和类型的应用程序中。在设计和实现一个MySQL数据库时,理解其基本概念、逻辑结构设计和物理结构…...

《昇思 25 天学习打卡营第 6 天 | 函数式自动微分 》
《昇思 25 天学习打卡营第 6 天 | 函数式自动微分 》 活动地址:https://xihe.mindspore.cn/events/mindspore-training-camp 签名:Sam9029 函数式自动微分 自动微分是深度学习中的一个核心概念,它允许我们自动计算模型参数的梯度,…...

刷题——二叉树的中序遍历
双指针法 void midorder(vector<int>&res, TreeNode* root){if(root NULL) return;midorder(res, root->left);res.push_back(root->val);midorder(res, root->right);}vector<int> inorderTraversal(TreeNode* root) {// write code herevector<…...