语义分割标签——mask的读取与保存

上篇博客对语义分割数据集进行Copy-Paste数据增强(点我访问),其中涉及到对mask文件的读写,踩了一些坑,在这里记录一下相关知识点。

目录

一、灰度模式与调色板模式

二、两种模式对应的读写方法

三、语义分割mask可视化


一、灰度模式与调色板模式

我们标注好的文件,或者通过模型预测出的结果,通常保存为.png格式的图片。不同于RGB图像,其保存的位数为8位,或是灰度图、或是调色板图;

在PIL格式中,我们通过查看其mode属性,能够发现其区别。

我们使用VOC2012中的两个mask图片:'2007_000032.png'、'2007_000033.png',其样式分别为:

 其mode属性分别为:

from PIL import Image

print(Image.open('2007_000032.png').mode)  # L
print(Image.open('2007_000033.png').mode)  # P

二、两种模式对应的读写方法

之所以其mode属性不同(一个是L,代表灰度模式,另一个是P,代表调色板模式),是因为对分割好的mask文件保存时的方式不同。对于灰度模式,直接使用cv2.imwrite()函数进行保存即可,只不过读取时,需要按照灰度图的方式读取|(用OpenCV或者PIL格式均可以):

# 方式一:
label = cv2.imread(label_path, 0)

# 方式二:
label = np.asarray(Image.open(label_path), dtype=np.int32)

而对于调色板模式,其保存方式如下:

def save_colored_mask(mask, save_path):
    lbl_pil = Image.fromarray(mask.astype(np.uint8), mode="P")
    colormap = imgviz.label_colormap()
    lbl_pil.putpalette(colormap.flatten())
    lbl_pil.save(save_path)

如上,需要先将array格式的mask转为PIL.Image格式,然后,使用imgviz中的Label colormap给mask添加调色板,最后保存PIL.Image格式的图像即可。读取时,则需要同样使用PIL.Image格式来读取,然后转为array,而不可以使用OpenCV进行读取

# 正确的读取方式
label = np.asarray(Image.open(label_path), dtype=np.int32)

# 错误的读取方式:因为调色板模式下,使用cv2.imread(label_path, 0)会默认以BGR转灰度图的模式读取,从而导致得到的label值不一致
label = cv2.imread(label_path, 0)

三、语义分割mask可视化

对于可视化则比较简单,因为不需要考虑模式问题,可以使用OpenCV也可以使用PIL的方式:

# OpenCV方式:
image = cv2.imread('2007_000033.jpg')
mask = cv2.imread('2007_000033.png')
mask_img = cv2.addWeighted(image, 0.5, mask, 0.7, 0.9)
cv2.imwrite("vis.jpg", mask_img)

# PIL方式:
image = Image.open('2007_000033.jpg')
mask = Image.open('2007_000033.png')
mask_img = Image.blend(image.convert('RGBA'),
                       mask.convert('RGBA'), 0.7)
mask_img.save("vis2.png")

两种方式的可视化结果一样:

猜你喜欢

转载自blog.csdn.net/oYeZhou/article/details/111934432
今日推荐