jasper-software / jasper

Official Repository for the JasPer Image Coding Toolkit
http://www.ece.uvic.ca/~mdadams/jasper
Other
223 stars 101 forks source link

Correct higher resolution level 9/7 energy weight approximations #385

Closed boxerab closed 3 months ago

boxerab commented 4 months ago

It's nice to see this project getting the attention it deserves.

I notice that the higher level 9/7 energy weights / L2 norms are currently approximations, and that exact values can be found in the OpenJPH project here.

With permission from @aous72, these approximations could be corrected.

Ideally, these values could be calculated through some script

Thanks!

mdadams commented 4 months ago

I would have to compute the correct values myself to be sure that they are correct. I do not have any script handy to compute these values, however.

boxerab commented 4 months ago

Thanks, I would be happy to put together a Python script to do the calculations if you post the formula needed.

There ought to be one common project to store these kinds of tables and scripts, so the 5+ open source JPEG 2000 codecs don't have to re-invent the wheel.

boxerab commented 4 months ago

PyWavelet and scipy convolve might be useful here.

A sample script:

import pywt
import numpy as np
from scipy.signal import convolve

def calculate_filter_norms(wavelet_name='bior2.2', levels=32):
    wavelet = pywt.Wavelet(wavelet_name)

    # Start with the original filters
    filters = {
        'dec_lo': np.array(wavelet.dec_lo, dtype=np.float64),
        'dec_hi': np.array(wavelet.dec_hi, dtype=np.float64),
        'rec_lo': np.array(wavelet.rec_lo, dtype=np.float64),
        'rec_hi': np.array(wavelet.rec_hi, dtype=np.float64)
    }

    # Dictionary to store norms at each level
    norms = {0: {key: np.linalg.norm(f) for key, f in filters.items()}}

    # Calculate norms across levels
    for level in range(1, levels):
        new_filters = {}
        for key in filters:
            # Use direct convolution and normalize
            new_filter = convolve(filters[key], filters[key], mode='full', method='direct')
            new_filter /= np.linalg.norm(new_filter)  # Normalizing the filter
            new_filters[key] = new_filter
            norms[level] = {key: np.linalg.norm(new_filter)}

        # Update filters to the new filters
        filters = new_filters

    return norms

# Example usage
norms = calculate_filter_norms()
for level, filter_norms in norms.items():
    print(f"Level {level}:")
    for filter_type, norm in filter_norms.items():
        print(f"  {filter_type} norm: {norm}")