最近要跑分割,但是用的分割项目的数据集格式是voc格式,如下图:
-ImageSets
--Segmentation
--train # 存放训练数据的名称
--trainval # 存放总数据名称
--val # 存放验证数据名称
-JPEGImages # 总图片
-SegmentationClass # voc形式的分割图片
voc形式的标签图片:voc标签图片是将类别index(1,2,3,......)映射到颜色。
详细讲解:分割标签索引颜色对照及程序
现在用labelme标注的分割数据集标签是json类型,标注信息会以一个大字典的形式存储在json文件中,要将json形式标签转化成voc带有调色盘的标签图片。
方法一:
搜索发现labelme自带json转voc格式的源码,详细操作参考该博客https://blog.csdn.net/u011574296/article/details/79740633dad但是看了其中的源码发现(我看的是labelme安装位置下的json_export.py)该代码每次只能转换一张图片,很费力,而且我只需要voc格式的数据集,不需要其他的,所以自己改了一下脚本。如方法二
方法二:
root_path='label/result'
data_list=os.listdir(root_path)
for name in data_list:
if name.split('.')[-1]=='json':
json_path=os.path.join(root_path,name)
img_path=os.path.join(root_path,name.split('.')[0]+'.png')
tmp = {}
with open(json_path, "r") as f:
tmp = f.read()
tmp = json.loads(tmp)
img = cv2.imread(img_path)
mask = np.zeros(img.shape[:2],dtype=np.uint8) #
mask1 = np.zeros(img.shape[:2],dtype=np.int32)
mask=Image.fromarray(mask)
l=len(tmp['shapes'])
for i in range(0,l):
draw=ImageDraw.Draw(mask)
points = tmp["shapes"][i]["points"] # 将point大列表中的每个点的列表转化为元组
xy=[tuple(point) for point in points]
# print(xy)
assert len(xy)>2,"Polygon must have points more than 2" # 至少两个点才能绘制一个封闭的图形
draw.polygon(xy=xy, fill=1)
a = np.array(mask, dtype=bool)
# print(mask1.shape)
mask1[a]=1 # 这里1表示该类别的index是1,因为我这里只需要一类,可根据情况自行修改。
# 调色板上色
mask=Image.fromarray(mask1.astype(np.uint8),mode="P")
colormap = imgviz.label_colormap()
mask.putpalette(colormap.flatten()) # 将调色板放入图片中
mask_path=os.path.join('voc_label',name.split('.')[0]+'.png')
mask.save(mask_path)
print('successful')
将带有json和对应图片的路径传给root_path,就可以生成对应的voc标签。
最终我的voc标签: