Пример #1
0
def gbu_report(scores_dev, output_filename, titles, figsize=(8, 6)):

    colors = plt.cm.tab20.colors

    # Plotting
    pdf = PdfPages(output_filename)

    # Figure for eval plot
    fig = plt.figure(figsize=figsize)
    ax = fig.add_subplot(111)

    for d_scores, title, color in zip(scores_dev, titles, colors):

        # Load the score files and fill in the angle associated to each camera
        impostors_dev, genuines_dev = get_split_dataframe(d_scores)

        # loading the dask dataframes
        i_dev = impostors_dev["score"].compute().to_numpy()
        g_dev = genuines_dev["score"].compute().to_numpy()

        fmr, fnmr = bob.measure.roc(i_dev, g_dev, n_points=40)
        # in %
        fnmr = 1 - fnmr
        fnmr *= 100
        fmr *= 100

        # plot.plot(roc_curve)
        plt.semilogx(fmr, fnmr, marker="o", label=title)
        pass

    pass

    # Plot finalization
    # plt.title(f"FMR vs FNMR .  at Dev. FMR@{fmr_threshold}")
    ax.set_xlabel("FMR%", fontsize=18)
    ax.set_ylabel("1 - FNMR%", fontsize=18)

    x_ticks = [0.0001, 0.01, 1, 100]
    ax.set_xticks(x_ticks)
    ax.set_xticklabels([f"{x}%" for x in x_ticks], fontsize=14)

    y_ticks = [0, 20, 40, 60, 80, 100]
    ax.set_yticks(y_ticks)
    ax.set_yticklabels([f"{x}%" for x in y_ticks], fontsize=14)

    plt.legend()
    plt.grid()

    pdf.savefig(fig)
    pdf.close()
Пример #2
0
    def fit(self, input_score_file_name):
        """
        Fit the calibrator

        Parameters
        ----------

           input_score_file_name: str
              Reference score file used to fit the calibrator (E.g `scores-dev.csv`).


        """
        def impostor_threshold(impostor_scores):
            """
            score > Q3 + 1.5*IQR
            """
            q1 = np.quantile(impostor_scores, 0.25)
            q3 = np.quantile(impostor_scores, 0.75)

            if self.score_selection_method == "q3-outlier":
                outlier_zone = q3 + self.quantile_factor * (q3 - q1)
                return impostor_scores[(impostor_scores > q3)
                                       & (impostor_scores <= outlier_zone)]
            elif self.score_selection_method == "q1-median":
                median = np.median(impostor_scores)
                return impostor_scores[(impostor_scores > q1)
                                       & (impostor_scores <= median)]
            elif self.score_selection_method == "median-q3":
                median = np.median(impostor_scores)
                return impostor_scores[(impostor_scores < q3)
                                       & (impostor_scores >= median)]
            else:
                return impostor_scores

        def genuine_threshold(genuine_scores):
            """
            score <= Q3 - 1.5*IQR
            """
            q1 = np.quantile(genuine_scores, 0.25)
            q3 = np.quantile(genuine_scores, 0.75)

            if self.score_selection_method == "q3-outlier":
                outlier_zone = q1 - self.quantile_factor * (q3 - q1)
                return genuine_scores[(genuine_scores < q1)
                                      & (genuine_scores >= outlier_zone)]
            elif self.score_selection_method == "q1-median":
                median = np.median(genuine_scores)
                return genuine_scores[(genuine_scores < q3)
                                      & (genuine_scores <= median)]
            elif self.score_selection_method == "median-q3":
                median = np.median(genuine_scores)
                return genuine_scores[(genuine_scores > q1)
                                      & (genuine_scores <= median)]
            else:
                return genuine_scores

        impostors, genuines = get_split_dataframe(input_score_file_name)
        self._categorical_fitters = []

        def get_sigmoid_score(X, regressor):
            return expit(X * regressor.coef_ + regressor.intercept_).ravel()

        for value in self.field_values:

            # Filtering genunines and impostors per group
            impostors_per_group = (
                impostors[(impostors[f"probe_{self.field_name}"] == value)
                          & (impostors[f"bio_ref_{self.field_name}"] == value)]
                ["score"].compute().to_numpy())
            genuines_per_group = (
                genuines[(genuines[f"probe_{self.field_name}"] == value
                          )]["score"].compute().to_numpy())

            impostors_per_group = impostor_threshold(impostors_per_group)
            genuines_per_group = genuine_threshold(genuines_per_group)

            # Training the regressor
            y = np.hstack((
                np.zeros(len(impostors_per_group)),
                np.ones(len(genuines_per_group)),
            ))
            X = np.expand_dims(np.hstack(
                (impostors_per_group, genuines_per_group)),
                               axis=1)
            fitter = self.fit_estimator().fit(X, y)
            self._categorical_fitters.append(fitter)

        return self
Пример #3
0
def arface_report(
    scores_dev,
    scores_eval,
    output_filename,
    titles,
    fmr_threshold=1e-3,
    figsize=(16, 8),
    y_abs_max=32,  # Max absolute value for y axis
    colors=plt.cm.tab10.colors,
):

    occlusion_illumination = [
        "illumination",
        "occlusion",
        "both",
    ]

    occlusions = [
        "scarf",
        "sunglasses",
    ]

    # style_iterator = _get_colors_markers()
    # colors = plt.cm.tab20.colors

    eval_fmr_fnmr_occlusion_illumination = dict()
    eval_fmr_fnmr_occlusion = dict()

    for (
            d_scores,
            e_scores,
            title,
    ) in zip(scores_dev, scores_eval, titles):

        eval_fmr_fnmr_occlusion_illumination[title] = []
        eval_fmr_fnmr_occlusion[title] = []

        # Load the score files and fill in the angle associated to each camera
        impostors_dev, genuines_dev = get_split_dataframe(d_scores)
        impostors_eval, genuines_eval = get_split_dataframe(e_scores)

        # loading the dask dataframes
        impostors_dev = impostors_dev.compute()
        genuines_dev = genuines_dev.compute()
        impostors_eval = impostors_eval.compute()
        genuines_eval = genuines_eval.compute()

        # Computing the threshold combining all distances
        threshold = bob.measure.far_threshold(
            impostors_dev["score"].to_numpy(),
            genuines_dev["score"].to_numpy(),
            fmr_threshold,
        )

        def compute_fmr_fnmr(impostor_scores, genuine_scores):
            eval_fmr, eval_fnmr = bob.measure.farfrr(
                impostor_scores["score"].to_numpy(),
                genuine_scores["score"].to_numpy(),
                threshold,
            )
            return eval_fmr, eval_fnmr

        # EVALUATING OCCLUSION AND ILLUMINATION

        # All illumination
        i_eval = impostors_eval.loc[
            (impostors_eval.probe_illumination != "front")
            & (impostors_eval.probe_occlusion == "none")]
        g_eval = genuines_eval.loc[
            (genuines_eval.probe_illumination != "front")
            & (genuines_eval.probe_occlusion == "none")]
        eval_fmr_fnmr_occlusion_illumination[title].append(
            compute_fmr_fnmr(i_eval, g_eval))

        # All occlusions
        i_eval = impostors_eval.loc[
            (impostors_eval.probe_occlusion != "none")
            & (impostors_eval.probe_illumination == "front")]
        g_eval = genuines_eval.loc[
            (genuines_eval.probe_occlusion != "none")
            & (genuines_eval.probe_illumination == "front")]
        eval_fmr_fnmr_occlusion_illumination[title].append(
            compute_fmr_fnmr(i_eval, g_eval))

        # BOTH
        overall_fmr_fnmr = compute_fmr_fnmr(impostors_eval, genuines_eval)
        eval_fmr_fnmr_occlusion_illumination[title].append(overall_fmr_fnmr)

        # EVALUATING DIFFERENT TYPES OF OCCLUSION
        for occlusion in occlusions:
            i_eval = impostors_eval.loc[impostors_eval.probe_occlusion ==
                                        occlusion]
            g_eval = genuines_eval.loc[genuines_eval.probe_occlusion ==
                                       occlusion]

            eval_fmr_fnmr_occlusion[title].append(
                compute_fmr_fnmr(i_eval, g_eval))

    pass

    # Plotting

    #
    # EFFECT OF OCCLUSION TYPES

    # Figure for eval plot
    fig = plt.figure(figsize=figsize)
    ax = fig.add_subplot(111)

    width = 0.8 / len(titles)

    X = np.arange(len(occlusions))

    for i, (title, color) in enumerate(zip(titles, colors)):
        fmrs = [-1 * fmr * 100 for fmr, _ in eval_fmr_fnmr_occlusion[title]]
        fnmrs = [fnmr * 100 for _, fnmr in eval_fmr_fnmr_occlusion[title]]

        x_axis = X + (i + 1) * width - width / 2
        ax.bar(
            x_axis,
            fmrs,
            width,
            label=title,
            color=color,
            alpha=1,
            hatch="\\",
        )
        ax.bar(
            x_axis,
            fnmrs,
            width,
            color=color,
            alpha=0.5,
            hatch="/",
        )

        # Writting the texts on top of the bar plots
        for i, fnmr, fmr in zip(x_axis, fnmrs, fmrs):
            plt.text(i - width / 2,
                     fnmr + 0.5,
                     str(round(fnmr, 1)),
                     fontsize=15)
            plt.text(i - width / 2,
                     fmr - 2.3,
                     str(round(abs(fmr), 1)),
                     fontsize=15)

    # Plot finalization
    plt.title(f"FMR vs FNMR.  at Dev. FMR@{fmr_threshold*100}%", fontsize=16)
    ax.set_xlabel("Occlusion types", fontsize=14)
    ax.set_ylabel("FMR(%) vs FNMR(%)                  ", fontsize=18)

    ax.set_xticks(X + 0.5)
    ax.set_xticklabels(occlusions, fontsize=14)

    yticks = np.array([
        -y_abs_max / 4,
        0,
        y_abs_max / 4,
        y_abs_max / 2,
        y_abs_max,
    ])

    ax.set_yticks(yticks)
    ax.set_yticklabels([abs(int(y)) for y in yticks], fontsize=16)

    plt.axhline(0, linestyle="-", color="k")
    plt.ylim([-y_abs_max / 4, y_abs_max + 1])

    plt.legend()
    plt.grid()

    plt.savefig(fig)

    # EFFECT OF ILLUMINATION AND OCCLUSION

    # Figure for eval plot
    fig = plt.figure(figsize=figsize)
    ax = fig.add_subplot(111)

    X = np.arange(len(occlusion_illumination))

    for i, (title, color) in enumerate(zip(titles, colors)):
        fmrs = [
            -1 * fmr * 100
            for fmr, _ in eval_fmr_fnmr_occlusion_illumination[title]
        ]
        fnmrs = [
            fnmr * 100
            for _, fnmr in eval_fmr_fnmr_occlusion_illumination[title]
        ]

        x_axis = X + (i + 1) * width - width / 2
        ax.bar(
            x_axis,
            fmrs,
            width,
            label=title,
            color=color,
            alpha=1,
            hatch="\\",
        )
        ax.bar(
            x_axis,
            fnmrs,
            width,
            color=color,
            alpha=0.5,
            hatch="/",
        )
        # Writting the texts on top of the bar plots
        for i, fnmr, fmr in zip(x_axis, fnmrs, fmrs):
            plt.text(
                i - width / 2,
                fnmr + 0.4,
                str(int(fnmr)) if fnmr == 0 else str(round(fnmr, 1)),
                fontsize=15,
            )
            plt.text(
                i - width / 2,
                fmr - 0.9,
                str(int(fmr)),
                fontsize=15,
            )

    plt.title(f"FMR vs FNMR.  at Dev. FMR@{fmr_threshold*100}%", fontsize=16)
    ax.set_xlabel("Occlusion and illumination", fontsize=14)
    ax.set_ylabel("FMR(%) vs FNMR(%)            ", fontsize=18)

    ax.set_xticks(X + 0.5)
    ax.set_xticklabels(occlusion_illumination, fontsize=14)

    yticks = np.array([-y_abs_max / 4, 0, y_abs_max / 4, y_abs_max / 2])
    ax.set_yticks(yticks)
    ax.set_yticklabels([abs(int(y)) for y in yticks], fontsize=16)

    plt.axhline(0, linestyle="-", color="k")
    plt.ylim([-y_abs_max / 4, y_abs_max / 2])

    plt.legend()
    plt.grid()
    plt.savefig(fig)
Пример #4
0
def multipie_expression_report(
    scores_dev,
    scores_eval,
    output_filename,
    titles,
    fmr_threshold=1e-3,
    figsize=(16, 8),
    y_abs_max=60,  # Max absolute value for y axis
    colors=plt.cm.tab10.colors,
):

    # "all",
    expressions = [
        "neutral",
        "smile",
        "surprise",
        "squint",
        "disgust",
        "scream",
    ]

    # style_iterator = _get_colors_markers()
    # colors = plt.cm.tab20.colors

    eval_fmr_fnmr_expressions = dict()

    for (
        d_scores,
        e_scores,
        title,
    ) in zip(scores_dev, scores_eval, titles):

        eval_fmr_fnmr_expressions[title] = []

        # Load the score files and fill in the angle associated to each camera
        impostors_dev, genuines_dev = get_split_dataframe(d_scores)
        impostors_eval, genuines_eval = get_split_dataframe(e_scores)

        # loading the dask dataframes
        impostors_dev = impostors_dev.compute()
        genuines_dev = genuines_dev.compute()
        impostors_eval = impostors_eval.compute()
        genuines_eval = genuines_eval.compute()

        # Computing the threshold combining all distances
        threshold = bob.measure.far_threshold(
            impostors_dev["score"].to_numpy(),
            genuines_dev["score"].to_numpy(),
            fmr_threshold,
        )

        def compute_fmr_fnmr(impostor_scores, genuine_scores):
            eval_fmr, eval_fnmr = bob.measure.farfrr(
                impostor_scores["score"].to_numpy(),
                genuine_scores["score"].to_numpy(),
                threshold,
            )
            return eval_fmr, eval_fnmr

        # All expressions
        # i_eval = impostors_eval
        # g_eval = genuines_eval
        # eval_fmr_fnmr_expressions[title].append(compute_fmr_fnmr(i_eval, g_eval))

        # EVALUATING DIFFERENT TYPES OF EXPRESSION
        for expression in expressions:
            i_eval = impostors_eval.loc[
                impostors_eval.probe_expression == expression
            ]
            g_eval = genuines_eval.loc[
                genuines_eval.probe_expression == expression
            ]

            eval_fmr_fnmr_expressions[title].append(
                compute_fmr_fnmr(i_eval, g_eval)
            )

    pass

    # Plotting
    pdf = PdfPages(output_filename)

    # Figure for eval plot
    fig = plt.figure(figsize=figsize)
    ax = fig.add_subplot(111)

    width = 0.8 / len(titles)

    X = np.arange(len(expressions))

    for i, (title, color) in enumerate(zip(titles, colors)):
        fmrs = [-1 * fmr * 100 for fmr, _ in eval_fmr_fnmr_expressions[title]]
        fnmrs = [fnmr * 100 for _, fnmr in eval_fmr_fnmr_expressions[title]]

        x_axis = X + (i + 1) * width - width / 2
        ax.bar(
            x_axis,
            fmrs,
            width,
            label=title,
            color=color,
            alpha=1,
            hatch="\\",
        )
        ax.bar(
            x_axis,
            fnmrs,
            width,
            color=color,
            alpha=0.5,
            hatch="/",
        )
        # str(int(fnmr)) if fnmr == 0 else str(round(fnmr, 1))
        # Writting the texts on top of the bar plots
        for i, fnmr, fmr in zip(x_axis, fnmrs, fmrs):
            plt.text(
                i - width / 2,
                fnmr + 0.8,
                str(int(fnmr)),
                fontsize=10,
            )
            plt.text(
                i - width / 2,
                fmr - 2.8,
                str(int(abs(fmr))),
                fontsize=10,
            )

    # Plot finalization
    plt.title(f"FMR vs FNMR.  at Dev. FMR@{fmr_threshold*100}%", fontsize=16)
    ax.set_xlabel("Expressions", fontsize=12)
    ax.set_ylabel("FMR(%) vs FNMR(%)         ", fontsize=14)

    ax.set_xticks(X + 0.5)
    ax.set_xticklabels(expressions)

    yticks = np.array(
        [
            -y_abs_max / 8,
            0,
            y_abs_max / 4,
            y_abs_max / 2,
            y_abs_max,
        ]
    )

    ax.set_yticks(yticks)
    ax.set_yticklabels([int(abs(y)) for y in yticks], fontsize=16)

    plt.axhline(0, linestyle="-", color="k")
    plt.ylim([-y_abs_max / 8, y_abs_max + 1])

    plt.legend()
    plt.grid()

    pdf.savefig(fig)

    pdf.close()
Пример #5
0
def multipie_pose_report(
    scores_dev,
    scores_eval,
    output_filename,
    titles,
    figsize=(16, 8),
    fmr_threshold=1e-3,
    colors=plt.cm.tab10.colors,
    optimal_threshold=False,
    threshold_eval=False,
):
    """
    Compute the multipie pose report, ploting the FNMR for each view point

    Parameters
    ----------

    scores_dev:

    scores_eval:

    output_filename:

    titles:

    figsize=(16, 8):

    fmr_threshold:

    colors:
       Color palete

    optimal_threshold: bool
      If set it to `True`, it will compute one decision threshold for each
      subprotocol (for each pose). Default to false.

    threshold_eval: bool
      If set it to `True` it will compute the threshold using the evaluation set.
      Default obviouslly to `False`.

    """

    cameras = [
        "11_0",
        "12_0",
        "09_0",
        "08_0",
        "13_0",
        "14_0",
        "05_1",
        "05_0",
        "04_1",
        "19_0",
        "20_0",
        "01_0",
        "24_0",
    ]

    angles = np.linspace(-90, 90, len(cameras))
    camera_to_angle = dict(zip(cameras, angles))

    pdf = PdfPages(output_filename)

    # Figure for eval plot
    fig = plt.figure(figsize=figsize)
    ax = fig.add_subplot(111)
    style_iterator = _get_colors_markers()

    for d_scores, e_scores, title, (linestyle, marker), color in zip(
        scores_dev, scores_eval, titles, style_iterator, colors
    ):

        # Load the score files and fill in the angle associated to each camera
        impostors_dev, genuines_dev = get_split_dataframe(d_scores)
        impostors_eval, genuines_eval = get_split_dataframe(e_scores)

        # loading the dask dataframes
        impostors_dev = impostors_dev.compute()
        genuines_dev = genuines_dev.compute()
        impostors_eval = impostors_eval.compute()
        genuines_eval = genuines_eval.compute()

        # Appending the angle
        impostors_dev["angle"] = impostors_dev["probe_camera"].map(
            camera_to_angle
        )
        genuines_dev["angle"] = genuines_dev["probe_camera"].map(
            camera_to_angle
        )
        impostors_eval["angle"] = impostors_eval["probe_camera"].map(
            camera_to_angle
        )
        genuines_eval["angle"] = genuines_eval["probe_camera"].map(
            camera_to_angle
        )

        angles = []
        eval_fmr_fnmr = []

        # Compute the min. HTER threshold on the Dev set
        threshold = None
        if not optimal_threshold:

            if threshold_eval:
                threshold = bob.measure.far_threshold(
                    impostors_eval["score"].to_numpy(),
                    genuines_eval["score"].to_numpy(),
                    fmr_threshold,
                )
            else:
                threshold = bob.measure.far_threshold(
                    impostors_dev["score"].to_numpy(),
                    genuines_dev["score"].to_numpy(),
                    fmr_threshold,
                )

        # Run the analysis per view angle
        for ((angle, i_dev), (_, g_dev), (_, i_eval), (_, g_eval),) in zip(
            impostors_dev.groupby("angle"),
            genuines_dev.groupby("angle"),
            impostors_eval.groupby("angle"),
            genuines_eval.groupby("angle"),
        ):

            if optimal_threshold:
                if threshold_eval:
                    threshold = bob.measure.far_threshold(
                        i_eval["score"].to_numpy(),
                        g_eval["score"].to_numpy(),
                        fmr_threshold,
                    )
                else:
                    threshold = bob.measure.far_threshold(
                        i_dev["score"].to_numpy(),
                        g_dev["score"].to_numpy(),
                        fmr_threshold,
                    )

            eval_fmr, eval_fnmr = bob.measure.farfrr(
                i_eval["score"].to_numpy(),
                g_eval["score"].to_numpy(),
                threshold,
            )
            # eval_fnmr = (eval_fnmr + eval_fmr) / 2

            angles.append(angle)
            eval_fmr_fnmr.append([eval_fmr, eval_fnmr])

            # eval_hter = (1 / 2 * (eval_far + eval_frr)) * 100
            # eval_hter = eval_frr * 100
            # eval_hters.append(eval_hter)

        # Update plots

        fnrms = [fnmr * 100 for fmr, fnmr in eval_fmr_fnmr]
        # fmrs = [-fmr * 100 for fmr, fnmr in eval_fmr_fnmr]
        plt.plot(
            angles,
            fnrms,
            label=title,
            linestyle=linestyle,
            marker=marker,
            linewidth=2,
            color=color,
        )

        # plt.plot(
        #    angles, fnrms, label=title, linestyle=linestyle, marker=marker, linewidth=2,
        # )
    if threshold_eval:
        plt.title(f"FNMR. at Eval. FMR@{fmr_threshold*100}%", fontsize=16)
    else:
        plt.title(f"FNMR. at Dev. FMR@{fmr_threshold*100}%", fontsize=16)
    plt.xlabel("Angle", fontsize=12)
    plt.ylabel("FNMR(%)", fontsize=14)
    plt.legend()
    plt.grid()

    # Plot finalization

    xticks = [-90, -75, -60, -45, -30, -15, 0, 15, 30, 45, 60, 75, 90]
    plt.xticks(xticks)
    ax.set_xticklabels(xticks, fontsize=10)

    yticks = np.array([0, 20, 40, 60, 80, 100])
    ax.set_yticks(yticks)
    ax.set_yticklabels(yticks, fontsize=12)

    pdf.savefig(fig)
    pdf.close()
Пример #6
0
def scface_report(
        scores_dev,
        scores_eval,
        output_filename,
        titles,
        fmr_threshold=1e-3,
        figsize=(16, 8),
        colors=plt.cm.tab10.colors,
):

    distances = [
        "close",
        "medium",
        "far",
    ]
    # "combined",

    eval_fmr_fnmr = dict()

    for (
            d_scores,
            e_scores,
            title,
    ) in zip(scores_dev, scores_eval, titles):

        eval_fmr_fnmr[title] = []

        # Load the score files and fill in the angle associated to each camera
        impostors_dev, genuines_dev = get_split_dataframe(d_scores)
        impostors_eval, genuines_eval = get_split_dataframe(e_scores)

        # loading the dask dataframes
        impostors_dev = impostors_dev.compute()
        genuines_dev = genuines_dev.compute()
        impostors_eval = impostors_eval.compute()
        genuines_eval = genuines_eval.compute()
        # Computing the threshold combining all distances

        # Computing the decision threshold
        i_dev = impostors_dev["score"].to_numpy()
        g_dev = genuines_dev["score"].to_numpy()

        threshold = bob.measure.far_threshold(
            i_dev,
            g_dev,
            far_value=fmr_threshold,
        )

        def compute_fmr_fnmr(impostor_scores, genuine_scores):
            eval_fmr, eval_fnmr = bob.measure.farfrr(
                impostor_scores["score"].to_numpy(),
                genuine_scores["score"].to_numpy(),
                threshold,
            )
            return eval_fmr, eval_fnmr

        for distance in distances:

            i_eval = impostors_eval.loc[impostors_eval.probe_distance ==
                                        distance]
            g_eval = genuines_eval.loc[genuines_eval.probe_distance ==
                                       distance]

            eval_fmr_fnmr[title].append(compute_fmr_fnmr(i_eval, g_eval))

        # Combined
        # eval_fmr_fnmr[title].append(compute_fmr_fnmr(impostors_eval, genuines_eval))

    pass

    # Plotting
    pdf = PdfPages(output_filename)

    # Figure for eval plot
    fig = plt.figure(figsize=figsize)
    ax = fig.add_subplot(111)

    width = 0.8 / len(titles)
    X = np.arange(len(distances))

    for i, (title, color) in enumerate(zip(titles, colors)):
        fmrs = [-1 * fmr * 100 for fmr, _ in eval_fmr_fnmr[title]]
        fnmrs = [fnmr * 100 for _, fnmr in eval_fmr_fnmr[title]]
        x_axis = X + (i + 1) * width - width / 2
        ax.bar(
            x_axis,
            fmrs,
            width,
            label=title,
            color=color,
            alpha=0.75,
            hatch="\\",
        )
        ax.bar(x_axis, fnmrs, width, color=color, alpha=0.5, hatch="/")

        # Writting the texts on top of the bar plots
        for i, fnmr, fmr in zip(x_axis, fnmrs, fmrs):
            plt.text(i - width / 2, fnmr + 1, str(round(fnmr, 1)), fontsize=10)
            plt.text(
                i - width / 2,
                fmr - 4.5,
                str(int(fmr)) if fmr <= 0.4 else str(round(abs(fmr), 1)),
                fontsize=10,
            )

    ax.set_axisbelow(True)

    # Plot finalization
    plt.title(
        f"FMR vs FNMR.  at Dev. FMR@{fmr_threshold*100}% under differente distances"
    )
    # ax.set_xlabel("Distances", fontsize=14)
    ax.set_ylabel("FMR(%) vs FNMR(%)                               ",
                  fontsize=14)
    plt.ylim([-25, 104])

    ax.set_xticks(X + 0.5)
    ax.set_xticklabels(distances, fontsize=16)

    yticks = np.array([-20, 0, 20, 40, 60, 80, 100])
    ax.set_yticks(yticks)
    ax.set_yticklabels(abs(yticks), fontsize=16)
    plt.axhline(0, linestyle="-", color="k")

    plt.legend()
    plt.grid()

    pdf.savefig(fig)
    pdf.close()
Пример #7
0
def mobio_report(
        scores_dev,
        scores_eval,
        output_filename,
        titles,
        fmr_threshold=1e-3,
        figsize=(16, 8),
        colors=plt.cm.tab10.colors,
):

    genders = [
        "m",
        "f",
    ]
    gender_labels = ["male", "female"]

    # colors = plt.cm.tab20.colors

    eval_fmr_fnmr = dict()

    for (
            d_scores,
            e_scores,
            title,
    ) in zip(scores_dev, scores_eval, titles):

        eval_fmr_fnmr[title] = []

        # Load the score files and fill in the angle associated to each camera
        impostors_dev, genuines_dev = get_split_dataframe(d_scores)
        impostors_eval, genuines_eval = get_split_dataframe(e_scores)

        # loading the dask dataframes
        impostors_dev = impostors_dev.compute()
        genuines_dev = genuines_dev.compute()
        impostors_eval = impostors_eval.compute()
        genuines_eval = genuines_eval.compute()
        # Computing the threshold combining all distances
        # Getting only the close distance to compute the threshold

        threshold = bob.measure.far_threshold(
            impostors_dev["score"].to_numpy(),
            genuines_dev["score"].to_numpy(),
            far_value=fmr_threshold,
        )

        def compute_fmr_fnmr(impostor_scores, genuine_scores):
            eval_fmr, eval_fnmr = bob.measure.farfrr(
                impostor_scores["score"].to_numpy(),
                genuine_scores["score"].to_numpy(),
                threshold,
            )
            return eval_fmr, eval_fnmr

        # Combined
        eval_fmr_fnmr[title].append(
            compute_fmr_fnmr(impostors_eval, genuines_eval))

        for gender in genders[1:]:

            i_eval = impostors_eval.loc[impostors_eval.probe_gender == gender]
            g_eval = genuines_eval.loc[genuines_eval.probe_gender == gender]

            eval_fmr_fnmr[title].append(compute_fmr_fnmr(i_eval, g_eval))

    pass

    # Plotting
    pdf = PdfPages(output_filename)

    # Figure for eval plot
    fig = plt.figure(figsize=figsize)
    ax = fig.add_subplot(111)

    width = 0.8 / len(titles)
    X = np.arange(len(genders))

    for i, (title, color) in enumerate(zip(titles, colors)):
        fmrs = [-1 * fmr * 100 for fmr, _ in eval_fmr_fnmr[title]]
        fnmrs = [fnmr * 100 for _, fnmr in eval_fmr_fnmr[title]]

        x_axis = X + (i + 1) * width - width / 2
        ax.bar(
            x_axis,
            fmrs,
            width,
            label=title,
            color=color,
            alpha=0.75,
            hatch="\\",
        )
        ax.bar(x_axis, fnmrs, width, color=color, alpha=0.5, hatch="/")

        # Writting the texts on top of the bar plots
        for i, fnmr, fmr in zip(x_axis, fnmrs, fmrs):
            plt.text(i - width / 2,
                     fnmr + 0.8,
                     str(round(fnmr, 2)),
                     fontsize=12)
            # print(i - width / 2)
            plt.text(i - width / 2,
                     fmr - 2.2,
                     str(round(abs(fmr), 2)),
                     fontsize=12)

    ax.set_axisbelow(True)

    # Plot finalization
    plt.title(f"FMR vs FNMR .  at Dev. FMR@{fmr_threshold*100}%")
    # ax.set_xlabel("Genders", fontsize=18)
    ax.set_ylabel("FMR(%) vs FNMR(%)                        ", fontsize=15)
    # plt.ylim([-5, 40])

    ax.set_xticks(X + 0.5)
    ax.set_xticklabels(gender_labels, fontsize=14)

    yticks = np.array([-5, 0, 5, 15, 25, 35])
    ax.set_yticks(yticks)
    ax.set_yticklabels(abs(yticks), fontsize=16)

    plt.axhline(0, linestyle="-", color="k")

    plt.legend()
    plt.grid()

    pdf.savefig(fig)
    pdf.close()