使用labelme后,生成如图所示文件夹,其中JPEGImages是原图,SegmentationClassPNG是标签。
此时SegmentationClassPNG中的标签(masks)是只包含0和1的二进制文件,0表示背景,1表示要识别的物体类型。(二分类),为单通道彩色图
查看图片的像素点:参考:Python查看图片模式及像素
src= Image.open(r"D:/CV/images/change/vocSample/SegmentationClassPNG/bad-003.png")
print(src.mode)
for y in range(src.size[1]):#行不变
for x in range(src.size[0]):#列变化
pix = src.getpixel((x,y))
print(pix)
此时SegmentationClassPNG中图片的像素点如下:
由于原数据集较小,因此使用albumentations进行数据增强,由于cv2默认读取为BGR格式,因此masks变成了多通道彩色图。
1.将多通道彩色图转为单通道灰度图
from PIL import Image
import os
path = 'D:\\CV\\images\\test\\masks' # 读取图片文件夹路径
save_path = 'D:\\CV\\images\\test\\masks_oneChennal' # 保存图片文件夹路径
file_list = os.listdir(path) # 读取路径下所有图片的名字
# 对每张图片进行转换
for file in file_list:
o_img = Image.open(path+ '/' + file)
L_img = o_img.convert('L') # 转换为灰度图片
L_img.save(save_path + '/' + file)
print("已完成")
查看此时的像素点由0和38构成:
3.将图片的像素值变为只包含0或1的二进制文件。参考:数据增强系列(5)PyTorch和Albumentations用于语义分割
def preprocess_mask(mask):
mask = mask.astype(np.uint8)
mask[mask == 0] = 0
mask[(mask == 1) | (mask == 38)] = 1
return mask
src= Image.open("D:/CV/images/MyDataSet/UnetDataSet/test/UnetTestOut/new.png")
mat = np.array(src)
print(mat)
mask=preprocess_mask(mat)
print(mask)
dst = Image.fromarray(mask, 'P')
dst.save("D:/CV/images/MyDataSet/UnetDataSet/test/UnetTestOut/01.png")
原来的多通道图片转为单通道灰度图后,并不是完全由0或1构成,需要进行转换,如下图:
此时的01.png仅是只包含0和1的二进制文件
3.将单通道灰度图,变为单通道彩图,更容易区分,参考:numpy转PIL.Image: 处理Mask图像为单通道的彩色/灰度图colormap.png
import numpy as np
import PIL.Image as Image
def preprocess_mask(mask):
mask = mask.astype(np.uint8)
mask[mask == 0] = 0
mask[(mask == 1) | (mask == 38)] = 1
return mask
src= Image.open("D:/CV/images/MyDataSet/UnetDataSet/test/UnetTestOut/new.png")
mat = np.array(src)
print(mat)
mask=preprocess_mask(mat)
print(mask)
dst = Image.fromarray(mask, 'P')
bin_colormap = [0,0,0] + [255,0,0]*254 # 二值调色板,红色
dst.putpalette(bin_colormap)
dst.save("D:/CV/images/MyDataSet/UnetDataSet/test/UnetTestOut/01.png")