Coverage for src/bob/pad/face/database/mask_attack.py: 80%

46 statements  

« prev     ^ index     » next       coverage.py v7.6.0, created at 2024-07-13 01:19 +0200

1import logging 

2import os 

3 

4from functools import partial 

5 

6import h5py 

7import numpy as np 

8 

9from clapper.rc import UserDefaults 

10from sklearn.preprocessing import FunctionTransformer 

11 

12from bob.bio.base.database.utils import download_file 

13from bob.bio.video import VideoLikeContainer, select_frames 

14from bob.pad.base.database import FileListPadDatabase 

15from bob.pipelines import DelayedSample 

16 

17logger = logging.getLogger(__name__) 

18rc = UserDefaults("bobrc.toml") 

19 

20 

21def load_frames_from_hdf5( 

22 hdf5_file, 

23 key="Color_Data", 

24 selection_style=None, 

25 max_number_of_frames=None, 

26 step_size=None, 

27): 

28 with h5py.File(hdf5_file) as f: 

29 video = f[key][()] 

30 # reduce the shape of depth from (N, C, H, W) to (N, H, W) since H == 1 

31 video = np.squeeze(video) 

32 

33 indices = select_frames( 

34 len(video), 

35 max_number_of_frames=max_number_of_frames, 

36 selection_style=selection_style, 

37 step_size=step_size, 

38 ) 

39 data = VideoLikeContainer(video[indices], indices) 

40 

41 return data 

42 

43 

44def load_annotations_from_hdf5( 

45 hdf5_file, 

46): 

47 with h5py.File(hdf5_file) as f: 

48 eye_pos = f["Eye_Pos"][()] 

49 

50 annotations = { 

51 str(i): { 

52 "reye": [row[1], row[0]], 

53 "leye": [row[3], row[2]], 

54 } 

55 for i, row in enumerate(eye_pos) 

56 } 

57 return annotations 

58 

59 

60def delayed_maskattack_video_load( 

61 samples, 

62 original_directory, 

63 selection_style=None, 

64 max_number_of_frames=None, 

65 step_size=None, 

66): 

67 original_directory = original_directory or "" 

68 results = [] 

69 for sample in samples: 

70 hdf5_file = os.path.join(original_directory, sample.filename) 

71 data = partial( 

72 load_frames_from_hdf5, 

73 key="Color_Data", 

74 hdf5_file=hdf5_file, 

75 selection_style=selection_style, 

76 max_number_of_frames=max_number_of_frames, 

77 step_size=step_size, 

78 ) 

79 depth = partial( 

80 load_frames_from_hdf5, 

81 key="Depth_Data", 

82 hdf5_file=hdf5_file, 

83 selection_style=selection_style, 

84 max_number_of_frames=max_number_of_frames, 

85 step_size=step_size, 

86 ) 

87 annotations = partial( 

88 load_annotations_from_hdf5, 

89 hdf5_file=hdf5_file, 

90 ) 

91 delayed_attributes = { 

92 "annotations": annotations, 

93 "depth": depth, 

94 } 

95 

96 results.append( 

97 DelayedSample( 

98 data, 

99 parent=sample, 

100 delayed_attributes=delayed_attributes, 

101 ) 

102 ) 

103 return results 

104 

105 

106def MaskAttackPadSample( 

107 original_directory, 

108 selection_style=None, 

109 max_number_of_frames=None, 

110 step_size=None, 

111): 

112 return FunctionTransformer( 

113 delayed_maskattack_video_load, 

114 validate=False, 

115 kw_args=dict( 

116 original_directory=original_directory, 

117 selection_style=selection_style, 

118 max_number_of_frames=max_number_of_frames, 

119 step_size=step_size, 

120 ), 

121 ) 

122 

123 

124def MaskAttackPadDatabase( 

125 protocol="classification", 

126 selection_style=None, 

127 max_number_of_frames=None, 

128 step_size=None, 

129 **kwargs, 

130): 

131 name = "pad-face-mask-attack-6d8854c2.tar.gz" 

132 dataset_protocols_path = download_file( 

133 urls=[f"http://www.idiap.ch/software/bob/data/bob/bob.pad.face/{name}"], 

134 destination_filename=name, 

135 destination_sub_directory="protocols/pad", 

136 checksum="6d8854c2", 

137 ) 

138 

139 transformer = MaskAttackPadSample( 

140 original_directory=rc.get("bob.db.mask_attack.directory"), 

141 selection_style=selection_style, 

142 max_number_of_frames=max_number_of_frames, 

143 step_size=step_size, 

144 ) 

145 

146 database = FileListPadDatabase( 

147 name="mask-attack", 

148 dataset_protocols_path=dataset_protocols_path, 

149 protocol=protocol, 

150 transformer=transformer, 

151 **kwargs, 

152 ) 

153 database.annotation_type = "eyes-center" 

154 database.fixed_positions = None 

155 return database