-
Notifications
You must be signed in to change notification settings - Fork 3
/
negative_face_recognition.py
92 lines (75 loc) · 3.22 KB
/
negative_face_recognition.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# Implementation of the Negative Face Recognition approach to
# enhance privacy of face recognition
#
# For further information please refer to:
# "Unsupervised Enhancement of Soft-biometric Privacy with Negative Face Recognition" by
# Philipp Terhörst, Marco Huber, Naser Damer, Florian Kirchbuchner and Arjan Kuijper (2020)
#
import random
import numpy as np
from sklearn.preprocessing import KBinsDiscretizer, StandardScaler
class NegativeFaceRecognition:
def __transform_random(self, features, bins):
""" transform the given discrete vectors into a new random representation.
No discrete value is retained.
features: array (n_samples, n_features)
bins: number of bins/discrete values
"""
neg_templates = []
for template in features:
neg_t = []
for f in template:
bin_space = [x for x in list(range(0,bins)) if x != f]
f = random.choice(bin_space)
neg_t.append(f)
neg_templates.append(neg_t)
return np.asarray(neg_templates, dtype=int)
def get_positive_template(self, features, bins):
""" Returns the generated positive template
features: array (n_samples, n_features)
bins: number of bins/discrete values
"""
scaled_features = self.__scale(features)
positive_template = self.__discretize(scaled_features, bins)
return positive_template.astype(int)
def get_negative_template(self, features, bins):
""" Returns the generated negative template
features: array (n_samples, n_features)
bins: number of bins/discrete values
"""
scaled_features = self.__scale(features)
positive_template = self.__discretize(scaled_features, bins)
negative_template = self.__transform_random(positive_template, bins)
return negative_template
def pn_comparison_score(self, pos, neg):
""" positive-negative comparison score:
calculates and returns the dissimilarity between a positive
and a negative template that acts as a comparison score
pos: positive template
neg: negative template
"""
parity = neg == pos
parity_score = 0
unique, counts = np.unique(parity, return_counts=True)
for i in range(0,len(unique)):
if unique[i] == True:
parity_score = counts[i]
sim = 1 - (parity_score/parity.size)
return sim
def __scale(self, features):
"""
standardize features by removing the mean and scaling to unit variance
features: array (n_samples, n_features)
"""
scaler = StandardScaler()
features = scaler.fit_transform(features)
return features
def __discretize(self, features, bins):
"""
discretize the given features into bins intervals.
features: array (n_samples, n_features)
bins: number of bins/discrete values
"""
discretizer = KBinsDiscretizer(n_bins=bins, encode='ordinal', strategy='quantile')
discrete_features = discretizer.fit_transform(features)
return discrete_features