Coverage for src/bob/bio/face/reports/mobio.py: 0%

54 statements  

« 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 

3 

4from matplotlib.backends.backend_pdf import PdfPages 

5 

6import bob.measure 

7 

8from bob.bio.base.score.load import get_split_dataframe 

9 

10 

11def mobio_report( 

12 scores_dev, 

13 scores_eval, 

14 output_filename, 

15 titles, 

16 fmr_threshold=1e-3, 

17 figsize=(16, 8), 

18 colors=plt.cm.tab10.colors, 

19): 

20 genders = [ 

21 "m", 

22 "f", 

23 ] 

24 gender_labels = ["male", "female"] 

25 

26 # colors = plt.cm.tab20.colors 

27 

28 eval_fmr_fnmr = dict() 

29 

30 for ( 

31 d_scores, 

32 e_scores, 

33 title, 

34 ) in zip(scores_dev, scores_eval, titles): 

35 eval_fmr_fnmr[title] = [] 

36 

37 # Load the score files and fill in the angle associated to each camera 

38 impostors_dev, genuines_dev = get_split_dataframe(d_scores) 

39 impostors_eval, genuines_eval = get_split_dataframe(e_scores) 

40 

41 # loading the dask dataframes 

42 impostors_dev = impostors_dev.compute() 

43 genuines_dev = genuines_dev.compute() 

44 impostors_eval = impostors_eval.compute() 

45 genuines_eval = genuines_eval.compute() 

46 # Computing the threshold combining all distances 

47 # Getting only the close distance to compute the threshold 

48 

49 threshold = bob.measure.far_threshold( 

50 impostors_dev["score"].to_numpy(), 

51 genuines_dev["score"].to_numpy(), 

52 far_value=fmr_threshold, 

53 ) 

54 

55 def compute_fmr_fnmr(impostor_scores, genuine_scores): 

56 eval_fmr, eval_fnmr = bob.measure.farfrr( 

57 impostor_scores["score"].to_numpy(), 

58 genuine_scores["score"].to_numpy(), 

59 threshold, 

60 ) 

61 return eval_fmr, eval_fnmr 

62 

63 # Combined 

64 eval_fmr_fnmr[title].append( 

65 compute_fmr_fnmr(impostors_eval, genuines_eval) 

66 ) 

67 

68 for gender in genders[1:]: 

69 i_eval = impostors_eval.loc[impostors_eval.probe_gender == gender] 

70 g_eval = genuines_eval.loc[genuines_eval.probe_gender == gender] 

71 

72 eval_fmr_fnmr[title].append(compute_fmr_fnmr(i_eval, g_eval)) 

73 

74 pass 

75 

76 # Plotting 

77 pdf = PdfPages(output_filename) 

78 

79 # Figure for eval plot 

80 fig = plt.figure(figsize=figsize) 

81 ax = fig.add_subplot(111) 

82 

83 width = 0.8 / len(titles) 

84 X = np.arange(len(genders)) 

85 

86 for i, (title, color) in enumerate(zip(titles, colors)): 

87 fmrs = [-1 * fmr * 100 for fmr, _ in eval_fmr_fnmr[title]] 

88 fnmrs = [fnmr * 100 for _, fnmr in eval_fmr_fnmr[title]] 

89 

90 x_axis = X + (i + 1) * width - width / 2 

91 ax.bar( 

92 x_axis, 

93 fmrs, 

94 width, 

95 label=title, 

96 color=color, 

97 alpha=0.75, 

98 hatch="\\", 

99 ) 

100 ax.bar(x_axis, fnmrs, width, color=color, alpha=0.5, hatch="/") 

101 

102 # Writting the texts on top of the bar plots 

103 for i, fnmr, fmr in zip(x_axis, fnmrs, fmrs): 

104 plt.text( 

105 i - width / 2, fnmr + 0.8, str(round(fnmr, 2)), fontsize=12 

106 ) 

107 # print(i - width / 2) 

108 plt.text( 

109 i - width / 2, fmr - 2.2, str(round(abs(fmr), 2)), fontsize=12 

110 ) 

111 

112 ax.set_axisbelow(True) 

113 

114 # Plot finalization 

115 plt.title(f"FMR vs FNMR . at Dev. FMR@{fmr_threshold*100}%") 

116 # ax.set_xlabel("Genders", fontsize=18) 

117 ax.set_ylabel("FMR(%) vs FNMR(%) ", fontsize=15) 

118 # plt.ylim([-5, 40]) 

119 

120 ax.set_xticks(X + 0.5) 

121 ax.set_xticklabels(gender_labels, fontsize=14) 

122 

123 yticks = np.array([-5, 0, 5, 15, 25, 35]) 

124 ax.set_yticks(yticks) 

125 ax.set_yticklabels(abs(yticks), fontsize=16) 

126 

127 plt.axhline(0, linestyle="-", color="k") 

128 

129 plt.legend() 

130 plt.grid() 

131 

132 pdf.savefig(fig) 

133 pdf.close()