在制作分割数据集时需要对图像进行标注,但标注过程比较耗时,因此想到通过画图填充的方法制作mask标签,从而节省时间。(注:最好图片格式为png)
- 对图像进行画图填充
- 调整像素值
填充后的图像存在一个问题,如填充为红色,像素值应为(255,0,0),但实际填充后像素值可能为(240, 0,0),从而造成像素值存在误差,而图像分割实质是根据像素值进行分类,因此结果可能会造成存在多余类别。因此需对像素值进行调整。代码如下:
#黑色(0,0,0)
#红色(255,0,0)
#蓝色(0,0,255)
import os
from PIL import Image
path = 'C:/Users/123/Desktop/1/'
savedpath = 'C:/Users/123/Desktop/2/'
filelist = os.listdir(path)
for item in filelist:
im = Image.open(path + item) # 打开图片
pix = im.load() # 导入像素
width = im.size[0] # 获取宽度
height = im.size[1] # 获取长度
for x in range(width):
for y in range(height):
r, g, b = im.getpixel((x, y))
g = 0
if r <= 50:
r = 0
if b <= 50:
b = 0
else: b = 255
if r > 50 and b <= 50:
r = 255
b = 0
if r > 50 and b > 50:
if r > b :
r = 255
b = 0
else:
r = 0
b = 255
rgb = (r, g, b)
im.putpixel((x, y), rgb)
#print(rgb)
#if (a == 0):
#im.putpixel((x, y), (0, 0, 0, 0))
#if (a == 255):
#im.putpixel((x, y), (255, 255, 255, 255))
im = im.convert('RGB')
new_name = item[0: -4] + '.png'
im.save(savedpath + new_name)
print('item of %s is saved ' % (new_name))
3.rgb转单通道灰度图
利用labelme标注生成的json文件,转为png后,其实只包含n个像素值(n为类别数)若只有两类,则只包含0和1,因此我们需要将rgb图像转换为单通道灰度图。即如(255,0,0)转换为0,(0,0,255)转换为1,。。。依次。这样制作的mask等效于labelme标注生成的mask。
from random import randint
import os
import numpy as np
import imgviz
from PIL import Image
def get_gray_cls(van_lbl):
cls = [0] # 用来存储灰度图像中每种类别所对应的像素,默认背景色为0
for x in range(van_lbl.size[0]):
for y in range(van_lbl.size[1]):
pix = van_lbl.getpixel((x, y))
#print(array_lbl[x, y])
if pix not in cls:
cls.append(pix)
return cls
def get_P_cls(cls_gray):
cls_P = [] # 将灰度图像中的每类像素用0~N表示
for i in range(len(cls_gray)):
cls_P.append(i)
return cls_P
def array_gray_to_P(cls_gray, cls_P, array):
for i in range(len(cls_gray)):
array[array == cls_gray[i]] = cls_P[i]
return array
if __name__ == '__main__':
label_from_PATH = 'C:/Users/123/Desktop/2/' # 存放原始label的路径
label_to_PATH = 'C:/Users/123/Desktop/4/' # 存放转换后图像当路径
van_file = 'C:/Users/123/Desktop/2/0246.png' # 必须是一张包含所有类别的图像,称之为先锋图像
van_lbl = Image.open(van_file).convert('L') # 将先锋图像转换为灰度图像
print(van_lbl.size)
#array_lbl = np.array(van_lbl) # 获得灰度图像的numpy矩阵
#print(array_lbl.size)
cls_gray = get_gray_cls(van_lbl) # 获取灰度图像中每种类别所对应的像素值
print(cls_gray)
cls_P = get_P_cls(cls_gray) # 将灰度图像中的每种类别所对应的像素值映射为0~N
print(cls_P)
#print(cls_gray)
#print(cls_P)
file_list = os.listdir(label_from_PATH)
if not os.path.isdir(label_to_PATH):
os.mkdir(label_to_PATH)
# 遍历每一张原始图像
for file_name in file_list:
file_path = os.path.join(label_from_PATH, file_name)
orig_lbl = Image.open(file_path).convert('L') # 将图像转换为灰度图像
array_gray = np.array(orig_lbl) # 获得灰度图像的numpy矩阵
array_P = array_gray_to_P(cls_gray, cls_P, array_gray) # 将灰度图像的numpy矩阵值映射为0~N
label = Image.fromarray(array_P.astype(np.uint8), mode='P') # 转换为PIL的P模式
# 转换成VOC格式的P模式图像
colormap = imgviz.label_colormap()
label.putpalette(colormap.flatten())
label.save(os.path.join(label_to_PATH, file_name))