[GAN]CelebAMask-HQ数据集处理、划分
CelebAMask数据集是2020年MaskGAN这篇⽂章⼀起提出的,这篇⽂章主要讲了利⽤⽤户修改后的语义分割信息来引导图像编辑。
港中⽂和商汤合作的,还是蛮不错的⼀篇⽂章。
⽂章链接:
本篇博客只讲⽂章对于CelebAMask数据集补充的部分(因为博主⽬前更关⼼这部分哈哈哈啊哈!)
CelebAMask简介
MaskGAN作者们构造⼀个名为CelebAMask-HQ的⼤规模⾼分辨率⼈脸数据集,其中包含细粒度的掩码标签(mask labels)。
CelebAMask-HQ由超过30000张512×512分辨率的⼈脸图像组成,其中每张图像都带有19个⾯部组件类别的语义掩码(例如眼睛区域、⿐⼦区域、嘴巴区域)
心怦怦跳
CelebAMask-HQ数据集和现存数据集的对⽐:
CelebAMask的特性
CelebAMask-HQ⼤规模⼈脸语义标签数据集,根据CelebA-HQ[17]进⾏标记(CelebA-HQ包含来⾃CelebA[27]的30000张⾼分辨率⼈脸图像)。它有⼏个吸引⼈的特性:
感兴趣可以去看看CelebA-HQ和CelebA的提出网球爱好者
CelebA-HQ[17]Tero Karras, Timo Aila, Samuli Laine, and Jaakko Lehtinen.Progressive growing of gans for improved quality, stability,and variation. arXiv preprint arXiv:1710.10196, 2017.
CelebA[27] Tero Karras, Timo Aila, Samuli Laine, and Jaakko Lehtinen.Progressive growing of gans for improved quality, stability,and variation. arXiv preprint arXiv:1710.10196, 2017.
1. 全⾯的注释。CelebAMask-HQ的尺⼨为512×512,有19个类别,包括所有⾯部组件和配件的精准⼿⼯注释,如“⽪肤”、“⿐
⼦”、“眼睛”、“眉⽑”、“⽿朵”、“嘴巴”、“嘴唇”、“头发”、“帽⼦”、“眼镜”、“⽿环”、“项链”、“脖
⼦”和“布料”。
2. 标签⼤⼩选择。CelebA-HQ[17]中的图像⼤⼩为1024×1024。然⽽,CelebAMask-HQ选择了512×512的mask⼤⼩,因为在
1024×1024的图像上标记⼈脸的成本⾮常⾼。此外,我们可以通过最近邻插值(nearest-neighbor interpolation)轻松地将标签从512×512扩展到1024×1024,⽽不会产⽣明显的伪影。
3. 质量控制。⼿⼯注释后,我们对每⼀个分割mask进⾏了质量检查。此外,我们要求注释⼈员通过⼏轮迭代来优化所有遮罩。(标数据
真惨啊,真的能给⼈眼睛标瞎)
4. 特殊情况处理。对于遮挡的处理:如果⾯部组件被部分遮挡,我们要求注释者通过⼈类推断来标记组件被遮挡的部分。另⼀⽅⾯,我
们跳过了那些完全被遮挡的组件的注释。
CelebAMask使⽤
数据预处理
g_mask.py⽣成完整mask
数据集提供的CelebAMask-HQ-mask-anno是每张图像各个类别(眼、⿐、配饰等)分开的mask,如下图:
⾸先先将CelebA-HQ-img(图像)和CelebAMask-HQ-mask-anno(未整合的label)移动到Data_preprocessing⽬录下。还有(CelebA-HQ和CelebA数据级
的映射,⽤于训练集验证集测试集的的划分),这个txt⽂件记得把第⼀⾏去掉!。博主⽤直接软链接的⽅式,链过来了。
通过该脚本把mask值合在⼀起,需要注意修改⽂件名(估计是作者更新数据集的时候把数据集名字改了,处理mask的脚本也是很早写的,所以名字没对应上,跑还不报错,但是结果是没有数值的mask,看了⼀个⼩时才发现是名字没对上,也是醉了)
修改+整理+注释的脚本如下:
g_mask.py
import os
import cv2
import numpy as np
from utils import make_folder
label_list =['skin','no','eye_g','l_eye','r_eye','l_brow','r_brow','l_ear','r_ear','mouth','u_lip','l_lip','hair','hat','ear_r','neck_l','neck','cloth']
# 输⼊数据集的名称⼀定要检查⼀下,这个名称错了不会报错,但是输出的mask⾥⾯全部都是空值
folder_ba ='CelebAMask-HQ-mask-anno'坚韧的近义词
folder_save ='CelebAMaskHQ-mask'
img_num =30000# 数据集⼀共有30000张图⽚
make_folder(folder_save)
for k in range(img_num):
folder_num = k //2000# 该图⽚的分割组件存放的⽬录,⼀共有15个⽬录,每个⽬录存了2000张分割结果(包含⼀张图⽚的⾯部各个组件分开的分割结果) im_ba = np.zeros((512,512))
for idx, label in enumerate(label_list):
filename = os.path.join(folder_ba,str(folder_num),str(k).rjust(5,'0')+'_'+ label +'.png')
if(ists(filename)):
print(label, idx+1)
im = cv2.imread(filename)
im = im[:,:,0]# 取出图像第⼀个通道的值(分割图像只有⼀个通道,但是是部分的组件)
im_ba[im !=0]=(idx +1)# 将该部分的值赋予⼀个idx+1的数值,实现分割,后期填充上颜⾊就变成我们看到的最终分割结果了
filename_save = os.path.join(folder_save,str(k)+'.png')
print(filename_save)
cv2.imwrite(filename_save, im_ba)# 保存图⽚
⽣成的图⽚就是⿊的,上⾯存的都是1~20的数值。
g_color.py⽣成带颜⾊的mask
注意⼀下folder_ba和folder_save就可以了,还有循环中有些⼩错,可能原作者忘更新了。
g_color.py
import os
from PIL import Image
import numpy as np
from utils import make_folder
color_list =[[0,0,0],[204,0,0],[76,153,0],[204,204,0],[51,51,255],[204,0,204],[0,255,255],[255,204,204],[102,51,0],[255,0,0],[102,204,0], [255,255,0],[0,0,153],[0,0,204],[255,51,153],[0,204,204],[0,51,0],[255,153,51],[0,204,0]]
folder_ba ='CelebAMaskHQ-mask'
folder_save ='CelebAMask-HQ-mask-color'
img_num =30000
make_folder(folder_save)
for k in range(img_num):
filename = os.path.join(folder_ba,str(k)+'.png')
im_ba = np.zeros((512,512,3))
if(ists(filename)):
print(filename)
im = Image.open(filename)
im = np.array(im)
for idx, color in enumerate(color_list):
im_ba[im == idx]= color # 将标签idx(单通道数据)和三通道的颜⾊对应上,给数据⼀个⾊彩填充
filename_save = os.path.join(folder_save,str(k)+'.png')
result = Image.fromarray((im_ba).astype(np.uint8))
print(filename_save)
result.save(filename_save)
对应的RGB颜⾊可以上⽹查⼀下,⽐如[76, 153, 0]对应的就是下⾯的绿⾊
最终⽣成的带颜⾊的mask如下所⽰:
g_partition.py划分数据集
脚本如下,原作者可能是想保存⼀下train_list,但是忘写了哈哈哈哈啊。
滚筒洗衣机怎么清洗污垢import os
哑铃背部训练
import shutil
import pandas as pd
from shutil import copyfile
说了再见以后
from utils import make_folder
#### source data path
# s_label = 'CelebAMask-HQ-label'
s_label ='CelebAMask-HQ-mask'
s_img ='CelebA-HQ-img'
韩国饮食#### destination training data path
d_train_label ='train_label'
d_train_img ='train_img'
#### destination testing data path
d_test_label ='test_label'
d_test_img ='test_img'
#### val data path
d_val_label ='val_label'
d_val_img ='val_img'
#### make folder
make_folder(d_train_label)
make_folder(d_train_img)
make_folder(d_test_label)
make_folder(d_test_img)
make_folder(d_val_label)
make_folder(d_val_img)
#### calculate data counts in destination folder
train_count =0
test_count =0
val_count =0
image_list = pd.read_csv('', delim_whitespace=True, header=None) f_train =open('','w')
f_val =open('','w')
f_test =open('','w')
for idx, x in enumerate(image_list.loc[:,1]):
print(idx, x)
if x >=162771and x <182638:
copyfile(os.path.join(s_label,str(idx)+'.png'), os.path.join(d_val_label,str(val_count)+'.png'))
copyfile(os.path.join(s_img,str(idx)+'.jpg'), os.path.join(d_val_img,str(val_count)+'.jpg'))
val_count +=1
elif x >=182638:
copyfile(os.path.join(s_label,str(idx)+'.png'), os.path.join(d_test_label,str(test_count)+'.png'))
copyfile(os.path.join(s_img,str(idx)+'.jpg'), os.path.join(d_test_img,str(test_count)+'.jpg'))
test_count +=1
el:
不忘根本copyfile(os.path.join(s_label,str(idx)+'.png'), os.path.join(d_train_label,str(train_count)+'.png')) copyfile(os.path.join(s_img,str(idx)+'.jpg'), os.path.join(d_train_img,str(train_count)+'.jpg'))
train_count +=1
print(train_count + test_count + val_count)
#### clo the file
f_train.clo()
f_val.clo()
f_test.clo()