Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Option To Flatten The Matrix In The CLF #89

Open
wants to merge 1 commit into
base: feature/prelinearized
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 52 additions & 32 deletions aces/idt/core/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,7 @@ def clf_processing_elements(
k_factor: float,
use_range: bool = True,
include_white_balance_in_clf: bool = False,
flatten_clf: bool = True,
) -> Et.Element:
"""
Add the *Common LUT Format* (CLF) elements for given *IDT* matrix,
Expand All @@ -440,6 +441,8 @@ def clf_processing_elements(
factor :math:`k`.
include_white_balance_in_clf
Whether to include the white balance multipliers in the *CLF*.
flatten_clf
Whether to flatten the *CLF*. into a single 1D Lut & 1 3x3 Matrix

Returns
-------
Expand All @@ -460,39 +463,56 @@ def format_array(a: NDArrayFloat) -> str:

return formatted_string

if include_white_balance_in_clf:
et_RGB_w = Et.SubElement(root, "Matrix", inBitDepth="32f", outBitDepth="32f")
et_description = Et.SubElement(et_RGB_w, "Description")
et_description.text = "White balance multipliers *b*."
et_array = Et.SubElement(et_RGB_w, "Array", dim="3 3")
et_array.text = f"\n\t\t{format_array(np.diag(multipliers))}"

if use_range:
et_range = Et.SubElement(
root,
"Range",
inBitDepth="32f",
outBitDepth="32f",
if not flatten_clf:
if include_white_balance_in_clf:
et_RGB_w = Et.SubElement(
root, "Matrix", inBitDepth="32f", outBitDepth="32f"
)
et_description = Et.SubElement(et_RGB_w, "Description")
et_description.text = "White balance multipliers *b*."
et_array = Et.SubElement(et_RGB_w, "Array", dim="3 3")
et_array.text = f"\n\t\t{format_array(np.diag(multipliers))}"

# TODO is this even used any more? Default param is False, and the calling
# TODO function is hard coded to False
if use_range:
et_range = Et.SubElement(
root,
"Range",
inBitDepth="32f",
outBitDepth="32f",
)
et_max_in_value = Et.SubElement(et_range, "maxInValue")
et_max_in_value.text = "1"
et_max_out_value = Et.SubElement(et_range, "maxOutValue")
et_max_out_value.text = "1"

et_k = Et.SubElement(root, "Matrix", inBitDepth="32f", outBitDepth="32f")
et_description = Et.SubElement(et_k, "Description")
et_description.text = (
'Exposure factor *k* that results in a nominally "18% gray" object in '
"the scene producing ACES values [0.18, 0.18, 0.18]."
)
et_max_in_value = Et.SubElement(et_range, "maxInValue")
et_max_in_value.text = "1"
et_max_out_value = Et.SubElement(et_range, "maxOutValue")
et_max_out_value.text = "1"

et_k = Et.SubElement(root, "Matrix", inBitDepth="32f", outBitDepth="32f")
et_description = Et.SubElement(et_k, "Description")
et_description.text = (
'Exposure factor *k* that results in a nominally "18% gray" object in '
"the scene producing ACES values [0.18, 0.18, 0.18]."
)
et_array = Et.SubElement(et_k, "Array", dim="3 3")
et_array.text = f"\n\t\t{format_array(np.ravel(np.diag([k_factor] * 3)))}"

et_M = Et.SubElement(root, "Matrix", inBitDepth="32f", outBitDepth="32f")
et_description = Et.SubElement(et_M, "Description")
et_description.text = "*Input Device Transform* (IDT) matrix *B*."
et_array = Et.SubElement(et_M, "Array", dim="3 3")
et_array.text = f"\n\t\t{format_array(matrix)}"
et_array = Et.SubElement(et_k, "Array", dim="3 3")
et_array.text = f"\n\t\t{format_array(np.ravel(np.diag([k_factor] * 3)))}"

et_M = Et.SubElement(root, "Matrix", inBitDepth="32f", outBitDepth="32f")
et_description = Et.SubElement(et_M, "Description")
et_description.text = "*Input Device Transform* (IDT) matrix *B*."
et_array = Et.SubElement(et_M, "Array", dim="3 3")
et_array.text = f"\n\t\t{format_array(matrix)}"

else:
# If we are flattening the clf we output just a single matrix into the clf
output_matrix = np.diag([k_factor] * 3) @ matrix
if include_white_balance_in_clf:
output_matrix = np.diag(multipliers) @ np.diag([k_factor] * 3) @ matrix

et_M = Et.SubElement(root, "Matrix", inBitDepth="32f", outBitDepth="32f")
et_description = Et.SubElement(et_M, "Description")
et_description.text = "*Input Device Transform* (IDT) matrix *B*."
et_array = Et.SubElement(et_M, "Array", dim="3 3")
et_array.text = f"\n\t\t{format_array(output_matrix)}"

return root

Expand Down
9 changes: 9 additions & 0 deletions aces/idt/core/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,14 @@ class ProjectSettingsMetadataConstants:
ui_category=UICategories.STANDARD,
)

FLATTEN_CLF = Metadata(
default_value=False,
description="Whether to flatten the CLF to a 1D Lut and a single 3x3 Matrix ",
display_name="Flatten CLF",
ui_type=UITypes.BOOLEAN_FIELD,
ui_category=UICategories.STANDARD,
)

ALL: ClassVar[tuple[Metadata, ...]] = (
SCHEMA_VERSION,
CAMERA_MAKE,
Expand Down Expand Up @@ -436,4 +444,5 @@ class ProjectSettingsMetadataConstants:
EV_WEIGHTS,
OPTIMIZATION_KWARGS,
INCLUDE_WHITE_BALANCE_IN_CLF,
FLATTEN_CLF,
)
17 changes: 17 additions & 0 deletions aces/idt/framework/project_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,10 @@ def __init__(self, **kwargs: Dict):
"include_white_balance_in_clf",
IDTProjectSettings.include_white_balance_in_clf.metadata.default_value,
)
self._flatten_clf = kwargs.get(
"flatten_clf",
IDTProjectSettings.flatten_clf.metadata.default_value,
)

@metadata_property(metadata=MetadataConstants.SCHEMA_VERSION)
def schema_version(self) -> str:
Expand Down Expand Up @@ -560,6 +564,19 @@ def include_white_balance_in_clf(self) -> bool:
"""
return self._include_white_balance_in_clf

@metadata_property(metadata=MetadataConstants.FLATTEN_CLF)
def flatten_clf(self) -> str:
"""
Getter property for the flatten_clf.

Returns
-------
:class:`bool`
Whether to flatten the clf output into a 1D LUT and a single 3x3 Matrix
"""

return self._flatten_clf

def get_reference_colour_checker_samples(self) -> NDArrayFloat:
"""
Return the reference colour checker samples.
Expand Down
1 change: 1 addition & 0 deletions aces/idt/generators/base_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,7 @@ def format_array(a):
self._k,
False,
self.project_settings.include_white_balance_in_clf,
self.project_settings.flatten_clf,
)

clf_path = (
Expand Down
1 change: 1 addition & 0 deletions tests/resources/example_from_folder.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"camera_make": "",
"camera_model": "",
"include_white_balance_in_clf": false,
"flatten_clf": false,
"iso": 800,
"temperature": 6000,
"additional_camera_settings": "",
Expand Down