예제 #1
0
def bundle_get_static_filter_analysis(
    file_or_filename,
    wavelet_index,
    wavelet_index_ho,
    dwt_depth,
    dwt_depth_ho,
):
    """
    Read a static filter analysis for a particular filter configuration from
    a bundle. Raises :py:exc:`KeyError` if no matching analysis is present in
    the bundle.
    
    Parameters
    ==========
    file_or_filename : file-like or str
        The bundle to read.
    wavelet_index : int
    wavelet_index_ho : int
    dwt_depth : int
    dwt_depth_ho : int
    
    Returns
    =======
    analysis_signal_bounds : {(level, array_name, x, y): (lower_bound_exp, upper_bound_exp), ...}
    synthesis_signal_bounds : {(level, array_name, x, y): (lower_bound_exp, upper_bound_exp), ...}
    analysis_test_patterns: {(level, array_name, x, y): :py:class:`~vc2_bit_widths.patterns.TestPatternSpecification`, ...}
    synthesis_test_patterns: {(level, array_name, x, y): :py:class:`~vc2_bit_widths.patterns.TestPatternSpecification`, ...}
        See :py:func:`vc2_bit_widths.helpers.static_filter_analysis`.
    """
    analysis = bundle_get_serialised_static_filter_analysis(
        file_or_filename,
        wavelet_index,
        wavelet_index_ho,
        dwt_depth,
        dwt_depth_ho,
    )

    return (
        deserialise_signal_bounds(analysis["analysis_signal_bounds"]),
        deserialise_signal_bounds(analysis["synthesis_signal_bounds"]),
        deserialise_test_pattern_specifications(
            TestPatternSpecification, analysis["analysis_test_patterns"]),
        deserialise_test_pattern_specifications(
            TestPatternSpecification, analysis["synthesis_test_patterns"]),
    )
예제 #2
0
def deserialise_static_analysis(data):
    """
    Deserialise contents in place.
    """
    data["analysis_signal_bounds"] = deserialise_signal_bounds(
        data["analysis_signal_bounds"],
    )
    data["synthesis_signal_bounds"] = deserialise_signal_bounds(
        data["synthesis_signal_bounds"],
    )
    data["analysis_test_patterns"] = deserialise_test_pattern_specifications(
        TPS,
        data["analysis_test_patterns"],
    )
    data["synthesis_test_patterns"] = deserialise_test_pattern_specifications(
        TPS,
        data["synthesis_test_patterns"],
    )
    return data
예제 #3
0
def main(args=None):
    args = parse_args(args)
    
    # Load precomputed signal bounds
    static_filter_analysis = json.load(args.static_filter_analysis)
    
    quantisation_matrix = parse_quantisation_matrix_argument(
        args.custom_quantisation_matrix,
        static_filter_analysis["wavelet_index"],
        static_filter_analysis["wavelet_index_ho"],
        static_filter_analysis["dwt_depth"],
        static_filter_analysis["dwt_depth_ho"],
    )
    
    analysis_signal_bounds = deserialise_signal_bounds(
        static_filter_analysis["analysis_signal_bounds"]
    )
    synthesis_signal_bounds = deserialise_signal_bounds(
        static_filter_analysis["synthesis_signal_bounds"]
    )
    
    (
        concrete_analysis_signal_bounds,
        concrete_synthesis_signal_bounds,
    ) = evaluate_filter_bounds(
        static_filter_analysis["wavelet_index"],
        static_filter_analysis["wavelet_index_ho"],
        static_filter_analysis["dwt_depth"],
        static_filter_analysis["dwt_depth_ho"],
        analysis_signal_bounds,
        synthesis_signal_bounds,
        args.picture_bit_width,
    )
    
    print(quantisation_index_bound(
        concrete_analysis_signal_bounds,
        quantisation_matrix,
    ))
    
    return 0
def test_serialise_signal_bounds():
    before = OrderedDict([
        ((1, "LH", 2, 3), (
            LinExp("foo")/2,
            LinExp("bar")/4,
        )),
        ((2, "HL", 3, 2), (
            LinExp("qux")/8,
            LinExp("quo")/16,
        )),
    ])
    after = serialise_signal_bounds(before)
    after = json_roundtrip(after)
    
    assert after == [
        {
            "level": 1,
            "array_name": "LH",
            "phase": [2, 3],
            "lower_bound": [
                {"symbol": "foo", "numer": "1", "denom": "2"},
            ],
            "upper_bound": [
                {"symbol": "bar", "numer": "1", "denom": "4"},
            ],
        },
        {
            "level": 2,
            "array_name": "HL",
            "phase": [3, 2],
            "lower_bound": [
                {"symbol": "qux", "numer": "1", "denom": "8"},
            ],
            "upper_bound": [
                {"symbol": "quo", "numer": "1", "denom": "16"},
            ],
        },
    ]
    
    assert deserialise_signal_bounds(after) == before
예제 #5
0
    else:
        if args.picture_bit_width is None:
            parser.error("A --picture-bit-width/-b argument or a set of "
                         "optimised synthesis test signals are required.")

    return args


args = parse_args()

if args.verbose:
    logging.basicConfig(level=logging.INFO)

# Load precomputed signal bounds
static_filter_analysis = json.load(args.static_filter_analysis)
analysis_signal_bounds = deserialise_signal_bounds(
    static_filter_analysis["analysis_signal_bounds"])
synthesis_signal_bounds = deserialise_signal_bounds(
    static_filter_analysis["synthesis_signal_bounds"])

# Load precomputed test signals
analysis_test_signals = deserialise_test_signals(
    TestSignalSpecification, static_filter_analysis["analysis_test_signals"])
synthesis_test_signals = deserialise_test_signals(
    TestSignalSpecification, static_filter_analysis["synthesis_test_signals"])

# Load optimised synthesis signal
if args.optimised_synthesis_test_signals is not None:
    optimised_json = json.load(args.optimised_synthesis_test_signals)

    assert static_filter_analysis["wavelet_index"] == optimised_json[
        "wavelet_index"]
예제 #6
0
def load_filter_analysis(
    static_filter_analysis_file,
    optimised_synthesis_patterns_file,
    quantisation_matrix_argument,
    picture_bit_width,
):
    """
    Load a static filter analysis and optionally a set of optimised synthesis
    test patterns, returning all of the loaded data.
    
    Parameters
    ==========
    static_filter_analysis_file : :py:class:`file`
        An open file ready to read the static filter analysis data from a JSON
        file.
    optimised_synthesis_patterns_file : :py:class:`file` or None
        An open file ready to read a set of optimised synthesis test patterns
        for a JSON file. If None, synthesis test patterns will be read from the
        ``static_filter_analysis_file`` instead.
    quantisation_matrix_argument : [str, ...] or None
        The --custom-quantisation-matrix argument which will be parsed (if
        optimised_synthesis_patterns_file is not provided)
    picture_bit_width : int or None
        The --picture-bit-width argument which will be used if no
        optimised_synthesis_test_patterns file is provided.
    
    Returns
    =======
    wavelet_index : int
    wavelet_index_ho : int
    dwt_depth : int
    dwt_depth_ho : int
    quantisation_matrix : {level: {orient: value, ...}, ...}
    picture_bit_width : int
    max_quantisation_index : int
    concrete_analysis_bounds : {(level, array_name, x, y): (lo, hi), ...}
    concrete_synthesis_bounds : {(level, array_name, x, y): (lo, hi), ...}
    analysis_test_patterns : {(level, array_name, x, y): :py:class:`~vc2_bit_widths.patterns.TestPatternSpecification`, ...}
    synthesis_test_patterns : {(level, array_name, x, y): :py:class:`~vc2_bit_widths.patterns.TestPatternSpecification`, ...}
    """
    # Load precomputed signal bounds
    static_filter_analysis = json.load(static_filter_analysis_file)
    analysis_signal_bounds = deserialise_signal_bounds(
        static_filter_analysis["analysis_signal_bounds"]
    )
    synthesis_signal_bounds = deserialise_signal_bounds(
        static_filter_analysis["synthesis_signal_bounds"]
    )
    
    # Load precomputed test patterns
    analysis_test_patterns = deserialise_test_pattern_specifications(
        TestPatternSpecification,
        static_filter_analysis["analysis_test_patterns"]
    )
    synthesis_test_patterns = deserialise_test_pattern_specifications(
        TestPatternSpecification,
        static_filter_analysis["synthesis_test_patterns"]
    )
    
    # Load optimised synthesis signal
    if optimised_synthesis_patterns_file is not None:
        optimised_json = json.load(optimised_synthesis_patterns_file)
        
        assert static_filter_analysis["wavelet_index"] == optimised_json["wavelet_index"]
        assert static_filter_analysis["wavelet_index_ho"] == optimised_json["wavelet_index_ho"]
        assert static_filter_analysis["dwt_depth"] == optimised_json["dwt_depth"]
        assert static_filter_analysis["dwt_depth_ho"] == optimised_json["dwt_depth_ho"]
        
        picture_bit_width = optimised_json["picture_bit_width"]
        
        quantisation_matrix = deserialise_quantisation_matrix(
            optimised_json["quantisation_matrix"]
        )
        
        synthesis_test_patterns = deserialise_test_pattern_specifications(
            OptimisedTestPatternSpecification,
            optimised_json["optimised_synthesis_test_patterns"]
        )
    else:
        quantisation_matrix = parse_quantisation_matrix_argument(
            quantisation_matrix_argument,
            static_filter_analysis["wavelet_index"],
            static_filter_analysis["wavelet_index_ho"],
            static_filter_analysis["dwt_depth"],
            static_filter_analysis["dwt_depth_ho"],
        )
    
    # Compute signal bounds for all specified bit widths
    #
    # analysis_bounds_dicts = [{(level, array_name, x, y): (lower_bound, upper_bound), ...}, ...]
    # synthesis_bounds_dicts = same as above
    concrete_analysis_bounds, concrete_synthesis_bounds = evaluate_filter_bounds(
        static_filter_analysis["wavelet_index"],
        static_filter_analysis["wavelet_index_ho"],
        static_filter_analysis["dwt_depth"],
        static_filter_analysis["dwt_depth_ho"],
        analysis_signal_bounds,
        synthesis_signal_bounds,
        picture_bit_width,
    )
    
    # Find the maximum quantisation index for each bit width
    max_quantisation_index = quantisation_index_bound(
        concrete_analysis_bounds,
        quantisation_matrix,
    )
    
    return (
        static_filter_analysis["wavelet_index"],
        static_filter_analysis["wavelet_index_ho"],
        static_filter_analysis["dwt_depth"],
        static_filter_analysis["dwt_depth_ho"],
        quantisation_matrix,
        picture_bit_width,
        max_quantisation_index,
        concrete_analysis_bounds,
        concrete_synthesis_bounds,
        analysis_test_patterns,
        synthesis_test_patterns,
    )
예제 #7
0
def main(args=None):
    args = parse_args(args)

    if args.verbose:
        logging.basicConfig(level=logging.INFO)

    static_filter_analysis = json.load(args.static_filter_analysis)

    quantisation_matrix = parse_quantisation_matrix_argument(
        args.custom_quantisation_matrix,
        static_filter_analysis["wavelet_index"],
        static_filter_analysis["wavelet_index_ho"],
        static_filter_analysis["dwt_depth"],
        static_filter_analysis["dwt_depth_ho"],
    )

    analysis_signal_bounds = deserialise_signal_bounds(
        static_filter_analysis["analysis_signal_bounds"])
    synthesis_signal_bounds = deserialise_signal_bounds(
        static_filter_analysis["synthesis_signal_bounds"])
    synthesis_test_patterns = deserialise_test_pattern_specifications(
        TestPatternSpecification,
        static_filter_analysis["synthesis_test_patterns"])

    (
        concrete_analysis_signal_bounds,
        concrete_synthesis_signal_bounds,
    ) = evaluate_filter_bounds(
        static_filter_analysis["wavelet_index"],
        static_filter_analysis["wavelet_index_ho"],
        static_filter_analysis["dwt_depth"],
        static_filter_analysis["dwt_depth_ho"],
        analysis_signal_bounds,
        synthesis_signal_bounds,
        args.picture_bit_width,
    )

    max_quantisation_index = quantisation_index_bound(
        concrete_analysis_signal_bounds,
        quantisation_matrix,
    )

    random_state = np.random.RandomState(args.seed)

    optimised_synthesis_test_patterns = optimise_synthesis_test_patterns(
        wavelet_index=static_filter_analysis["wavelet_index"],
        wavelet_index_ho=static_filter_analysis["wavelet_index_ho"],
        dwt_depth=static_filter_analysis["dwt_depth"],
        dwt_depth_ho=static_filter_analysis["dwt_depth_ho"],
        quantisation_matrix=quantisation_matrix,
        picture_bit_width=args.picture_bit_width,
        synthesis_test_patterns=synthesis_test_patterns,
        max_quantisation_index=max_quantisation_index,
        random_state=random_state,
        number_of_searches=args.number_of_searches,
        terminate_early=args.terminate_early,
        added_corruption_rate=args.added_corruption_rate,
        removed_corruption_rate=args.removed_corruption_rate,
        base_iterations=args.base_iterations,
        added_iterations_per_improvement=args.added_iterations_per_improvement,
    )

    out = {
        "wavelet_index":
        static_filter_analysis["wavelet_index"],
        "wavelet_index_ho":
        static_filter_analysis["wavelet_index_ho"],
        "dwt_depth":
        static_filter_analysis["dwt_depth"],
        "dwt_depth_ho":
        static_filter_analysis["dwt_depth_ho"],
        "picture_bit_width":
        args.picture_bit_width,
        "quantisation_matrix":
        serialise_quantisation_matrix(quantisation_matrix, ),
        "optimised_synthesis_test_patterns":
        serialise_test_pattern_specifications(
            OptimisedTestPatternSpecification,
            optimised_synthesis_test_patterns,
        )
    }

    json.dump(out, args.output)
    args.output.write("\n")

    return 0