Coverage for src/bob/bio/face/reports/arface.py: 0%
86 statements
« prev ^ index » next coverage.py v7.6.0, created at 2024-07-13 00:04 +0200
« prev ^ index » next coverage.py v7.6.0, created at 2024-07-13 00:04 +0200
1import matplotlib.pyplot as plt
2import numpy as np
4import bob.measure
6from bob.bio.base.score.load import get_split_dataframe
9def arface_report(
10 scores_dev,
11 scores_eval,
12 output_filename,
13 titles,
14 fmr_threshold=1e-3,
15 figsize=(16, 8),
16 y_abs_max=32, # Max absolute value for y axis
17 colors=plt.cm.tab10.colors,
18):
19 occlusion_illumination = [
20 "illumination",
21 "occlusion",
22 "both",
23 ]
25 occlusions = [
26 "scarf",
27 "sunglasses",
28 ]
30 # style_iterator = _get_colors_markers()
31 # colors = plt.cm.tab20.colors
33 eval_fmr_fnmr_occlusion_illumination = dict()
34 eval_fmr_fnmr_occlusion = dict()
36 for (
37 d_scores,
38 e_scores,
39 title,
40 ) in zip(scores_dev, scores_eval, titles):
41 eval_fmr_fnmr_occlusion_illumination[title] = []
42 eval_fmr_fnmr_occlusion[title] = []
44 # Load the score files and fill in the angle associated to each camera
45 impostors_dev, genuines_dev = get_split_dataframe(d_scores)
46 impostors_eval, genuines_eval = get_split_dataframe(e_scores)
48 # loading the dask dataframes
49 impostors_dev = impostors_dev.compute()
50 genuines_dev = genuines_dev.compute()
51 impostors_eval = impostors_eval.compute()
52 genuines_eval = genuines_eval.compute()
54 # Computing the threshold combining all distances
55 threshold = bob.measure.far_threshold(
56 impostors_dev["score"].to_numpy(),
57 genuines_dev["score"].to_numpy(),
58 fmr_threshold,
59 )
61 def compute_fmr_fnmr(impostor_scores, genuine_scores):
62 eval_fmr, eval_fnmr = bob.measure.farfrr(
63 impostor_scores["score"].to_numpy(),
64 genuine_scores["score"].to_numpy(),
65 threshold,
66 )
67 return eval_fmr, eval_fnmr
69 # EVALUATING OCCLUSION AND ILLUMINATION
71 # All illumination
72 i_eval = impostors_eval.loc[
73 (impostors_eval.probe_illumination != "front")
74 & (impostors_eval.probe_occlusion == "none")
75 ]
76 g_eval = genuines_eval.loc[
77 (genuines_eval.probe_illumination != "front")
78 & (genuines_eval.probe_occlusion == "none")
79 ]
80 eval_fmr_fnmr_occlusion_illumination[title].append(
81 compute_fmr_fnmr(i_eval, g_eval)
82 )
84 # All occlusions
85 i_eval = impostors_eval.loc[
86 (impostors_eval.probe_occlusion != "none")
87 & (impostors_eval.probe_illumination == "front")
88 ]
89 g_eval = genuines_eval.loc[
90 (genuines_eval.probe_occlusion != "none")
91 & (genuines_eval.probe_illumination == "front")
92 ]
93 eval_fmr_fnmr_occlusion_illumination[title].append(
94 compute_fmr_fnmr(i_eval, g_eval)
95 )
97 # BOTH
98 overall_fmr_fnmr = compute_fmr_fnmr(impostors_eval, genuines_eval)
99 eval_fmr_fnmr_occlusion_illumination[title].append(overall_fmr_fnmr)
101 # EVALUATING DIFFERENT TYPES OF OCCLUSION
102 for occlusion in occlusions:
103 i_eval = impostors_eval.loc[
104 impostors_eval.probe_occlusion == occlusion
105 ]
106 g_eval = genuines_eval.loc[
107 genuines_eval.probe_occlusion == occlusion
108 ]
110 eval_fmr_fnmr_occlusion[title].append(
111 compute_fmr_fnmr(i_eval, g_eval)
112 )
114 pass
116 # Plotting
118 #
119 # EFFECT OF OCCLUSION TYPES
121 # Figure for eval plot
122 fig = plt.figure(figsize=figsize)
123 ax = fig.add_subplot(111)
125 width = 0.8 / len(titles)
127 X = np.arange(len(occlusions))
129 for i, (title, color) in enumerate(zip(titles, colors)):
130 fmrs = [-1 * fmr * 100 for fmr, _ in eval_fmr_fnmr_occlusion[title]]
131 fnmrs = [fnmr * 100 for _, fnmr in eval_fmr_fnmr_occlusion[title]]
133 x_axis = X + (i + 1) * width - width / 2
134 ax.bar(
135 x_axis,
136 fmrs,
137 width,
138 label=title,
139 color=color,
140 alpha=1,
141 hatch="\\",
142 )
143 ax.bar(
144 x_axis,
145 fnmrs,
146 width,
147 color=color,
148 alpha=0.5,
149 hatch="/",
150 )
152 # Writting the texts on top of the bar plots
153 for i, fnmr, fmr in zip(x_axis, fnmrs, fmrs):
154 plt.text(
155 i - width / 2, fnmr + 0.5, str(round(fnmr, 1)), fontsize=15
156 )
157 plt.text(
158 i - width / 2, fmr - 2.3, str(round(abs(fmr), 1)), fontsize=15
159 )
161 # Plot finalization
162 plt.title(f"FMR vs FNMR. at Dev. FMR@{fmr_threshold*100}%", fontsize=16)
163 ax.set_xlabel("Occlusion types", fontsize=14)
164 ax.set_ylabel("FMR(%) vs FNMR(%) ", fontsize=18)
166 ax.set_xticks(X + 0.5)
167 ax.set_xticklabels(occlusions, fontsize=14)
169 yticks = np.array(
170 [
171 -y_abs_max / 4,
172 0,
173 y_abs_max / 4,
174 y_abs_max / 2,
175 y_abs_max,
176 ]
177 )
179 ax.set_yticks(yticks)
180 ax.set_yticklabels([abs(int(y)) for y in yticks], fontsize=16)
182 plt.axhline(0, linestyle="-", color="k")
183 plt.ylim([-y_abs_max / 4, y_abs_max + 1])
185 plt.legend()
186 plt.grid()
188 plt.savefig(fig)
190 # EFFECT OF ILLUMINATION AND OCCLUSION
192 # Figure for eval plot
193 fig = plt.figure(figsize=figsize)
194 ax = fig.add_subplot(111)
196 X = np.arange(len(occlusion_illumination))
198 for i, (title, color) in enumerate(zip(titles, colors)):
199 fmrs = [
200 -1 * fmr * 100
201 for fmr, _ in eval_fmr_fnmr_occlusion_illumination[title]
202 ]
203 fnmrs = [
204 fnmr * 100
205 for _, fnmr in eval_fmr_fnmr_occlusion_illumination[title]
206 ]
208 x_axis = X + (i + 1) * width - width / 2
209 ax.bar(
210 x_axis,
211 fmrs,
212 width,
213 label=title,
214 color=color,
215 alpha=1,
216 hatch="\\",
217 )
218 ax.bar(
219 x_axis,
220 fnmrs,
221 width,
222 color=color,
223 alpha=0.5,
224 hatch="/",
225 )
226 # Writting the texts on top of the bar plots
227 for i, fnmr, fmr in zip(x_axis, fnmrs, fmrs):
228 plt.text(
229 i - width / 2,
230 fnmr + 0.4,
231 str(int(fnmr)) if fnmr == 0 else str(round(fnmr, 1)),
232 fontsize=15,
233 )
234 plt.text(
235 i - width / 2,
236 fmr - 0.9,
237 str(int(fmr)),
238 fontsize=15,
239 )
241 plt.title(f"FMR vs FNMR. at Dev. FMR@{fmr_threshold*100}%", fontsize=16)
242 ax.set_xlabel("Occlusion and illumination", fontsize=14)
243 ax.set_ylabel("FMR(%) vs FNMR(%) ", fontsize=18)
245 ax.set_xticks(X + 0.5)
246 ax.set_xticklabels(occlusion_illumination, fontsize=14)
248 yticks = np.array([-y_abs_max / 4, 0, y_abs_max / 4, y_abs_max / 2])
249 ax.set_yticks(yticks)
250 ax.set_yticklabels([abs(int(y)) for y in yticks], fontsize=16)
252 plt.axhline(0, linestyle="-", color="k")
253 plt.ylim([-y_abs_max / 4, y_abs_max / 2])
255 plt.legend()
256 plt.grid()
257 plt.savefig(fig)