分享一下从原始图片,到标记图片,再到转换为python里的数据结构语义分割数据集制作全流程。

安装labelme

labelme 是一个图形界面的图像标注软件,可以很方便地划分出多边形边界。

下面在win10系统中使用anaconda安装labelme

// python3
conda create --name=labelme python=3.6
activate labelme
pip install labelme

anaconda会自动安装好labelme及其依赖包
通过conda list命令查看安装好的包:

在每次打开prompt或cmd激活labelme虚拟环境后,输入labelme即可打开labelme

标注图片

打开labelme,在labelme中打开文件夹,在Edit中选择create polygons即可添加多边形标记框,标记完后输入标签名即可完成一片区域的标记。标记完成后保存为json文件

json文件转为数据集

labelme标签不一致问题

labelme库原有的labelme_json_to_dataset.py脚本可以将json文件转换为原图(img)、掩码(mask)、原图和掩码的叠加(viz)和一个标签文件(txt)。默认情况下,导出掩码的像素值和在标注时标记的顺序有关,而不是和标签名对应。
这里参考了https://zhuanlan.zhihu.com/p/159837405的方法对labelme的 _json_to_dataset.py代码进行更改,使label可以自行配置,同时保证了标签的统一。
首先使用everything找到虚拟环境中labelme库的labelme_json_to_dataset.py文件

注释掉部分源代码,加上自己的标签名称和对应编号(0,1,2,…),保存即可

import argparse
import base64
import json
import os
import os.path as ospimport imgviz
import PIL.Imagefrom labelme.logger import logger
from labelme import utilsdef main():logger.warning("This script is aimed to demonstrate how to convert the ""JSON file to a single image dataset.")logger.warning("It won't handle multiple JSON files to generate a ""real-use dataset.")parser = argparse.ArgumentParser()parser.add_argument("json_file")parser.add_argument("-o", "--out", default=None)args = parser.parse_args()json_file = args.json_fileif args.out is None:out_dir = osp.basename(json_file).replace(".", "_")out_dir = osp.join(osp.dirname(json_file), out_dir)else:out_dir = args.outif not osp.exists(out_dir):os.mkdir(out_dir)data = json.load(open(json_file))imageData = data.get("imageData")if not imageData:imagePath = os.path.join(os.path.dirname(json_file), data["imagePath"])with open(imagePath, "rb") as f:imageData = f.read()imageData = base64.b64encode(imageData).decode("utf-8")img = utils.img_b64_to_arr(imageData)# ##########################    开始修改    ######################### label_name_to_value = {"_background_": 0}# for shape in sorted(data["shapes"], key=lambda x: x["label"]):#     label_name = shape["label"]#     if label_name in label_name_to_value:#         label_value = label_name_to_value[label_name]#     else:#         label_value = len(label_name_to_value)#         label_name_to_value[label_name] = label_value# lbl, _ = utils.shapes_to_label(#     img.shape, data["shapes"], label_name_to_value# )# label_names = [None] * (max(label_name_to_value.values()) + 1)# for name, value in label_name_to_value.items():#     label_names[value] = namelabel_name_to_value={'_background_': 0, 'E': 1, 'Esl': 2, 'Esc': 3, 'F1':4, 'F2':5, 'Fspread':6}lbl, _ = utils.shapes_to_label(img.shape, data["shapes"], label_name_to_value)label_names=['_background_', 'E', 'Esl', 'Esc','F1', 'F2', 'Fspread']# ###########################   结束修改    #############################lbl_viz = imgviz.label2rgb(label=lbl, img=imgviz.asgray(img), label_names=label_names, loc="rb")PIL.Image.fromarray(img).save(osp.join(out_dir, "img.png"))utils.lblsave(osp.join(out_dir, "label.png"), lbl)PIL.Image.fromarray(lbl_viz).save(osp.join(out_dir, "label_viz.png"))with open(osp.join(out_dir, "label_names.txt"), "w") as f:for lbl_name in label_names:f.write(lbl_name + "\n")logger.info("Saved to: {}".format(out_dir))if __name__ == "__main__":main()

批量转换json文件

labelme库原有的labelme_json_to_dataset脚本一次只能转换一个json文件在此参考博主里先森的文章批量转换labelme标注json数据为图片,并将不同类型的图片分文件夹存储。

https://blog.csdn.net/sements/article/details/110135137

创建文件trans.py

# 调用labelme库中原有的 labelme_json_to_dataset 为核心
# 批量将文件夹中的json文件转换,并抽取对应图片至各自文件夹
# python trans.py -i ./ -r img -m mask -v viz
import os
import shutil
import argparsedef GetArgs():parser = argparse.ArgumentParser(description='将labelme标注后的json文件批量转换为图片')parser.add_argument('--input', '-i', required=True, help='json文件目录')parser.add_argument('--out-mask', '-m', required=True, help='mask图存储目录')parser.add_argument('--out-img', '-r', help='json文件中提取出的原图存储目录')parser.add_argument('--out-viz', '-v', help='mask与原图合并viz图存储目录')return parser.parse_args()if __name__ == '__main__':_args = GetArgs()_jsonFolder = _args.inputinput_files = os.listdir(_jsonFolder)for sfn in input_files:                                     # single file nameif (os.path.splitext(sfn)[1] == ".json"):               # 是否为json文件# 调用labelme_json_to_dataset执行转换,输出到 temp 文件夹os.system("labelme_json_to_dataset %s -o temp" % (_jsonFolder + '/' + sfn))# 复制json文件中提取出的原图到存储目录if _args.out_img:if not os.path.exists(_args.out_img):           # 文件夹是否存在os.makedirs(_args.out_img)src_img = "temp\img.png"dst_img = _args.out_img + '/' + os.path.splitext(sfn)[0] + ".png"shutil.copyfile(src_img, dst_img)# 复制mask图到存储目录if _args.out_mask:if not os.path.exists(_args.out_mask):          # 文件夹是否存在os.makedirs(_args.out_mask)src_mask = "temp\label.png"dst_mask = _args.out_mask + '/' + os.path.splitext(sfn)[0] + ".png"shutil.copyfile(src_mask, dst_mask)# 复制viz图到存储目录if _args.out_viz:if not os.path.exists(_args.out_viz):           # 文件夹是否存在os.makedirs(_args.out_viz)src_viz = "temp\label_viz.png"dst_viz = _args.out_viz + '/' + os.path.splitext(sfn)[0] + ".png"shutil.copyfile(src_viz, dst_viz)

将其与待转换的json文件放入同一个文件夹中,命令行切换至该目录,执行

python trans.py -i ./ -r img -m mask -v viz

即可完成转换,生成所需的四个文件夹

读取图片并转换为dataframe格式

json文件转换得到的掩码(mask)是RGB三通道彩色图,而语义分割需要的掩码往往是灰度图。

可以使用cv2库中的imread函数直接将三通道彩色图导入为灰度图,导入后查看六种不同标签的到灰度值如下(背景灰度值为0)

为了便于训练,我自己写了一个类似switch的字典用于将灰度值转换为0,1,2,3,4,5,6的标签值。

# labelconvert.py
def case0():                           return 0
def case1():                           return 1
def case2():                            return 2
def case3():                            return 3
def case4():                            return 4
def case5():                            return 5
def case6():                            return 6
def default(): print('Error')                        return 255
switch = {38: case1,                75: case2,113: case3,14: case4,52: case5,89: case6,0: case0}
def labelconvert(img):for i in range (360):for j in range (400):img[i][j] = switch.get(int(img[i][j]), default)() return img

为了方便存储原图、掩码和文件名,使用pandas的dataframe进行存储,dataframe里的数据也可以转换为np数组或tensor张量。

from tensorflow.keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_img
import matplotlib.pyplot as plt
import cv2
import numpy as np
from labelconvert import labelconvert  # 自定义函数,用于灰度标签转换为0-6
import os
import pandas as pd
import timemaskdf = pd.DataFrame(columns=('id', 'mask', 'Fspread'))
inputdf = pd.DataFrame(columns=(['input']))
mask_dir = 'D:\\OriginIonograms\\lyf50\\mask\\'
input_dir = 'D:\\OriginIonograms\\lyf50\\img\\'i = 1
tic1 = time.perf_counter()
# 导入mask数据
for filename in os.listdir(mask_dir):img = cv2.imread(mask_dir + "/" + filename, cv2.IMREAD_GRAYSCALE)   #导入灰度图img = img_to_array(img)img = labelconvert(img)   # 替换比较耗时Fspread = (img == 6).any() # Fspread = (img == 89).any() # 不做标签转换maskdf.loc[i] = [filename, img, Fspread]i = i + 1
tic2 = time.perf_counter()
print('导入', i-1,'组mask数据用时',tic2-tic1,'s' )# 导入input数据
i = 1
for filename in os.listdir(input_dir):img = cv2.imread(input_dir + "/" + filename, cv2.IMREAD_GRAYSCALE)img = img_to_array(img)inputdf.loc[i] = [img]i = i + 1
tic3 = time.perf_counter()
print('导入', i-1,'组input数据用时',tic3-tic2,'s' )df = pd.concat([maskdf, inputdf], axis=1)
print(df.columns)df2 = df.drop(df[df.Fspread == 1].index)
print('所有数据共', df.shape[0], '条')

从图片到dataframe——语义分割数据集制作全流程相关推荐

  1. 【语义分割数据集制作】使用labelme制作自己的U-net语义分割数据集

      最近有一个工作需要使用Unet的语义分割结果作为上游任务,语义分割数据集需要自己制作,特此记录一下. 1.下载labelme   第一步当然是下载labelme工具,主要有两种方式:   1. 系 ...

  2. 快速制作自己的VOC语义分割数据集

    语义分割数据集制作与转换方法 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 第一章 基于PS的语义分割标注 第二章 构建VOC语义分割数据集 文章目录 语义分割数据集制作与转换方法 ...

  3. 图像分割数据集制作matlab,制作自己的图像语义分割数据集

    本文教你如何正确制作自己的图像语义分割数据集.假设我当前目录下有500张图片,命名从1.jpg开始,一直往上递增,我事先已经调整好了图像的大小. 首先下载Labelme工具:https://githu ...

  4. 自己制作语义分割语义分割数据集

    最近在用deeplab,需要自己标注数据集,整理一下. 制作语义分割数据集大致需要 (1)使用labelme对数据进行标注,生成对应图片的json格式. (2)执行label下的labelme_jso ...

  5. 制作自定义语义分割数据集

    自定义语义分割数据集(划分训练集与验证集).并且将一个文件夹下的所有图片的名字存到txt文件 我们可以借助Pytorch从文件夹中读取数据集,十分方便,但是Pytorch中没有提供数据集划分的操作,需 ...

  6. 无人驾驶常用数据集---图像语义分割数据集--Cityscapes数据集的解读(for 小白)

    ** 无人驾驶常用数据集–图像语义分割数据集–Cityscapes数据集的解读(for 小白) ** 一.什么是Cityscapes数据集? Cityscapes是关于城市街道场景的语义理解图片数据集 ...

  7. 憨批的语义分割6——制作语义分割数据标签

    憨批的语义分割6--制作语义分割数据集 学习前言 制作工具Labelme Labelme的使用 标签文件内容 学习前言 有些小伙伴问怎么制作数据集,其实我也没有去制作过--所以也要学学啦, 制作工具L ...

  8. 4种语义分割数据集Cityscapes上SOTA方法总结

    本文分享自华为云社区<语义分割数据集Cityscapes上SOTA方法总结>,原文作者:fdafad. 1 Cityscapes数据集介绍 Cityscapes评测数据集即城市景观数据集, ...

  9. 遥感影像语义分割数据集

    遥感图像语义分割数据集 文章目录 遥感图像语义分割数据集 1.建筑 1.1 Aerial Image Segmentation Dataset 1.2 INRIA aerial image datas ...

最新文章

  1. Compiere去掉启动时的下面显示的进度条
  2. Git使用汇总之工作区、暂存区、版本库
  3. handler机制的原理_5分钟了解Handler错误使用场景
  4. 不得不看的17 个linux实用技巧
  5. Alfresco Community 批量导入指南
  6. 为什么 Web 开发人员需要学习一个 JavaScript 框架?
  7. 设计模式 之 单例模式
  8. 数据结构和算法练习网站_视频和练习介绍了10种常见数据结构
  9. linux课堂笔记(4)
  10. 蓝桥杯青少创意编程python组
  11. python3 compile_python3.2的pycompile
  12. 我是如何在自学编程9个月后找到工作的
  13. excel数据分析 - 17个计算统计类函数
  14. Python3截图识字工具
  15. maven报错:Failure to transfer xxx.jar from xxx was cached in the local repository.
  16. 高质量web前端后台模板
  17. 多合一音乐搜索器项目源码分享,支持播放,下载
  18. 解决浏览器看不到Flash文档(尤其某慕课)
  19. 北京三里屯苹果店悼念乔布斯:“黄牛”也献花
  20. 综合架构(备份部分)

热门文章

  1. bzoj1050 [HAOI2006]旅行comf
  2. ZT I Believe I Can Fly(我相信我能飞)
  3. 限时免费!2016杭州云栖大会抢票指南
  4. 哈夫曼树中压缩率到底是什么意思
  5. C语言自定义类型——枚举类型讲解
  6. mysql里如何写日期格式_mysql 日期格式
  7. X86与ARM平台下的参数传递机制
  8. DSB matlab仿真
  9. 小工具:找出序列中的极值点
  10. 直接在html打开ppt,PPT内如何直接看网页