前言:这篇文章记录了本人复现Face X-ray代码的过程以及参考的代码。由于这篇文章是笔者在完成复现完编写的,可能会有一些bug或者问题遗漏。在实现过程中,在关键点检测和混合人脸的过程推荐使用3.6版本的python环境。
一、关键点检测
- 原文参考的关键点检测模型是
Joint cascade face detection and alignment
提出的,是基于手工特征和级联回归实现的。本次复现采用关键点检测模型是"Deep Alignment Network: A convolutional neural network for robust face alignment"
,完全依赖于深度学习网络提取特征,DAN的效果更具鲁棒性。- 代码: MarekKowalski/DeepAlignmentNetwork: A deep neural network for face alignment
可能遇到的环境问题(笔者遇到了): AbstractConv2d Theano optimization failed
解决 :
① conda install numpy scipy mkl-service libpython m2w64-toolchain
② Theano 0.9.0 (不能使用0.8.1的,只有0.9.0的才不会报错)
生成关键点
解决完环境问题后,在提取过程几乎不会遇到多大问题,只需稍微修改一下ImageDemo
代码就可以生成自己人脸数据的关键点json文件,为步骤二混合人脸提供关键点数据。
import json
import os
from FaceAlignment import FaceAlignment
import numpy as np
import cv2
import utils
model = FaceAlignment(112, 112, 1, 1, True)
model.loadNetwork("../data/DAN-Menpo-tracking.npz")
cascade = cv2.CascadeClassifier("../data/haarcascade_frontalface_alt.xml")
keypoints_dict = {}
optimizer = None
def getKeypoint(path, cascade, model, keypoints_dict):
color_img = cv2.imread("../../../Face-Xray-master/train_poison/" + path)
if len(color_img.shape) > 2:
gray_img = np.mean(color_img, axis=2).astype(np.uint8)
else:
gray_img = color_img.astype(np.uint8)
# reset = True
landmarks = None
# if reset:
rects = cascade.detectMultiScale(gray_img, scaleFactor=1.2, minNeighbors=3, minSize=(50, 50))
for rect in rects:
tl_x = rect[0]
tl_y = rect[1]
br_x = tl_x + rect[2]
br_y = tl_y + rect[3]
cv2.rectangle(color_img, (tl_x, tl_y), (br_x, br_y), (255, 0, 0))
initLandmarks = utils.bestFitRect(None, model.initLandmarks, [tl_x, tl_y, br_x, br_y])
if model.confidenceLayer:
landmarks, confidence = model.processImg(gray_img[np.newaxis], initLandmarks)
if confidence < 0.1:
reset = True
else:
landmarks = model.processImg(gray_img[np.newaxis], initLandmarks)
landmarks = landmarks.astype(np.int32)
if (landmarks.shape[0]) == 68:
res = [[int(landmark[0]), int(landmark[1])] for landmark in landmarks]
keypoints_dict['./train_poison/' + path] = res # 将路径作为键,关键点作为值
# for i in range(landmarks.shape[0]):
# cv2.circle(color_img, (landmarks[i, 0], landmarks[i, 1]), 2, (0, 255, 0))
files = os.listdir("../../../Face-Xray-master/train_poison/")
for file in files:
getKeypoint(file, cascade, model, keypoints_dict)
output_json_path = 'output.json'
with open(output_json_path, 'w') as json_file:
json.dump(keypoints_dict, json_file, indent=4)
二、混合人脸
在混合人脸Face X-ray的实现过程主要的问题还是环境问题,推荐使用3.6版本的python环境。
- torch 1.10.2
- dlib 19.6.1
- opencv 4.1.2.30
解决完环境问题后,就可以根据上一步骤生成的json文件,运行bi_online_generation.py
,根据自己的需求生成人脸。为了能够生成满足可以作为HRNet
输入的数据,笔者直接将生成的图像存放到images文件夹下,需要注意的是,若采用cv2保存图像,还需要对图像的通道进行变换。
# bi_online_generation.py 部分代码修改部分
if __name__ == '__main__':
ds = BIOnlineGeneration()
from tqdm import tqdm
all_imgs = []
labels = []
id = 0
for _ in tqdm(range(20000)):
img,mask,label = ds.gen_one_datapoint()
img = cv2.resize(img, (224, 224))
img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
if label == 'fake':
cv2.imwrite(r"D:\pypro\Backdoor\DetectModel\YRM\detectmodel\HRNet-Image-Classification-master\imagenet\images\train\fake\\" + str(id)+".png",img)
elif label == 'real':
cv2.imwrite(r"D:\pypro\Backdoor\DetectModel\YRM\detectmodel\HRNet-Image-Classification-master\imagenet\images\train\real\\" + str(id)+".png",img)
三、HRNet
笔者实现HRNet
的过程是直接参考了以上代码和实现过程,并且可以成功运行。