人脸口罩识别——人脸添加口罩方法masked_faces

A realistic approach to generate masked faces applied on two novel masked face recognition data sets

1 人脸添加口罩masked_faces

1、论文和代码

paper:https://arxiv.org/pdf/2109.01745v5.pdf
code:https://github.com/securifai/masked_faces

2、作者在CelebACASIA-WebFace两个口罩数据集上添加口罩,处理出两个数据集,数据集下载地址:

  • CelebA+masks

  • CASIA-WebFace+masks

  • CASIA-WebFace 数据集上生成445446张(90%)添加口罩人的人脸图片

  • CelebA数据集上生成196254张 (96.8%)张添加口罩的人脸图片

2 添加口罩原理

该实现时依赖于facebook的Spark AR Studio,这是用于Instagram人脸滤镜的(face filter)。 作者使用该方法:

在这里插入图片描述

1、首先给一张原始图片
2、随机选择一个mask,然后使用SparkAR的3D face 模型进行转换mask模板
3、调整mask颜色,然后添加到人脸上

效果:

在这里插入图片描述

3 添加口罩代码操作

依赖python库包(tqdm、opencv-python)

1、数据准备:

  • 口罩mask的模板图片
  • 原始的CelebACASIA-WebFace数据集

2、在CelebA数据集上处理过程

数据集准备:

main directory
│   apply_masks_celeba.py
└───celeba_masks - masks folder (from this repo)
│   │   ...
└───celeba - data set folder (original images)
│   │   ...
└───masked_celeba - output folder (images with overlaid masks)...    

python python apply_masks_celeba.py

3、在CASIA-WebFace数据集上处理过程

数据集准备:

main directory
│   apply_masks_casia.py
└───casia_masks - masks folder (from this repo)
│   │   ...
└───casia - data set folder (original images)
│   │   ...
└───masked_casia - output folder (images with overlaid masks)...    

python apply_masks_casia.py

4 源码分析

apply_masks_casia.py

# This script applies masks over Casia-WebFace dataset. casia_folder, masks_folder, output folder should be set
# SecurifAI - 2021


import os
import glob
import cv2
from tqdm import tqdm

def overlay_image_alpha(img, img_overlay, pos, alpha_mask):
    x, y = pos

    y1, y2 = max(0, y), min(img.shape[0], y + img_overlay.shape[0])
    x1, x2 = max(0, x), min(img.shape[1], x + img_overlay.shape[1])

    y1o, y2o = max(0, -y), min(img_overlay.shape[0], img.shape[0] - y)
    x1o, x2o = max(0, -x), min(img_overlay.shape[1], img.shape[1] - x)

    if y1 >= y2 or x1 >= x2 or y1o >= y2o or x1o >= x2o:
        return

    channels = img.shape[2]

    alpha = alpha_mask[y1o:y2o, x1o:x2o]
    alpha_inv = 1.0 - alpha

    for c in range(channels):
        img[y1:y2, x1:x2, c] = (alpha * img_overlay[y1o:y2o, x1o:x2o, c] +
                                alpha_inv * img[y1:y2, x1:x2, c])




# casia images main folder
casia_folder = 'CASIA-WebFace'

# masks main folder
masks_folder = 'CASIA-WebFace_masks'

# masks img list
mask_list = glob.glob(masks_folder + '/*/*.png')

# output folder
output_folder = 'masked_CASIA-WebFace'

if not os.path.isdir(output_folder):
    os.mkdir(output_folder)


for mask in tqdm(mask_list):    
    
    # get the basename of the mask to find original Casia image
    mask_basename = os.path.basename(mask)
    
    parent_folder = os.path.basename(os.path.dirname(mask))
    if not os.path.isdir(os.path.join(output_folder,parent_folder)):
        os.mkdir(os.path.join(output_folder,parent_folder))

    # create path for original mask
    img_path = os.path.join(casia_folder, parent_folder, mask_basename.replace('png','jpg')) 

    # check that original image exists, if it exists load it
    if os.path.isfile(img_path):
        casia_image = cv2.imread(img_path)
    else:
        continue
        
    # load the mask
    mask_image = cv2.imread(mask,cv2.IMREAD_UNCHANGED)
    
    # apply mask over image
    overlay_image_alpha(casia_image,
        mask_image[:, :, 0:3],
        (0, 0),
        mask_image[:, :, 3] / 255.0)

    # save new overlayed image
    cv2.imwrite(os.path.join(output_folder,parent_folder, mask_basename.replace('png','jpg')),casia_image)

apply_masks_celeba.py

# This script applies the celeba_masks over the celeba_images. celeba_folder, output_folder must be set.
# SecurifAI - 2021

import glob
import cv2
import os
from tqdm import tqdm

def overlay_image_alpha(img, img_overlay, pos, alpha_mask):
    x, y = pos

    y1, y2 = max(0, y), min(img.shape[0], y + img_overlay.shape[0])
    x1, x2 = max(0, x), min(img.shape[1], x + img_overlay.shape[1])

    y1o, y2o = max(0, -y), min(img_overlay.shape[0], img.shape[0] - y)
    x1o, x2o = max(0, -x), min(img_overlay.shape[1], img.shape[1] - x)

    if y1 >= y2 or x1 >= x2 or y1o >= y2o or x1o >= x2o:
        return

    channels = img.shape[2]

    alpha = alpha_mask[y1o:y2o, x1o:x2o]
    alpha_inv = 1.0 - alpha

    for c in range(channels):
        img[y1:y2, x1:x2, c] = (alpha * img_overlay[y1o:y2o, x1o:x2o, c] +
                                alpha_inv * img[y1:y2, x1:x2, c])


# folder where celeba images are stored
celeba_folder = 'img_celeba'
img_list = glob.glob(celeba_folder + '/*.png')

# folder where the masks are stored
mask_folder = 'celeba_masks'
mask_list = glob.glob(mask_folder + '/*.png')

# output folder
output_folder = 'masked_celeba'

if not os.path.exists(output_folder):
    os.makedirs(output_folder)
    

for mask in tqdm(mask_list):
    # get basename and remove '_mask' string, change png to jpg
    mask_basename = os.path.basename(mask).replace('_mask','').replace('png','jpg')
    
    # get celeba path from mask path
    img_path = celeba_folder + '/' + mask_basename
    
    # check if we have an image for mask
    if os.path.exists(img_path):
        generated_mask = cv2.imread(mask,cv2.IMREAD_UNCHANGED)
        celeba_img = cv2.imread(img_path)
        
        # apply mask over celeba_image
        overlay_image_alpha(celeba_img,
                    generated_mask[:, :, 0:3],
                    (0, 0),
                    generated_mask[:, :, 3] / 255.0)
                    
        # write new image in output_folder
        cv2.imwrite(output_folder + '/' + mask_basename, celeba_img)
        

这个代码不全,在readme也没有说明,开源的代码几乎是没有什么价值!

猜你喜欢

转载自blog.csdn.net/weixin_41010198/article/details/122082070