plot_cmc.py 3.95 KB
Newer Older
André Anjos's avatar
André Anjos committed
1 2
#!/usr/bin/env python
# vim: set fileencoding=utf-8 :
3
# Wed 28 Sep 2016 21:24:46 CEST
André Anjos's avatar
André Anjos committed
4

5
"""Computes and plots a cumulative rank characteristics (CMC) curve
6

7 8 9
Usage: %(prog)s [-v...] [options] <scores>
       %(prog)s --help
       %(prog)s --version
André Anjos's avatar
André Anjos committed
10

11
Arguments:
André Anjos's avatar
André Anjos committed
12

13
  <scores>  The score file in 4 or 5 column format to test
André Anjos's avatar
André Anjos committed
14 15


16
Options:
André Anjos's avatar
André Anjos committed
17

18 19 20 21 22 23 24 25 26
  -h, --help                  Shows this help message and exits
  -V, --version               Prints the version and exits
  -v, --verbose               Increases the output verbosity level
  -o <path>, --output=<path>  Name of the output file that will contain the
                              plots [default: cmc.pdf]
  -x, --no-plot               If set, then I'll execute no plotting
  -l, --log-x-scale           If set, plots logarithmic rank axis
  -r <int>, --rank=<int>      Plot detection & identification rate curve for
                              the given rank instead of the CMC curve.
André Anjos's avatar
André Anjos committed
27

28
"""
André Anjos's avatar
André Anjos committed
29

30
from __future__ import print_function
André Anjos's avatar
André Anjos committed
31

32 33
import os
import sys
André Anjos's avatar
André Anjos committed
34

André Anjos's avatar
André Anjos committed
35

36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
def main(user_input=None):

  if user_input is not None:
    argv = user_input
  else:
    argv = sys.argv[1:]

  import docopt
  import pkg_resources

  completions = dict(
      prog=os.path.basename(sys.argv[0]),
      version=pkg_resources.require('bob.measure')[0].version
      )

  args = docopt.docopt(
      __doc__ % completions,
      argv=argv,
      version=completions['version'],
      )

  # Sets-up logging
  if args['--verbose'] == 1: logging.getLogger().setLevel(logging.INFO)
  elif args['--verbose'] >= 2: logging.getLogger().setLevel(logging.DEBUG)

  # Validates rank
  if args['--rank'] is not None:
    try:
      args['--rank'] = int(args['--rank'])
    except:
      raise docopt.DocoptExit("cannot convert %s into int for rank" % \
          args['--rank'])

    if args['--rank'] <= 0:
      raise docopt.DocoptExit('Rank (--rank) should greater than zero')

  from .. import load

  # Loads score file
  f = load.open_file(args['<scores>'])
  try:
    line = f.readline()
    ncolumns = len(line.split())
  except Exception:
    logger.warn('Could not guess the number of columns in file: {}. '
                'Assuming 4 column format.'.format(args['<scores>']))
    ncolumns = 4
  finally:
    f.close()

  if ncolumns == 4:
    data = load.cmc_four_column(args['<scores>'])
  else:
    data = load.cmc_five_column(args['<scores>'])
90

91 92 93 94 95
  # compute recognition rate
  from .. import recognition_rate
  rr = recognition_rate(data, args['--rank'])
  print("Recognition rate for score file %s is %3.2f%%" % (args['<scores>'],
    rr * 100))
André Anjos's avatar
André Anjos committed
96

97
  if not args['--no-plot']:
André Anjos's avatar
André Anjos committed
98

99
    from .. import plot
André Anjos's avatar
André Anjos committed
100 101 102 103 104 105 106

    # compute CMC
    import matplotlib
    if not hasattr(matplotlib, 'backends'): matplotlib.use('pdf')
    import matplotlib.pyplot as mpl
    from matplotlib.backends.backend_pdf import PdfPages

107
    pp = PdfPages(args['--output'])
André Anjos's avatar
André Anjos committed
108 109 110

    # CMC
    fig = mpl.figure()
111 112 113
    if args['--rank'] is None:
      max_rank = plot.cmc(data, color=(0,0,1), linestyle='--', dashes=(6,2),
          logx = args['--log-x-scale'])
114
      mpl.title("CMC Curve")
115
      if args['--log-x-scale']:
116 117 118 119 120 121 122 123
        mpl.xlabel('Rank (log)')
      else:
        mpl.xlabel('Rank')
      mpl.ylabel('Recognition Rate in %')

      ticks = [int(t) for t in mpl.xticks()[0]]
      mpl.xticks(ticks, ticks)
      mpl.xlim([1, max_rank])
124

André Anjos's avatar
André Anjos committed
125
    else:
126 127 128
      plot.detection_identification_curve(data, rank = args['--rank'],
          color=(0,0,1), linestyle='--', dashes=(6,2),
          logx = args['--log-x-scale'])
Amir MOHAMMADI's avatar
Amir MOHAMMADI committed
129
      mpl.title("Detection \& Identification Curve")
130
      if args['--log-x-scale']:
131 132 133
        mpl.xlabel('False Acceptance Rate (log) in %')
      else:
        mpl.xlabel('False Acceptance Rate in %')
Amir MOHAMMADI's avatar
Amir MOHAMMADI committed
134
      mpl.ylabel('Detection \& Identification Rate in %')
135 136 137 138 139

      ticks = ["%s"%(t*100) for t in mpl.xticks()[0]]
      mpl.xticks(mpl.xticks()[0], ticks)
      mpl.xlim([1e-4, 1])

André Anjos's avatar
André Anjos committed
140 141 142 143 144 145 146 147
    mpl.grid(True, color=(0.3,0.3,0.3))
    mpl.ylim(ymax=101)
    # convert log-scale ticks to normal numbers

    pp.savefig(fig)
    pp.close()

  return 0