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
« 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
6"""Visualizes a particular sample throughout many processing stages
8Usage: %(prog)s [-v...] [-s <path>] <database> <processed> <stem> [<stem>...]
9 %(prog)s --help
10 %(prog)s --version
13Arguments:
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
24Options:
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
33Examples:
35 Visualize the processing toolchain over a single image of VERA finger vein:
37 $ %(prog)s verafinger /mc client/sample
39 Visualize multiple masks (like in a proof-sheet):
41 $ %(prog)s verafinger /mc client/sample1 client/sample2
43"""
46import os
47import sys
49import clapper.logging
50import docopt
51import h5py
52import numpy
53import schema
55logger = clapper.logging.setup("bob.bio.vein")
57import matplotlib.pyplot as mpl
59import bob.io.base
61from ..preprocessor import utils
64def save_figures(title, image, mask, image_pp, binary):
65 """Saves individual images on a directory
68 Parameters:
70 title (str): A title for this plot
72 image (numpy.ndarray): The original image representing the finger vein (2D
73 array with dtype = ``uint8``)
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``).
79 image_pp (numpy.ndarray): A version of the original image, pre-processed by
80 one of the available algorithms
82 binary (numpy.ndarray): A binarized version of the original image in which
83 all pixels (should) represent vein (``True``) or not-vein (``False``)
85 """
87 os.makedirs(title)
88 bob.io.base.save(image, os.path.join(title, "original.png"))
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"))
95 # add binary image
96 bob.io.base.save(
97 binary.astype("uint8") * 255, os.path.join(title, "binarized.png")
98 )
101def proof_figure(title, image, mask, image_pp, binary=None):
102 """Builds a proof canvas out of individual images
105 Parameters:
107 title (str): A title for this plot
109 image (numpy.ndarray): The original image representing the finger vein (2D
110 array with dtype = ``uint8``)
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``).
116 image_pp (numpy.ndarray): A version of the original image, pre-processed by
117 one of the available algorithms
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``)
124 Returns:
126 matplotlib.pyplot.Figure: A figure canvas containing the proof for the
127 particular sample on the database
129 """
131 fig = mpl.figure(figsize=(6, 9), dpi=100)
133 images = 3 if binary is not None else 2
135 # add original image
136 mpl.subplot(images, 1, 1)
137 mpl.title("%s - original" % title)
138 mpl.imshow(image, cmap="gray")
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)
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")
152 return fig
155def validate(args):
156 """Validates command-line arguments, returns parsed values
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.
164 Parameters:
166 args (dict): Dictionary of arguments as defined by the help message and
167 returned by :py:mod:`docopt`
170 Returns
172 dict: Validate dictionary with the same keys as the input and with values
173 possibly transformed by the validation procedure
176 Raises:
178 schema.SchemaError: in case one of the checked options does not validate.
180 """
182 valid_databases = ("fv3d", "verafinger")
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 )
196 return sch.validate(args)
199def main(user_input=None):
200 if user_input is not None:
201 argv = user_input
202 else:
203 argv = sys.argv[1:]
205 import pkg_resources
207 completions = dict(
208 prog=os.path.basename(sys.argv[0]),
209 version=pkg_resources.require("bob.bio.vein")[0].version,
210 )
212 args = docopt.docopt(
213 __doc__ % completions,
214 argv=argv,
215 version=completions["version"],
216 )
218 try:
219 from .validate import setup_logger
221 setup_logger("bob.bio.vein", args["--verbose"])
222 args = validate(args)
223 except schema.SchemaError as e:
224 sys.exit(e)
226 raise NotImplementedError("Supported databases are not implemented yet")
227 db = args["<database>"]
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
234 database_replacement = "%s/.bob_bio_databases.txt" % os.environ["HOME"]
235 db.replace_directories(database_replacement)
236 all_files = db.objects()
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...")