Commit b63237ce authored by Amir MOHAMMADI's avatar Amir MOHAMMADI

nit

parent 2ddbe247
Pipeline #19959 canceled with stage
in 6 minutes and 28 seconds
......@@ -6,6 +6,7 @@ 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='det.pdf')
......
......@@ -6,6 +6,7 @@ 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='epc.pdf')
......@@ -49,6 +50,7 @@ def epc(ctx, scores, **kwargs):
process = figure.Epc(ctx, scores, True, load.split)
process.run()
@click.command()
@common_options.scores_argument(min_arg=2, force_eval=True, nargs=-1)
@common_options.output_plot_file_option(default_out='epsc.pdf')
......
#!/usr/bin/env python
#Ivana Chingovska <ivana.chingovska@idiap.ch>
#Fri Dec 7 12:33:37 CET 2012
# Ivana Chingovska <ivana.chingovska@idiap.ch>
# Fri Dec 7 12:33:37 CET 2012
"""Utility functions for computation of EPSC curve and related measurement"""
import os
import sys
import bob.measure
import numpy
import argparse
def calc_pass_rate(threshold, attacks):
......@@ -69,7 +66,7 @@ def weighted_neg_error_rate_criteria(data,
if beta == 0.5:
return abs(far_w - frr)
else:
#return abs(far_w - frr)
# return abs(far_w - frr)
return abs((1 - beta) * frr - beta * far_w)
elif criteria == 'min-hter':
......@@ -212,7 +209,7 @@ def epsc_thresholds(licit_neg,
"""
step_size = 1 / float(points)
if omega == None:
if omega is None:
omega = numpy.array([(i * step_size) for i in range(points + 1)])
elif not isinstance(omega, list) and not isinstance(
omega, tuple) and not isinstance(omega, numpy.ndarray):
......@@ -220,7 +217,7 @@ def epsc_thresholds(licit_neg,
else:
omega = numpy.array(omega)
if beta == None:
if beta is None:
beta = numpy.array([(i * step_size) for i in range(points + 1)])
elif not isinstance(beta, list) and not isinstance(
beta, tuple) and not isinstance(beta, numpy.ndarray):
......@@ -288,8 +285,8 @@ negative samples (impostors and spoofing attacks).
spoof_neg, spoof_pos,
threshold) # calculate test frr @ threshold (spoof scenario)
frr = farfrr_licit[
1] # we can take this value from farfrr_spoof as well, it doesn't matter
# we can take this value from farfrr_spoof as well, it doesn't matter
frr = farfrr_licit[1]
far = farfrr_licit[0]
sfar = farfrr_spoof[0]
......
......@@ -3,10 +3,10 @@ experiements
"""
import click
from bob.measure.script import common_options
from bob.extension.scripts.click_helper import (verbosity_option, bool_option)
from bob.bio.base.score import load
from bob.extension.scripts.click_helper import verbosity_option
import bob.bio.base.script.commands as bio_commands
from . import (figure, histograms, metrics, det, fmr_iapmr, epc)
from . import (histograms, metrics, det, fmr_iapmr, epc)
@click.command()
@common_options.scores_argument(nargs=-1)
......@@ -99,8 +99,8 @@ def vuln(ctx, scores, **kwargs):
\b
1. Computes bob pad vuln_metrics
2. Plots EPC, EPSC, vulnerability histograms, fmr vs IAPMR to a multi-page PDF
file
2. Plots EPC, EPSC, vulnerability histograms, fmr vs IAPMR to a multi-page
PDF file
You need to provide 4 score files for each biometric system in this order:
......
'''Runs error analysis on score sets, outputs metrics and plots'''
import logging
import click
import numpy as np
import matplotlib.pyplot as mpl
import bob.measure.script.figure as measure_figure
from tabulate import tabulate
from bob.extension.scripts.click_helper import verbosity_option
from bob.measure.utils import (get_fta, get_fta_list, get_thres)
from bob.measure.utils import get_fta_list
from bob.measure import (
far_threshold, eer_threshold, min_hter_threshold, farfrr, epc, ppndf
)
......@@ -58,6 +56,7 @@ class Metrics(measure_figure.Metrics):
super(Metrics, self).__init__(ctx, scores, evaluation, func_load)
''' Compute metrics from score files'''
def compute(self, idx, input_scores, input_names):
''' Compute metrics for the given criteria'''
neg_list, pos_list, _ = get_fta_list(input_scores)
......@@ -97,6 +96,7 @@ class MetricsVuln(measure_figure.Metrics):
super(MetricsVuln, self).__init__(ctx, scores, evaluation, func_load)
''' Compute metrics from score files'''
def compute(self, idx, input_scores, input_names):
''' Compute metrics for the given criteria'''
neg_list, pos_list, _ = get_fta_list(input_scores)
......@@ -110,10 +110,10 @@ class MetricsVuln(measure_figure.Metrics):
headers = ['' or title, '%s (threshold=%.2g)' %
(criter.upper(), threshold)]
rows = []
rows.append(['FMR (%)', '{:>5.1f}%'.format(100*far)])
rows.append(['FMNR (%)', '{:>5.1f}%'.format(frr*100)])
rows.append(['HTER (%)', '{:>5.1f}%'.format(50*(far+frr))])
rows.append(['IAPMR (%)', '{:>5.1f}%'.format(100*iapmr)])
rows.append(['FMR (%)', '{:>5.1f}%'.format(100 * far)])
rows.append(['FMNR (%)', '{:>5.1f}%'.format(frr * 100)])
rows.append(['HTER (%)', '{:>5.1f}%'.format(50 * (far + frr))])
rows.append(['IAPMR (%)', '{:>5.1f}%'.format(100 * iapmr)])
click.echo(
tabulate(rows, headers, self._tablefmt),
file=self.log_file
......@@ -190,10 +190,10 @@ class HistVuln(measure_figure.Hist):
def _lines(self, threshold, label, neg, pos, idx, **kwargs):
if 'iapmr_line' not in self._ctx.meta or self._ctx.meta['iapmr_line']:
#plot vertical line
# plot vertical line
super(HistVuln, self)._lines(threshold, label, neg, pos, idx)
#plot iapmr_line
# plot iapmr_line
iapmr, _ = farfrr(neg[1], pos[0], threshold)
ax2 = mpl.twinx()
# we never want grid lines on axis 2
......@@ -203,7 +203,8 @@ class HistVuln(measure_figure.Hist):
_iapmr_plot(neg[1], threshold, iapmr, real_data=real_data)
n = idx % self._step_print
col = n % self._ncols
rest_print = self.n_systems - int(idx / self._step_print) * self._step_print
rest_print = self.n_systems - \
int(idx / self._step_print) * self._step_print
if col == self._ncols - 1 or n == rest_print - 1:
ax2.set_ylabel("IAPMR (%)", color='C3')
ax2.tick_params(axis='y', colors='red')
......@@ -213,19 +214,20 @@ class HistVuln(measure_figure.Hist):
class PadPlot(measure_figure.PlotBase):
'''Base class for PAD plots'''
def __init__(self, ctx, scores, evaluation, func_load):
super(PadPlot, self).__init__(ctx, scores, evaluation, func_load)
mpl.rcParams['figure.constrained_layout.use'] = self._clayout
def end_process(self):
'''Close pdf '''
#do not want to close PDF when running evaluate
# 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()
def _plot_legends(self):
#legends for all axes
# legends for all axes
lines = []
labels = []
for ax in mpl.gcf().get_axes():
......@@ -239,6 +241,7 @@ class PadPlot(measure_figure.PlotBase):
class Epc(PadPlot):
''' Handles the plotting of EPC '''
def __init__(self, ctx, scores, evaluation, func_load):
super(Epc, self).__init__(ctx, scores, evaluation, func_load)
self._iapmr = True if 'iapmr' not in self._ctx.meta else \
......@@ -247,7 +250,7 @@ class Epc(PadPlot):
'EPC')
self._x_label = self._x_label or r"Weight $\beta$"
self._y_label = self._y_label or "WER (%)"
self._eval = True #always eval data with EPC
self._eval = True # always eval data with EPC
self._split = False
self._nb_figs = 1
......@@ -306,7 +309,7 @@ class Epc(PadPlot):
title = self._legends[idx] if self._legends is not None else self._title
if title.replace(' ', ''):
mpl.title(title)
#legends for all axes
# legends for all axes
self._plot_legends()
mpl.xticks(rotation=self._x_rotation)
self._pdf_page.savefig(mpl.gcf())
......@@ -314,6 +317,7 @@ class Epc(PadPlot):
class Epsc(PadPlot):
''' Handles the plotting of EPSC '''
def __init__(self, ctx, scores, evaluation, func_load,
criteria, var_param, fixed_param):
super(Epsc, self).__init__(ctx, scores, evaluation, func_load)
......@@ -324,7 +328,7 @@ class Epsc(PadPlot):
self._criteria = 'eer' if criteria is None else criteria
self._var_param = "omega" if var_param is None else var_param
self._fixed_param = 0.5 if fixed_param is None else fixed_param
self._eval = True #always eval data with EPC
self._eval = True # always eval data with EPC
self._split = False
self._nb_figs = 1
self._title = ''
......@@ -364,7 +368,7 @@ class Epsc(PadPlot):
spoof_dev_neg,
spoof_dev_pos,
points=points,
criteria= self._criteria,
criteria=self._criteria,
omega=self._fixed_param
)
......@@ -427,11 +431,11 @@ class Epsc(PadPlot):
if self._var_param == 'omega':
if title is not None and title.replace(' ', ''):
mpl.title(title or (r"EPSC with $\beta$ = %.2f" %\
mpl.title(title or (r"EPSC with $\beta$ = %.2f" %
self._fixed_param))
else:
if title is not None and title.replace(' ', ''):
mpl.title(title or (r"EPSC with $\omega$ = %.2f" %\
mpl.title(title or (r"EPSC with $\omega$ = %.2f" %
self._fixed_param))
mpl.grid()
......@@ -444,6 +448,7 @@ class Epsc(PadPlot):
class Epsc3D(Epsc):
''' 3D EPSC plots for PAD'''
def compute(self, idx, input_scores, input_names):
''' Implements plots'''
licit_dev_neg = input_scores[0][0]
......@@ -513,6 +518,7 @@ class Epsc3D(Epsc):
class Det(PadPlot):
'''DET for PAD'''
def __init__(self, ctx, scores, evaluation, func_load, criteria, real_data):
super(Det, self).__init__(ctx, scores, evaluation, func_load)
self._no_spoof = False if 'no_spoof' not in ctx.meta else\
......@@ -645,7 +651,7 @@ class Det(PadPlot):
def end_process(self):
''' Set title, legend, axis labels, grid colors, save figures and
close pdf is needed '''
#only for plots
# only for plots
add = ''
if not self._no_spoof:
add = " and overlaid SPOOF scenario"
......@@ -669,7 +675,7 @@ class Det(PadPlot):
self._pdf_page.savefig(fig)
#do not want to close PDF when running evaluate
# 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()
......@@ -683,9 +689,10 @@ class Det(PadPlot):
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._eval = True # always eval data with EPC
self._split = False
self._nb_figs = 1
self._semilogx = False if 'semilogx' not in ctx.meta else\
......@@ -717,7 +724,7 @@ class FmrIapmr(PadPlot):
def end_process(self):
''' Set title, legend, axis labels, grid colors, save figures and
close pdf is needed '''
#only for plots
# only for plots
title = self._title if self._title is not None else "FMR vs IAPMR"
if title.replace(' ', ''):
mpl.title(title)
......@@ -733,7 +740,7 @@ class FmrIapmr(PadPlot):
self._pdf_page.savefig(fig)
#do not want to close PDF when running evaluate
# 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()
......@@ -6,6 +6,7 @@ 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')
......
......@@ -6,6 +6,7 @@ from bob.extension.scripts.click_helper import (verbosity_option, bool_option)
from bob.bio.base.score import load
from . import figure
@click.command()
@common_options.scores_argument(nargs=-1)
@common_options.title_option()
......@@ -27,9 +28,9 @@ def hist(ctx, scores, evaluation, **kwargs):
""" Plots histograms of Bona fida and PA along with threshold
criterion.
You need to provide one or more development score file(s) for each experiment.
You can also provide eval files along with dev files. If only dev scores
are provided, you must use flag `--no-evaluation`.
You need to provide one or more development score file(s) for each
experiment. You can also provide eval files along with dev files. If only
dev scores are provided, you must use flag `--no-evaluation`.
By default, when eval-scores are given, only eval-scores histograms are
displayed with threshold line
......@@ -47,6 +48,7 @@ def hist(ctx, scores, evaluation, **kwargs):
process = figure.HistPad(ctx, scores, evaluation, load.split)
process.run()
@click.command()
@common_options.scores_argument(nargs=-1, min_arg=2)
@common_options.title_option()
......@@ -87,10 +89,10 @@ def vuln_hist(ctx, scores, evaluation, **kwargs):
See :ref:`bob.pad.base.vulnerability` in the documentation for a guide on
vulnerability analysis.
You need to provide one or more development score file(s) for each experiment.
You can also provide eval files along with dev files. If only dev-scores
are used set the flag `--no-evaluation`
is required in that case.
You need to provide one or more development score file(s) for each
experiment. You can also provide eval files along with dev files. If only
dev-scores are used set the flag `--no-evaluation` is required in that
case.
By default, when eval-scores are given, only eval-scores histograms are
displayed with threshold line
......
......@@ -7,6 +7,7 @@ from bob.extension.scripts.click_helper import (verbosity_option,
from bob.bio.base.score import load
from . import figure
@click.command(context_settings=dict(token_normalize_func=lambda x: x.lower()))
@common_options.scores_argument(nargs=-1)
@common_options.eval_option()
......@@ -20,7 +21,8 @@ def metrics(ctx, scores, evaluation, **kwargs):
"""PAD ISO compliant metrics.
Reports several metrics based on a selected thresholds on the development
set and apply them on evaluation sets (if provided). The used thresholds are:
set and apply them on evaluation sets (if provided). The used thresholds
are:
bpcer20 When APCER is set to 5%.
......@@ -52,6 +54,7 @@ def metrics(ctx, scores, evaluation, **kwargs):
process = figure.Metrics(ctx, scores, evaluation, load.split)
process.run()
@click.command(context_settings=dict(token_normalize_func=lambda x: x.lower()))
@common_options.scores_argument(min_arg=2, force_eval=True, nargs=-1)
@common_options.eval_option()
......
......@@ -8,5 +8,5 @@ from click_plugins import with_plugins
@with_plugins(pkg_resources.iter_entry_points('bob.pad.cli'))
@click.group()
def pad():
"""Entry for bob.pad commands."""
"""Presentation Attack Detection related commands."""
pass
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