107 def __call__(self, intensities: FloatImagePlane) -> FloatImagePlane:
108 """Compress and enhance luminance using multi-stage processing.
110 This method applies the configured luminance compression algorithm to
111 the input image. The processing pipeline includes optional denoising,
112 asinh stretching, linear contrast manipulation, midtone adjustment,
113 contrast equalization, and tone adjustment.
117 intensities : `FloatImagePlane`
118 Input image with pixel intensities. This FloatImagePlane should
119 contain the luminance data to be compressed.
123 result : `FloatImagePlane`
124 The processed image with luminance compression applied. Values
125 are clipped to the range [0, 1].
129 The processing pipeline consists of the following stages:
131 1. Optional wavelet denoising if doDenoise is True
132 2. Asinh stretching with configurable stretch parameter
133 3. Linear contrast adjustment using highlight, shadow parameters
134 4. Midtone adjustment using midtone parameter
135 5. Optional contrast equalization if equalizerLevels is configured
136 6. Optional tone adjustment if toneAdjustment is configured
137 7. Final clipping to [0, 1] range
139 The configuration fields (stretch, highlight, shadow, midtone,
140 equalizerLevels, toneAdjustment, toneWidth) control the behavior
141 of each processing stage.
144 intensities = skimage.restoration.denoise_wavelet(intensities)
147 intensities = abs(intensities)
148 nj_to_lum = rgb.RGB_to_Oklab(
149 np.array([[[self.
floor, self.
floor, self.
floor]]], dtype=float), (0.28, 0.28)
152 bottom = (np.arcsinh(nj_to_lum * self.
stretch) - 0.2 * top) / 0.8
153 intensities = (np.arcsinh(intensities * self.
stretch) - bottom) / (top - bottom)
154 logger.debug(
"arcsinh max %.4f", intensities.max())
155 intensities = np.clip(intensities, 0, 1)
157 logger.debug(
"post lin stretch max %.4f", intensities.max())
158 intensities = ((self.
midtone - 1) * intensities) / (
161 logger.debug(
"midtone adjustment max %.4f", intensities.max())
162 intensities = np.clip(intensities, 0.0, self.
max)
166 logger.debug(
"equalizer max %.4f", intensities.max())
169 intensities = np.clip(intensities, 0, self.
max)
172 intensities = np.clip(intensities, 0, 1)