Parameter Estimation¶
To use the Anscombe Transform codec effectively, you need two key parameters: zero_level and conversion_gain.
See Codec Parameters for detailed explanations of what these parameters mean and how they relate to your camera hardware.
This guide explains how to estimate these parameters from your data.
The compute_conversion_gain() Function¶
The codec provides a built-in parameter estimation function:
import numpy as np
from anscombe_transform.estimate import compute_conversion_gain
from anscombe_transform.common import make_demo_data
# Set seed for reproducibility
np.random.seed(0)
# Generate demo data
movie = make_demo_data(n_frames=100)
# Estimate parameters
result = compute_conversion_gain(movie)
print(f"Conversion gain: {result['conversion_gain']:.3f}")
#> Conversion gain: 29.866
print(f"Zero level: {result['zero_level']:.3f}")
#> Zero level: 17.814
Input Requirements¶
The compute_conversion_gain() function expects:
- Shape: (time, height, width) - temporal axis must be first
- Data type: Integer or float
- Minimum frames: At least 10-20 frames for reliable estimation
- Static scene: Works best when the scene doesn't change much over time
How It Works¶
The function uses the noise transfer function approach:
- Compute temporal variance: Calculate sample-wise variance across time
- Compute temporal mean: Calculate sample-wise mean across time
- Fit noise model: Use HuberRegressor to fit
variance = slope * mean + intercept
For Poisson noise: variance = conversion_gain * (mean - zero_level)
Therefore:
- conversion_gain = slope
- zero_level = -intercept / slope
Return Value¶
The function returns a dictionary with:
import numpy as np
from sklearn.linear_model import HuberRegressor
result = {
'conversion_gain': float, # The conversion gain (signal units per event)
'zero_level': float, # The baseline signal level
'variance': np.ndarray, # Computed sample-wise variance
'model': HuberRegressor, # The fitted regression model
'counts': np.ndarray, # Event counts per sample
'min_intensity': int, # Minimum intensity value
'max_intensity': int, # Maximum intensity value
}
Validation¶
After estimating parameters, validate them:
import numpy as np
from anscombe_transform import AnscombeTransformV3
from anscombe_transform.estimate import compute_conversion_gain
from anscombe_transform.common import make_demo_data
# Set seed for reproducibility
np.random.seed(0)
# Generate test movie data
movie = make_demo_data(n_frames=100)
# Estimate parameters
result = compute_conversion_gain(movie)
# Create codec with estimated parameters
codec = AnscombeTransformV3(
zero_level=result['zero_level'],
conversion_gain=result['conversion_gain']
)
# Print estimated parameters
print(f"Estimated zero level: {result['zero_level']:.1f}")
#> Estimated zero level: 17.8
print(f"Estimated conversion gain: {result['conversion_gain']:.3f}")
#> Estimated conversion gain: 29.866
Example Workflow¶
import numpy as np
from anscombe_transform.estimate import compute_conversion_gain
from anscombe_transform import AnscombeTransformV3
from anscombe_transform.common import make_demo_data
import zarr
# Set seed for reproducibility
np.random.seed(0)
# 1. Load temporal data (generate sample movie)
movie = make_demo_data(n_frames=100)
# 2. Estimate parameters
params = compute_conversion_gain(movie)
print(f"Conversion gain: {params['conversion_gain']:.3f} ADU/event")
#> Conversion gain: 29.866 ADU/event
print(f"Zero level: {params['zero_level']:.1f} ADU")
#> Zero level: 17.8 ADU
# 3. Create codec with estimated parameters
codec = AnscombeTransformV3(
zero_level=params['zero_level'],
conversion_gain=params['conversion_gain']
)
# 4. Create Zarr array in memory
store = zarr.storage.MemoryStore()
arr = zarr.create_array(
store=store,
shape=movie.shape,
chunks=(10, 512, 512),
dtype='int16',
filters=[codec],
zarr_format=3
)
# 5. Compress data
arr[:] = movie