huge changes

This commit is contained in:
2025-06-19 15:31:45 -04:00
parent 2bcf6a3325
commit bb253155fb
18 changed files with 4243 additions and 129 deletions

View File

@ -314,8 +314,8 @@ def negadoctor_process(img_aces_negative: np.ndarray,
compressed_highlights = soft_clip_param + (1.0 - e_to_gamma) * soft_clip_comp
output_pixels = np.where(print_gamma > soft_clip_param, compressed_highlights, print_gamma)
return np.clip(output_pixels, 0.0, 1.0) # Final clip to 0-1 range
return np.clip(output_pixels, 0.0, None) # Final clip to 0-Inf range
# --- Main Execution ---
@ -371,10 +371,26 @@ if __name__ == "__main__":
print("Converting to ACEScg...")
# img_linear_srgb = colour.gamma_correct(img_float, 1/2.2, 'ITU-R BT.709') # Approximate sRGB EOTF decoding
img_linear_srgb = colour.models.eotf_sRGB(img_float) # More accurate sRGB EOTF decoding
img_acescg = colour.RGB_to_RGB(img_linear_srgb,
colour.models.RGB_COLOURSPACE_sRGB,
colour.models.RGB_COLOURSPACE_ACESCG)
img_acescg = np.clip(img_acescg, 0.0, None) # ACEScg can have values > 1.0 for very bright sources
# Calculate the full transformation matrix from linear sRGB to ACEScg.
# This includes chromatic adaptation from sRGB's D65 whitepoint
# to ACEScg's D60 whitepoint, which is crucial for accuracy.
sRGB_cs = colour.models.RGB_COLOURSPACE_sRGB
ACEScg_cs = colour.models.RGB_COLOURSPACE_ACESCG
# colour.matrix_RGB_to_RGB computes the combined matrix: M_XYZ_to_ACEScg @ M_CAT @ M_sRGB_to_XYZ
# This matrix is cached by colour-science after the first call for efficiency.
srgb_to_acescg_matrix = colour.matrix_RGB_to_RGB(sRGB_cs, ACEScg_cs) # Shape: (3, 3)
# Apply the transformation using NumPy's matrix multiplication operator @.
# img_linear_srgb has shape (H, W, 3).
# srgb_to_acescg_matrix.T also has shape (3, 3).
# The @ operator performs (H, W, 3) @ (3, 3) -> (H, W, 3),
# effectively applying the 3x3 matrix to each 3-element RGB vector.
# This is generally highly optimized and avoids explicit reshape calls.
img_acescg = img_linear_srgb @ srgb_to_acescg_matrix.T
# ACEScg space can legitimately have values outside [0,1] for bright, saturated colors.
img_acescg = np.clip(img_acescg, 0.0, None)
print(f"Image in ACEScg: shape: {img_acescg.shape}, min: {img_acescg.min():.4f}, max: {img_acescg.max():.4f}, mean: {img_acescg.mean():.4f}")