Helen人脸数据集包括2330张人脸图像,并且每张人脸图像包含11个部位的掩模,通常做人脸分割只需要面部以及面部特征掩模即可。数据集文件的整体结构如下:
依赖的库:
import os
import cv2 as cv
import numpy as np
定义人脸分割不同部位的颜色:
colors = [[160, 0, 10], [11, 138, 19], [11, 138, 19], [21, 83, 184], [21, 83, 184], [33, 182, 151], [255, 16, 16], [88, 13, 13], [255, 16, 16]]
其中掩模的第一张图像是背景,掩模的最后一张图像是头发,如果只需要脸部特征掩模那么我们只需要9张掩模图像即9种不同的分割颜色。
img_list = os.listdir('./images/')
masks_dir = os.listdir('./labels/')
for i in range(len(masks_dir)):
images = os.listdir(os.path.join('./labels/', masks_dir[i]))
raw = cv.imread(os.path.join('./labels/', masks_dir[i]+'/'+images[-1]))
h, w, _ = raw.shape
src_img = np.zeros((h, w, 3), dtype=np.uint8)
# 9个不同人脸关键部位的分割生成
for j in range(1, 10):
mask = cv.imread(os.path.join('./labels/', masks_dir[i]+'/'+images[j]))
# 掩模是灰度图像, 需要将像素值映射到[0,1]区间
mask = mask / 255.
h, w, _ = mask.shape
# 0.85是分割阈值,选取的阈值越大生成的人脸关键部位的分割面积越小,反之越大。
mask = (mask > 0.85)[:, :, 0]
color_mask = np.zeros((h, w, 3), dtype=np.uint8)
mv = cv.split(color_mask) # 通道分离
mv[2][mask == 1], mv[1][mask == 1], mv[0][mask == 1] = colors[j-1]
color_mask = cv.merge(mv) # 通道合并
src_img = src_img + color_mask # 不同部位分割依次叠加
cv.imwrite(os.path.join('./segmentation/', masks_dir[i]+'.png'), src_img)
生成的人脸分割如下: