Coverage for src/bob/bio/vein/script/view_sample.py: 0%

51 statements  

« prev     ^ index     » next       coverage.py v7.6.0, created at 2024-07-12 23:27 +0200

1#!/usr/bin/env python 

2# vim: set fileencoding=utf-8 : 

3# Mon 07 Nov 2016 15:20:26 CET 

4 

5 

6"""Visualizes a particular sample throughout many processing stages 

7 

8Usage: %(prog)s [-v...] [-s <path>] <database> <processed> <stem> [<stem>...] 

9 %(prog)s --help 

10 %(prog)s --version 

11 

12 

13Arguments: 

14 

15 <database> Name of the database to use for creating the model (options are: 

16 "fv3d" or "verafinger") 

17 <processed> Path with the directory holding the preprocessed and extracted 

18 sub-directories containing the processing results of a 

19 bob.bio.vein toolchain 

20 <stem> Name of the object on the database to display, without the root 

21 or the extension 

22 

23 

24Options: 

25 

26 -h, --help Shows this help message and exits 

27 -V, --version Prints the version and exits 

28 -v, --verbose Increases the output verbosity level 

29 -s <path>, --save=<path> If set, saves image into a file instead of 

30 displaying it 

31 

32 

33Examples: 

34 

35 Visualize the processing toolchain over a single image of VERA finger vein: 

36 

37 $ %(prog)s verafinger /mc client/sample 

38 

39 Visualize multiple masks (like in a proof-sheet): 

40 

41 $ %(prog)s verafinger /mc client/sample1 client/sample2 

42 

43""" 

44 

45 

46import os 

47import sys 

48 

49import clapper.logging 

50import docopt 

51import h5py 

52import numpy 

53import schema 

54 

55logger = clapper.logging.setup("bob.bio.vein") 

56 

57import matplotlib.pyplot as mpl 

58 

59import bob.io.base 

60 

61from ..preprocessor import utils 

62 

63 

64def save_figures(title, image, mask, image_pp, binary): 

65 """Saves individual images on a directory 

66 

67 

68 Parameters: 

69 

70 title (str): A title for this plot 

71 

72 image (numpy.ndarray): The original image representing the finger vein (2D 

73 array with dtype = ``uint8``) 

74 

75 mask (numpy.ndarray): A 2D boolean array with the same size of the original 

76 image containing the pixels in which the image is valid (``True``) or 

77 invalid (``False``). 

78 

79 image_pp (numpy.ndarray): A version of the original image, pre-processed by 

80 one of the available algorithms 

81 

82 binary (numpy.ndarray): A binarized version of the original image in which 

83 all pixels (should) represent vein (``True``) or not-vein (``False``) 

84 

85 """ 

86 

87 os.makedirs(title) 

88 bob.io.base.save(image, os.path.join(title, "original.png")) 

89 

90 # add preprocessed image 

91 img = utils.draw_mask_over_image(image_pp, mask) 

92 img = numpy.array(img).transpose(2, 0, 1) 

93 bob.io.base.save(img[:3], os.path.join(title, "preprocessed.png")) 

94 

95 # add binary image 

96 bob.io.base.save( 

97 binary.astype("uint8") * 255, os.path.join(title, "binarized.png") 

98 ) 

99 

100 

101def proof_figure(title, image, mask, image_pp, binary=None): 

102 """Builds a proof canvas out of individual images 

103 

104 

105 Parameters: 

106 

107 title (str): A title for this plot 

108 

109 image (numpy.ndarray): The original image representing the finger vein (2D 

110 array with dtype = ``uint8``) 

111 

112 mask (numpy.ndarray): A 2D boolean array with the same size of the original 

113 image containing the pixels in which the image is valid (``True``) or 

114 invalid (``False``). 

115 

116 image_pp (numpy.ndarray): A version of the original image, pre-processed by 

117 one of the available algorithms 

118 

119 binary (numpy.ndarray, Optional): A binarized version of the original image 

120 in which all pixels (should) represent vein (``True``) or not-vein 

121 (``False``) 

122 

123 

124 Returns: 

125 

126 matplotlib.pyplot.Figure: A figure canvas containing the proof for the 

127 particular sample on the database 

128 

129 """ 

130 

131 fig = mpl.figure(figsize=(6, 9), dpi=100) 

132 

133 images = 3 if binary is not None else 2 

134 

135 # add original image 

136 mpl.subplot(images, 1, 1) 

137 mpl.title("%s - original" % title) 

138 mpl.imshow(image, cmap="gray") 

139 

140 # add preprocessed image 

141 img = utils.draw_mask_over_image(image_pp, mask) 

142 mpl.subplot(images, 1, 2) 

143 mpl.title("Preprocessed") 

144 mpl.imshow(img) 

145 

146 if binary is not None: 

147 # add binary image 

148 mpl.subplot(3, 1, 3) 

149 mpl.title("Binarized") 

150 mpl.imshow(binary.astype("uint8") * 255, cmap="gray") 

151 

152 return fig 

153 

154 

155def validate(args): 

156 """Validates command-line arguments, returns parsed values 

157 

158 This function uses :py:mod:`schema` for validating :py:mod:`docopt` 

159 arguments. Logging level is not checked by this procedure (actually, it is 

160 ignored) and must be previously setup as some of the elements here may use 

161 logging for outputing information. 

162 

163 

164 Parameters: 

165 

166 args (dict): Dictionary of arguments as defined by the help message and 

167 returned by :py:mod:`docopt` 

168 

169 

170 Returns 

171 

172 dict: Validate dictionary with the same keys as the input and with values 

173 possibly transformed by the validation procedure 

174 

175 

176 Raises: 

177 

178 schema.SchemaError: in case one of the checked options does not validate. 

179 

180 """ 

181 

182 valid_databases = ("fv3d", "verafinger") 

183 

184 sch = schema.Schema( 

185 { 

186 "<database>": schema.And( 

187 lambda n: n in valid_databases, 

188 error="<database> must be one of %s" 

189 % ", ".join(valid_databases), 

190 ), 

191 str: object, # ignores strings we don't care about 

192 }, 

193 ignore_extra_keys=True, 

194 ) 

195 

196 return sch.validate(args) 

197 

198 

199def main(user_input=None): 

200 if user_input is not None: 

201 argv = user_input 

202 else: 

203 argv = sys.argv[1:] 

204 

205 import pkg_resources 

206 

207 completions = dict( 

208 prog=os.path.basename(sys.argv[0]), 

209 version=pkg_resources.require("bob.bio.vein")[0].version, 

210 ) 

211 

212 args = docopt.docopt( 

213 __doc__ % completions, 

214 argv=argv, 

215 version=completions["version"], 

216 ) 

217 

218 try: 

219 from .validate import setup_logger 

220 

221 setup_logger("bob.bio.vein", args["--verbose"]) 

222 args = validate(args) 

223 except schema.SchemaError as e: 

224 sys.exit(e) 

225 

226 raise NotImplementedError("Supported databases are not implemented yet") 

227 db = args["<database>"] 

228 

229 # if args["<database>"] == "fv3d": 

230 # from bob.bio.vein.config.fv3d import database as db 

231 # elif args["<database>"] == "verafinger": 

232 # from bob.bio.vein.config.verafinger import database as db 

233 

234 database_replacement = "%s/.bob_bio_databases.txt" % os.environ["HOME"] 

235 db.replace_directories(database_replacement) 

236 all_files = db.objects() 

237 

238 # Loads the image, the mask and save it to a PNG file 

239 for stem in args["<stem>"]: 

240 f = [k for k in all_files if k.path == stem] 

241 if len(f) == 0: 

242 raise RuntimeError( 

243 'File with stem "%s" does not exist on "%s"' 

244 % (stem, args["<database>"]) 

245 ) 

246 f = f[0] 

247 image = f.load(db.original_directory, db.original_extension) 

248 pp_name = f.make_path( 

249 os.path.join(args["<processed>"], "preprocessed"), extension=".hdf5" 

250 ) 

251 pp = h5py.File(pp_name) 

252 mask = pp.read("mask") 

253 image_pp = pp.read("image") 

254 try: 

255 binary = f.load(os.path.join(args["<processed>"], "extracted")) 

256 binary = numpy.rot90(binary, k=1) 

257 except Exception: 

258 binary = None 

259 proof_figure(stem, image, mask, image_pp, binary) 

260 if args["--save"]: 

261 save_figures(args["--save"], image, mask, image_pp, binary) 

262 else: 

263 mpl.show() 

264 print("Close window to continue...")