Пример #1
0
def test_quantisation_index_bound():
    wavelet_index = WaveletFilters.haar_with_shift
    wavelet_index_ho = WaveletFilters.haar_with_shift
    dwt_depth = 1
    dwt_depth_ho = 0

    quantisation_matrix = {
        0: {
            "LL": 10
        },
        1: {
            "LH": 10,
            "HL": 10,
            "HH": 10
        },
    }

    picture_bit_width = 10

    (
        analysis_signal_bounds,
        synthesis_signal_bounds,
        analysis_test_patterns,
        synthesis_test_patterns,
    ) = static_filter_analysis(
        wavelet_index,
        wavelet_index_ho,
        dwt_depth,
        dwt_depth_ho,
    )

    (
        concrete_analysis_signal_bounds,
        concrete_synthesis_signal_bounds,
    ) = evaluate_filter_bounds(
        wavelet_index,
        wavelet_index_ho,
        dwt_depth,
        dwt_depth_ho,
        analysis_signal_bounds,
        synthesis_signal_bounds,
        picture_bit_width,
    )

    max_qi = quantisation_index_bound(
        concrete_analysis_signal_bounds,
        quantisation_matrix,
    )

    max_coeff_magnitude = max(
        max(abs(lower), abs(upper))
        for lower, upper in concrete_analysis_signal_bounds.values())

    assert forward_quant(max_coeff_magnitude, max_qi - 10) == 0
    assert forward_quant(max_coeff_magnitude, max_qi - 11) != 0
Пример #2
0
def test_maximum_dequantised_magnitude(value, sign):
    # Empirically check that any lower quantisation index produces a non-zero
    # result
    value *= sign
    expectation = maximum_dequantised_magnitude(value)

    for qi in range(maximum_useful_quantisation_index(value) + 1):
        if expectation > 0:
            assert inverse_quant(forward_quant(value, qi), qi) <= expectation
        elif expectation < 0:
            assert inverse_quant(forward_quant(value, qi), qi) >= expectation
        else:
            assert inverse_quant(forward_quant(value, qi), qi) == 0
    def quant_dequant(level, orient, value):
        qi = max(0, quantisation_index - state["quant_matrix"][level][orient])

        quantised_value = forward_quant(value, qi)
        num_bits[0] += signed_exp_golomb_length(quantised_value)

        return inverse_quant(quantised_value, qi)
Пример #4
0
def test_forward_quant():
    for coeff in list(range(100)) + list(range(100, 10000, 997)):
        for sign in [1, -1]:
            for quant_index in range(64):
                value = coeff * sign
                quant_value = forward_quant(value, quant_index)
                dequant_value = inverse_quant(quant_value, quant_index)
                error = dequant_value - value
                assert abs(error * 4) <= quant_factor(quant_index)
def quantise_coeffs(transform_coeffs, qi, quantisation_matrix={}):
    return {
        level: {
            orient: [[
                inverse_quant(
                    forward_quant(
                        value,
                        max(
                            0, qi -
                            quantisation_matrix.get(level, {}).get(orient, 0)),
                    ),
                    max(0, qi -
                        quantisation_matrix.get(level, {}).get(orient, 0)),
                ) for value in row
            ] for row in array]
            for orient, array in orients.items()
        }
        for level, orients in transform_coeffs.items()
    }
Пример #6
0
def test_maximum_useful_quantisation_index(value):
    # Empirically check that any lower quantisation index produces a non-zero
    # result
    index = maximum_useful_quantisation_index(value)
    assert forward_quant(value, index) == 0
    assert forward_quant(value, index - 1) != 0
def quant_roundtrip(value, qi):
    return inverse_quant(forward_quant(value, qi), qi)
Пример #8
0
def test_optimise_synthesis_test_patterns():
    wavelet_index = WaveletFilters.haar_with_shift
    wavelet_index_ho = WaveletFilters.le_gall_5_3
    dwt_depth = 1
    dwt_depth_ho = 0

    quantisation_matrix = {
        0: {
            "LL": 0
        },
        1: {
            "LH": 0,
            "HL": 0,
            "HH": 0
        },
    }

    picture_bit_width = 10
    input_min = -512
    input_max = 511

    (
        analysis_signal_bounds,
        synthesis_signal_bounds,
        analysis_test_patterns,
        synthesis_test_patterns,
    ) = static_filter_analysis(
        wavelet_index,
        wavelet_index_ho,
        dwt_depth,
        dwt_depth_ho,
    )

    (
        concrete_analysis_signal_bounds,
        concrete_synthesis_signal_bounds,
    ) = evaluate_filter_bounds(
        wavelet_index,
        wavelet_index_ho,
        dwt_depth,
        dwt_depth_ho,
        analysis_signal_bounds,
        synthesis_signal_bounds,
        picture_bit_width,
    )

    max_quantisation_index = quantisation_index_bound(
        concrete_analysis_signal_bounds,
        quantisation_matrix,
    )

    random_state = np.random.RandomState(1)
    number_of_searches = 2
    terminate_early = None
    added_corruption_rate = 0.5
    removed_corruption_rate = 0.0
    base_iterations = 10
    added_iterations_per_improvement = 1

    optimised_synthesis_test_patterns = optimise_synthesis_test_patterns(
        wavelet_index,
        wavelet_index_ho,
        dwt_depth,
        dwt_depth_ho,
        quantisation_matrix,
        picture_bit_width,
        synthesis_test_patterns,
        max_quantisation_index,
        random_state,
        number_of_searches,
        terminate_early,
        added_corruption_rate,
        removed_corruption_rate,
        base_iterations,
        added_iterations_per_improvement,
    )

    # As a sanity check, ensure that the test patterns provided do produce the
    # values they say they do at the quantisation indices claimed
    state = State(
        wavelet_index=wavelet_index,
        wavelet_index_ho=wavelet_index_ho,
        dwt_depth=dwt_depth,
        dwt_depth_ho=dwt_depth_ho,
    )
    for level, array_name, x, y in optimised_synthesis_test_patterns:
        # Only check the final decoder output (as the pseudocode doesn't
        # provide access to other arrays)
        if level != dwt_depth + dwt_depth_ho or array_name != "Output":
            continue

        ts = optimised_synthesis_test_patterns[(level, array_name, x, y)]

        picture, _ = convert_test_pattern_to_padded_picture_and_slice(
            ts.pattern,
            input_min,
            input_max,
            dwt_depth,
            dwt_depth_ho,
        )

        tx, ty = ts.target
        coeffs = dwt(state, picture.tolist())

        qi = ts.quantisation_index
        quantised_coeffs = {
            level: {
                orient: [[
                    inverse_quant(forward_quant(value, qi), qi)
                    for value in row
                ] for row in rows]
                for orient, rows in orients.items()
            }
            for level, orients in coeffs.items()
        }

        decoded_picture = idwt(state, quantised_coeffs)

        assert decoded_picture[ty][tx] == ts.decoded_value