plot_cmc.py 4.04 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

35 36 37
import bob.core
logger = bob.core.log.setup("bob.measure")

André Anjos's avatar
André Anjos committed
38

39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
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
61 62
  verbosity = int(args['--verbose'])
  bob.core.log.set_verbosity_level(logger, verbosity)
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 90 91 92

  # 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>'])
93

94 95
  # compute recognition rate
  from .. import recognition_rate
96 97 98 99 100
  if args['--rank'] is not None:
    rr = recognition_rate(data, rank=args['--rank'])
  else:
    rr = recognition_rate(data)

101 102
  print("Recognition rate for score file %s is %3.2f%%" % (args['<scores>'],
    rr * 100))
André Anjos's avatar
André Anjos committed
103

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

106
    from .. import plot
André Anjos's avatar
André Anjos committed
107 108 109 110 111 112 113

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

114
    pp = PdfPages(args['--output'])
André Anjos's avatar
André Anjos committed
115 116 117

    # CMC
    fig = mpl.figure()
118 119 120
    if args['--rank'] is None:
      max_rank = plot.cmc(data, color=(0,0,1), linestyle='--', dashes=(6,2),
          logx = args['--log-x-scale'])
121
      mpl.title("CMC Curve")
122
      if args['--log-x-scale']:
123 124 125 126 127 128 129 130
        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])
131

André Anjos's avatar
André Anjos committed
132
    else:
133 134 135
      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
136
      mpl.title("Detection \& Identification Curve")
137
      if args['--log-x-scale']:
138 139 140
        mpl.xlabel('False Acceptance Rate (log) in %')
      else:
        mpl.xlabel('False Acceptance Rate in %')
Amir MOHAMMADI's avatar
Amir MOHAMMADI committed
141
      mpl.ylabel('Detection \& Identification Rate in %')
142 143 144 145 146

      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
147 148 149 150 151 152 153 154
    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