Commit e0a0db5e authored by Theophile GENTILHOMME's avatar Theophile GENTILHOMME

Add fmr vs IAPMR plot

parent d7eaabda
Pipeline #19366 failed with stage
in 35 minutes and 6 seconds
......@@ -219,7 +219,6 @@ class Epc(PadPlot):
self._eval = True #always eval data with EPC
self._split = False
self._nb_figs = 1
self._title = ''
if self._min_arg != 4:
raise click.BadParameter("You must provide 4 scores files:{licit,"
......@@ -620,7 +619,6 @@ class Det(PadPlot):
mpl.grid(True, color=self._grid_color)
mpl.legend(loc='best')
self._set_axis()
#gives warning when applied with mpl
fig = mpl.gcf()
mpl.xticks(rotation=self._x_rotation)
mpl.tick_params(axis='both', which='major', labelsize=4)
......@@ -641,3 +639,58 @@ class Det(PadPlot):
det_axis(self._axlim)
else:
det_axis([0.01, 99, 0.01, 99])
class FmrIapmr(PadPlot):
'''FMR vs IAPMR'''
def __init__(self, ctx, scores, evaluation, func_load):
super(FmrIapmr, self).__init__(ctx, scores, evaluation, func_load)
self._eval = True #always eval data with EPC
self._split = False
self._nb_figs = 1
self._semilogx = False if 'semilogx' not in ctx.meta else\
ctx.meta['semilogx']
if self._min_arg != 4:
raise click.BadParameter("You must provide 4 scores files:{licit,"
"spoof}/{dev,eval}")
def compute(self, idx, input_scores, input_names):
''' Implements plots'''
licit_eval_neg = input_scores[1][0]
licit_eval_pos = input_scores[1][1]
spoof_eval_neg = input_scores[3][0]
fmr_list = np.linspace(0, 1, 100)
iapmr_list = []
for i, fmr in enumerate(fmr_list):
thr = far_threshold(licit_eval_neg, licit_eval_pos, fmr, True)
iapmr_list.append(farfrr(spoof_eval_neg, licit_eval_pos, thr)[0])
# re-calculate fmr since threshold might give a different result
# for fmr.
fmr_list[i] = farfrr(licit_eval_neg, licit_eval_pos, thr)[0]
label = self._titles[idx] if self._titles is not None else \
'(%s/%s)' % (input_names[1], input_names[3])
if self._semilogx:
mpl.semilogx(fmr_list, iapmr_list, label=label)
else:
mpl.plot(fmr_list, iapmr_list, label=label)
def end_process(self):
''' Set title, legend, axis labels, grid colors, save figures and
close pdf is needed '''
#only for plots
title = self._title if self._title is not None else "FMR vs IAPMR"
mpl.title(title)
mpl.xlabel(self._x_label or "False Match Rate (%)")
mpl.ylabel(self._y_label or "IAPMR (%)")
mpl.grid(True, color=self._grid_color)
mpl.legend(loc='best')
self._set_axis()
fig = mpl.gcf()
mpl.xticks(rotation=self._x_rotation)
mpl.tick_params(axis='both', which='major', labelsize=4)
self._pdf_page.savefig(fig)
#do not want to close PDF when running evaluate
if 'PdfPages' in self._ctx.meta and \
('closef' not in self._ctx.meta or self._ctx.meta['closef']):
self._pdf_page.close()
"""Generates PAD ISO compliant FMR vs IAPMR plots based on the score files
"""
import click
from bob.measure.script import common_options
from bob.extension.scripts.click_helper import verbosity_option
from bob.bio.base.score import load
from . import figure
@click.command()
@common_options.scores_argument(min_arg=2, force_eval=True, nargs=-1)
@common_options.output_plot_file_option(default_out='fmr_iapmr.pdf')
@common_options.titles_option()
@common_options.const_layout_option()
@common_options.style_option()
@common_options.figsize_option()
@verbosity_option()
@common_options.axes_val_option()
@common_options.x_rotation_option()
@common_options.x_label_option()
@common_options.y_label_option()
@common_options.semilogx_option()
@click.pass_context
def fmr_iapmr(ctx, scores, **kwargs):
"""Plot FMR vs IAPMR
You need to provide 2 or 4 scores
files for each PAD system in this order:
\b
* licit development scores
* licit evaluation scores
* spoof development scores (when ``--no-spoof`` is False (default))
* spoof evaluation scores (when ``--no-spoof`` is False (default))
Examples:
$ bob pad fmr_iapmr --no-spoof dev-scores eval-scores
$ bob pad fmr_iapmr {licit,spoof}/scores-{dev,eval}
"""
process = figure.FmrIapmr(ctx, scores, True, load.split)
process.run()
......@@ -2,7 +2,7 @@ import sys
import click
from click.testing import CliRunner
import pkg_resources
from ..script import (metrics, histograms, epc, det)
from ..script import (metrics, histograms, epc, det, fmr_iapmr)
def test_det():
......@@ -23,6 +23,30 @@ def test_det():
spoof_dev, spoof_test])
assert result.exit_code == 0, (result.exit_code, result.output)
def test_fmr_iapmr():
licit_dev = pkg_resources.resource_filename('bob.pad.base.test',
'data/licit/scores-dev')
licit_test = pkg_resources.resource_filename('bob.pad.base.test',
'data/licit/scores-eval')
spoof_dev = pkg_resources.resource_filename('bob.pad.base.test',
'data/spoof/scores-dev')
spoof_test = pkg_resources.resource_filename('bob.pad.base.test',
'data/spoof/scores-eval')
runner = CliRunner()
with runner.isolated_filesystem():
result = runner.invoke(fmr_iapmr.fmr_iapmr, [
'--output', 'FMRIAPMR.pdf', licit_dev, licit_test, spoof_dev,
spoof_test
])
assert result.exit_code == 0, (result.exit_code, result.output)
result = runner.invoke(fmr_iapmr.fmr_iapmr, [
'--output', 'FMRIAPMR.pdf', licit_dev, licit_test, spoof_dev,
spoof_test, '-G', '-L', '1e-7,1,0,1'
])
assert result.exit_code == 0, (result.exit_code, result.output)
def test_hist():
licit_dev = pkg_resources.resource_filename('bob.pad.base.test',
'data/licit/scores-dev')
......
......@@ -146,6 +146,7 @@ setup(
'epc = bob.pad.base.script.epc:epc',
'epsc = bob.pad.base.script.epc:epsc',
'gen = bob.pad.base.script.gen:gen',
'fmr_iapmr = bob.pad.base.script.fmr_iapmr:fmr_iapmr',
],
},
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment