2020-07-02 23:02:05 +05:30
|
|
|
# from __future__ import absolute_import
|
|
|
|
# from __future__ import division
|
|
|
|
# from __future__ import print_function
|
|
|
|
|
2020-05-18 05:48:41 +05:30
|
|
|
import argparse
|
2020-06-29 05:43:14 +05:30
|
|
|
import glob
|
2020-07-09 11:56:42 +05:30
|
|
|
import logging
|
2020-05-18 05:48:41 +05:30
|
|
|
import os
|
2020-05-19 02:05:14 +05:30
|
|
|
import sys
|
2020-07-09 11:56:42 +05:30
|
|
|
|
2020-07-07 21:44:38 +05:30
|
|
|
import tensorflow as tf
|
2020-07-09 11:56:42 +05:30
|
|
|
|
2020-07-07 21:44:38 +05:30
|
|
|
logging.getLogger('tensorflow').disabled = True
|
2020-05-19 02:05:14 +05:30
|
|
|
|
|
|
|
import numpy as np
|
2020-07-07 21:44:38 +05:30
|
|
|
from fawkes.differentiator import FawkesMaskGeneration
|
|
|
|
from fawkes.utils import load_extractor, init_gpu, select_target_label, dump_image, reverse_process_cloaked, \
|
2020-07-20 07:24:04 +05:30
|
|
|
Faces, filter_image_paths
|
|
|
|
|
2020-07-12 04:42:32 +05:30
|
|
|
from fawkes.align_face import aligner
|
2020-07-17 00:09:50 +05:30
|
|
|
from fawkes.utils import get_file
|
2020-07-20 07:24:04 +05:30
|
|
|
|
2020-05-18 05:48:41 +05:30
|
|
|
|
2020-07-23 23:24:07 +05:30
|
|
|
def generate_cloak_images(protector, image_X, target_emb=None):
|
|
|
|
cloaked_image_X = protector.attack(image_X, target_emb)
|
2020-05-18 05:48:41 +05:30
|
|
|
return cloaked_image_X
|
|
|
|
|
|
|
|
|
2020-07-02 07:46:03 +05:30
|
|
|
def check_imgs(imgs):
|
|
|
|
if np.max(imgs) <= 1 and np.min(imgs) >= 0:
|
|
|
|
imgs = imgs * 255.0
|
|
|
|
elif np.max(imgs) <= 255 and np.min(imgs) >= 0:
|
|
|
|
pass
|
|
|
|
else:
|
|
|
|
raise Exception("Image values ")
|
|
|
|
return imgs
|
2020-05-18 05:48:41 +05:30
|
|
|
|
2020-05-19 02:05:14 +05:30
|
|
|
|
2020-07-09 11:56:42 +05:30
|
|
|
class Fawkes(object):
|
|
|
|
def __init__(self, feature_extractor, gpu, batch_size):
|
2020-07-12 04:42:32 +05:30
|
|
|
|
2020-07-09 11:56:42 +05:30
|
|
|
self.feature_extractor = feature_extractor
|
|
|
|
self.gpu = gpu
|
|
|
|
self.batch_size = batch_size
|
2020-07-20 07:24:04 +05:30
|
|
|
global sess
|
|
|
|
sess = init_gpu(gpu)
|
|
|
|
global graph
|
|
|
|
graph = tf.get_default_graph()
|
2020-07-17 00:09:50 +05:30
|
|
|
|
|
|
|
model_dir = os.path.join(os.path.expanduser('~'), '.fawkes')
|
|
|
|
if not os.path.exists(os.path.join(model_dir, "mtcnn.p.gz")):
|
|
|
|
os.makedirs(model_dir, exist_ok=True)
|
|
|
|
get_file("mtcnn.p.gz", "http://sandlab.cs.uchicago.edu/fawkes/files/mtcnn.p.gz", cache_dir=model_dir,
|
|
|
|
cache_subdir='')
|
|
|
|
|
2020-07-09 11:56:42 +05:30
|
|
|
self.fs_names = [feature_extractor]
|
|
|
|
if isinstance(feature_extractor, list):
|
|
|
|
self.fs_names = feature_extractor
|
|
|
|
|
2020-07-20 07:24:04 +05:30
|
|
|
self.aligner = aligner(sess)
|
2020-07-09 11:56:42 +05:30
|
|
|
self.feature_extractors_ls = [load_extractor(name) for name in self.fs_names]
|
|
|
|
|
2020-07-23 23:24:07 +05:30
|
|
|
self.protector = None
|
|
|
|
self.protector_param = None
|
|
|
|
|
2020-07-09 11:56:42 +05:30
|
|
|
def mode2param(self, mode):
|
|
|
|
if mode == 'low':
|
|
|
|
th = 0.003
|
2020-07-12 04:42:32 +05:30
|
|
|
max_step = 50
|
2020-07-09 11:56:42 +05:30
|
|
|
lr = 20
|
|
|
|
elif mode == 'mid':
|
|
|
|
th = 0.005
|
2020-07-23 23:24:07 +05:30
|
|
|
max_step = 120
|
|
|
|
lr = 15
|
2020-07-09 11:56:42 +05:30
|
|
|
elif mode == 'high':
|
|
|
|
th = 0.008
|
2020-07-23 23:24:07 +05:30
|
|
|
max_step = 600
|
|
|
|
lr = 10
|
2020-07-09 11:56:42 +05:30
|
|
|
elif mode == 'ultra':
|
|
|
|
if not tf.test.is_gpu_available():
|
|
|
|
print("Please enable GPU for ultra setting...")
|
|
|
|
sys.exit(1)
|
|
|
|
th = 0.01
|
2020-07-24 21:41:42 +05:30
|
|
|
max_step = 1000
|
|
|
|
lr = 10
|
2020-07-09 11:56:42 +05:30
|
|
|
else:
|
|
|
|
raise Exception("mode must be one of 'low', 'mid', 'high', 'ultra', 'custom'")
|
|
|
|
return th, max_step, lr
|
|
|
|
|
2020-07-23 23:24:07 +05:30
|
|
|
def run_protection(self, image_paths, mode='low', th=0.04, sd=1e9, lr=10, max_step=500, batch_size=1, format='png',
|
2020-07-20 07:24:04 +05:30
|
|
|
separate_target=True, debug=False):
|
|
|
|
|
2020-07-09 11:56:42 +05:30
|
|
|
if mode == 'custom':
|
|
|
|
pass
|
|
|
|
else:
|
|
|
|
th, max_step, lr = self.mode2param(mode)
|
|
|
|
|
2020-07-23 23:24:07 +05:30
|
|
|
current_param = "-".join([str(x) for x in [mode, th, sd, lr, max_step, batch_size, format,
|
|
|
|
separate_target, debug]])
|
|
|
|
|
2020-07-20 07:24:04 +05:30
|
|
|
image_paths, loaded_images = filter_image_paths(image_paths)
|
|
|
|
|
2020-07-09 11:56:42 +05:30
|
|
|
if not image_paths:
|
|
|
|
raise Exception("No images in the directory")
|
2020-07-12 04:42:32 +05:30
|
|
|
with graph.as_default():
|
2020-07-20 07:24:04 +05:30
|
|
|
faces = Faces(image_paths, loaded_images, self.aligner, verbose=1)
|
2020-07-12 04:42:32 +05:30
|
|
|
|
|
|
|
original_images = faces.cropped_faces
|
|
|
|
original_images = np.array(original_images)
|
|
|
|
|
2020-07-20 07:24:04 +05:30
|
|
|
with sess.as_default():
|
|
|
|
if separate_target:
|
|
|
|
target_embedding = []
|
|
|
|
for org_img in original_images:
|
|
|
|
org_img = org_img.reshape([1] + list(org_img.shape))
|
|
|
|
tar_emb = select_target_label(org_img, self.feature_extractors_ls, self.fs_names)
|
|
|
|
target_embedding.append(tar_emb)
|
|
|
|
target_embedding = np.concatenate(target_embedding)
|
|
|
|
else:
|
|
|
|
target_embedding = select_target_label(original_images, self.feature_extractors_ls, self.fs_names)
|
2020-07-12 04:42:32 +05:30
|
|
|
|
2020-07-23 23:24:07 +05:30
|
|
|
if current_param != self.protector_param:
|
|
|
|
self.protector_param = current_param
|
|
|
|
|
|
|
|
if self.protector is not None:
|
|
|
|
del self.protector
|
|
|
|
|
|
|
|
self.protector = FawkesMaskGeneration(sess, self.feature_extractors_ls,
|
|
|
|
batch_size=batch_size,
|
|
|
|
mimic_img=True,
|
|
|
|
intensity_range='imagenet',
|
|
|
|
initial_const=sd,
|
|
|
|
learning_rate=lr,
|
|
|
|
max_iterations=max_step,
|
|
|
|
l_threshold=th,
|
|
|
|
verbose=1 if debug else 0,
|
|
|
|
maximize=False,
|
|
|
|
keep_final=False,
|
|
|
|
image_shape=(224, 224, 3))
|
|
|
|
|
|
|
|
protected_images = generate_cloak_images(self.protector, original_images,
|
|
|
|
target_emb=target_embedding)
|
2020-07-12 04:42:32 +05:30
|
|
|
|
2020-07-20 07:24:04 +05:30
|
|
|
faces.cloaked_cropped_faces = protected_images
|
2020-07-12 04:42:32 +05:30
|
|
|
|
2020-07-20 07:24:04 +05:30
|
|
|
cloak_perturbation = reverse_process_cloaked(protected_images) - reverse_process_cloaked(
|
|
|
|
original_images)
|
|
|
|
final_images = faces.merge_faces(cloak_perturbation)
|
2020-07-12 04:42:32 +05:30
|
|
|
|
2020-07-20 07:24:04 +05:30
|
|
|
for p_img, path in zip(final_images, image_paths):
|
|
|
|
file_name = "{}_{}_cloaked.{}".format(".".join(path.split(".")[:-1]), mode, format)
|
|
|
|
dump_image(p_img, file_name, format=format)
|
2020-07-23 23:24:07 +05:30
|
|
|
|
2020-07-20 07:24:04 +05:30
|
|
|
print("Done!")
|
|
|
|
return None
|
2020-07-09 11:56:42 +05:30
|
|
|
|
|
|
|
|
2020-07-02 23:02:05 +05:30
|
|
|
def main(*argv):
|
|
|
|
if not argv:
|
|
|
|
argv = list(sys.argv)
|
|
|
|
|
2020-07-07 03:22:46 +05:30
|
|
|
try:
|
2020-07-02 23:02:05 +05:30
|
|
|
import signal
|
|
|
|
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
|
|
|
|
except Exception as e:
|
|
|
|
pass
|
|
|
|
|
|
|
|
parser = argparse.ArgumentParser()
|
|
|
|
parser.add_argument('--directory', '-d', type=str,
|
|
|
|
help='directory that contain images for cloaking', default='imgs/')
|
|
|
|
|
2020-07-07 21:44:38 +05:30
|
|
|
parser.add_argument('--gpu', '-g', type=str,
|
2020-07-02 23:02:05 +05:30
|
|
|
help='GPU id', default='0')
|
|
|
|
|
2020-07-07 21:44:38 +05:30
|
|
|
parser.add_argument('--mode', '-m', type=str,
|
2020-07-09 09:40:13 +05:30
|
|
|
help='cloak generation mode', default='low')
|
2020-07-02 23:02:05 +05:30
|
|
|
parser.add_argument('--feature-extractor', type=str,
|
|
|
|
help="name of the feature extractor used for optimization",
|
|
|
|
default="high_extract")
|
|
|
|
|
|
|
|
parser.add_argument('--th', type=float, default=0.01)
|
2020-07-24 21:41:42 +05:30
|
|
|
parser.add_argument('--max-step', type=int, default=1000)
|
2020-07-02 23:02:05 +05:30
|
|
|
parser.add_argument('--sd', type=int, default=1e9)
|
|
|
|
parser.add_argument('--lr', type=float, default=2)
|
|
|
|
|
2020-07-07 03:22:46 +05:30
|
|
|
parser.add_argument('--batch-size', type=int, default=1)
|
2020-07-02 23:02:05 +05:30
|
|
|
parser.add_argument('--separate_target', action='store_true')
|
2020-07-20 07:24:04 +05:30
|
|
|
parser.add_argument('--debug', action='store_true')
|
2020-07-02 23:02:05 +05:30
|
|
|
|
|
|
|
parser.add_argument('--format', type=str,
|
|
|
|
help="final image format",
|
2020-07-07 03:22:46 +05:30
|
|
|
default="png")
|
2020-07-02 23:02:05 +05:30
|
|
|
|
2020-07-09 11:56:42 +05:30
|
|
|
args = parser.parse_args(argv[1:])
|
2020-07-02 23:02:05 +05:30
|
|
|
|
2020-07-02 07:46:03 +05:30
|
|
|
assert args.format in ['png', 'jpg', 'jpeg']
|
|
|
|
if args.format == 'jpg':
|
|
|
|
args.format = 'jpeg'
|
2020-06-29 05:43:14 +05:30
|
|
|
|
|
|
|
image_paths = glob.glob(os.path.join(args.directory, "*"))
|
|
|
|
image_paths = [path for path in image_paths if "_cloaked" not in path.split("/")[-1]]
|
2020-05-18 05:48:41 +05:30
|
|
|
|
2020-07-09 11:56:42 +05:30
|
|
|
protector = Fawkes(args.feature_extractor, args.gpu, args.batch_size)
|
|
|
|
protector.run_protection(image_paths, mode=args.mode, th=args.th, sd=args.sd, lr=args.lr, max_step=args.max_step,
|
|
|
|
batch_size=args.batch_size, format=args.format,
|
2020-07-20 07:24:04 +05:30
|
|
|
separate_target=args.separate_target, debug=args.debug)
|
2020-07-07 03:22:46 +05:30
|
|
|
|
2020-05-18 05:48:41 +05:30
|
|
|
|
|
|
|
if __name__ == '__main__':
|
2020-07-02 23:02:05 +05:30
|
|
|
main(*sys.argv)
|