Example #1
0
    def test_angular_weighted_illegal(self):
        """Test that only possible to use weighing when single sample."""
        y_true = np.zeros((2, 10, 11, 2))
        y_pred = y_true

        with pytest.raises(ValueError):
            angular_error_of(y_true, y_pred, weighted=True)
Example #2
0
    def test_angular_zero(self):
        """Test that zero vectors lead to nans."""
        y_true = np.zeros((5, 10, 11, 2))
        y_pred = np.ones_like(y_true)

        assert np.all(np.isnan(angular_error_of(y_true, y_pred)[1]))
        assert np.all(np.isnan(angular_error_of(y_pred, y_true)[1]))
Example #3
0
    def test_angular_weighted_vs_unweighted(self):
        # One 90 (weight 2) and 180 (weight 1) degrees from the x axis
        # nonweighted_average = 135, weighted = 120
        delta_x_true = np.array([[0, 0], [0, -1]])
        delta_y_true = np.array([[2, 0], [0, 0]])

        delta_x_pred = np.ones_like(delta_x_true)  # x axis is the vectors
        delta_y_pred = np.zeros_like(delta_y_true)

        df_true = DisplacementField(delta_x_true, delta_y_true)
        df_pred = DisplacementField(delta_x_pred, delta_y_pred)

        ae_nonweighted, _ = angular_error_of([df_true], [df_pred],
                                             weighted=False)
        ae_weighted, _ = angular_error_of([df_true], [df_pred], weighted=True)

        assert ae_nonweighted == pytest.approx(135)
        assert ae_weighted == pytest.approx(120)
Example #4
0
    def test_angular_norm_independence(self, c):
        """Test that only angle matters for `angular_error_of`."""

        y_true = np.random.random((5, 10, 11, 2))
        y_pred = y_true * c

        metric_average, metric_per_output = angular_error_of(y_true, y_pred)

        assert metric_average == pytest.approx(0, abs=1e-5)
        assert np.allclose(metric_per_output, np.zeros((10, 11)), atol=1e-5)
Example #5
0
    def test_angular_norm_perpendicular(self, c):
        """Test that only angle matters for `angular_error_of`."""

        y_true = np.random.random((5, 10, 11, 2))
        y_pred = np.empty_like(y_true)
        y_pred[..., 0] = y_true[..., 1] * c
        y_pred[..., 1] = -y_true[..., 0] * c

        metric_average, metric_per_output = angular_error_of(y_true, y_pred)

        assert metric_average == pytest.approx(90, abs=1e-5)
        assert np.allclose(metric_per_output,
                           90 * np.ones((10, 11)),
                           atol=1e-5)
def generate_df_plots(df_true, df_pred, filepath=None, figsize=(15, 15)):
    """Generate displacement vector plots.

    df_true : DisplacementField
        Truth. Assumes that shape is (320, 456).

    df_pred : DisplacementField
        Prediction. Assumes that shape is (320, 456)

    filepath : None or pathlib.Path
        If specified, then the path to where the figure saved as a PNG image.
        If not specified, then shown.
    """
    plt.ioff()
    fig, (
        (ax_norm, ax_norm_p),
        (ax_angle, ax_angle_p),
        (ax_jacob, ax_jacob_p),
        (ax_grid, ax_grid_p),
    ) = plt.subplots(4, 2, figsize=figsize)

    df_base = DisplacementField.generate(
        (320, 456), approach="affine_simple",
        translation_x=1)  # make the angle work

    bar_norm = fig.add_axes([0.95, 0.772, 0.03, 0.2])
    bar_angle = fig.add_axes([0.95, 0.525, 0.03, 0.2])
    bar_jacob = fig.add_axes([0.95, 0.275, 0.03, 0.2])

    # Jacobian
    jacob_true = df_true.jacobian
    jacob_pred = df_pred.jacobian
    jacob_vmin, jacob_vmax = min(jacob_true.min(), jacob_pred.min()), max(
        jacob_true.max(), jacob_pred.max())
    ax_jacob.set_axis_off()
    sns.heatmap(
        jacob_true,
        ax=ax_jacob,
        cbar_ax=bar_jacob,
        center=0,
        cmap="seismic_r",
        vmin=jacob_vmin,
        vmax=jacob_vmax,
    )
    ax_jacob.set_title("Jacobian - Ground Truth")

    ax_jacob_p.set_axis_off()
    sns.heatmap(
        jacob_pred,
        ax=ax_jacob_p,
        cbar_ax=bar_jacob,
        center=0,
        cmap="seismic_r",
        vmin=jacob_vmin,
        vmax=jacob_vmax,
    )
    ax_jacob_p.set_title("Jacobian - Predicted")

    # GRID
    img_grid = create_grid((320, 456))
    img_grid_warped = df_true.warp(img_grid)
    ax_grid.set_axis_off()
    ax_grid.imshow(img_grid_warped, cmap="gray")
    ax_grid.set_title("Warped Grid - Ground Truth")

    img_grid_warped_p = df_pred.warp(img_grid)
    ax_grid_p.set_axis_off()
    ax_grid_p.imshow(img_grid_warped_p, cmap="gray")
    ax_grid_p.set_title("Warped Grid - Predicted")

    # NORM
    norm_vmin, norm_vmax = 0, max(df_true.norm.max(), df_pred.norm.max())
    ax_norm.set_axis_off()
    sns.heatmap(df_true.norm,
                ax=ax_norm,
                cbar_ax=bar_norm,
                vmin=norm_vmin,
                vmax=norm_vmax)
    ax_norm.set_title("Norm - Ground Truth")

    ax_norm_p.set_axis_off()
    sns.heatmap(df_pred.norm,
                ax=ax_norm_p,
                cbar_ax=bar_norm,
                vmin=norm_vmin,
                vmax=norm_vmax)
    ax_norm_p.set_title("Norm - Predicted")

    # Angle
    angle_vmin, angle_vmax = 0, 180
    ax_angle.set_title("Angle wrt positive x-axis - Ground Truth")
    ax_angle.set_axis_off()
    angles = angular_error_of([df_true], [df_base])[1]
    sns.heatmap(
        angles,
        ax=ax_angle,
        cbar_ax=bar_angle,
        mask=~np.isfinite(angles),
        cmap="hot_r",
        vmin=angle_vmin,
        vmax=angle_vmax,
    )

    ax_angle_p.set_title("Angle wrt positive x-axis - Predicted")
    ax_angle_p.set_axis_off()
    angles = angular_error_of([df_pred], [df_base])[1]
    sns.heatmap(
        angles,
        ax=ax_angle_p,
        cbar_ax=bar_angle,
        mask=~np.isfinite(angles),
        cmap="hot_r",
        vmin=angle_vmin,
        vmax=angle_vmax,
    )
    # fig.tight_layout(rect=[0, 0, .95, 1])

    if filepath is not None:
        fig.savefig(str(filepath))
    else:
        plt.show()