【PIL】图像分割竞赛中8位深调色板模式的mask读取与保存(PASCAL VOC)
目录:
1.调色板图像原理
首先理解调色板图像的结构,与RGB模式不同,调色板图像中每个像素为0~255中的一个数,代表颜色索引,而调色板图像本身还会存储一个叫调色板(palette)的数据结构, 最多存储256组rgb颜色。图像中的每一个像素,通过颜色索引, 可以在调色板中获得相应的颜色。
下面是某场比赛的mask数据和它对应的调色板展示:
这场比赛只有4类,mask使用的调色板模式,直接这样使用PIL读入图片,其中图像的像素值为颜色索引,一般来说也正好对应了比赛中的类别编号。
上图为该mask的调色板,因为比赛只有4类,所以除了前4个位置,调色板后面252个位置全置为了0。
不reshape的话,调色板是一维的。
2.代码
2.1 读取mask转换为GT
import os
from PIL import Image
import numpy as np
img_pil = Image.open('mask/xxx.png')
gt = np.array(img_pil)
# img_pil.close() 如果要连续用PIL打开文件最好close一下不用的
2.2 保存调色板
这一步的目的是为了保存模型预测的mask时逻辑上的美观,当然图方便也可以直接用原数据mask中的调色板, 可忽略此步。
img_pil = Image.open('mask/xxx.png')
palette = img_pil.getpalette() # 获取调色板
np.save('cmap.npy', palette)
img_pil.close()
这样原数据集中的调色板数据就保存在了cmap.npy文件中,之后每次保存mask时就可以直接用cmap的。
2.3 保存预测的mask为调色板模式(P模式)
cmap = np.load('cmap.npy')
img_pil = Image.fromarray(img, mode='P')
img_pil.putpalette(cmap.tolist()) # 赋予调色板,要从numpy变为list
# img_pil.show()
img_pil.save('pred/'+fname)
如果图方便,也可以直接img_pil.putpalette(palette) #2.2中的
3.参考
自制VOC数据集的踩坑记录和解决方案:使用PIL生成8位深的RGB图像
numpy转PIL.Image: 处理Mask图像为单通道的彩色/灰度图colormap.png