new file mode 100644
@@ -0,0 +1,120 @@
+import yaml
+import numpy as np
+import argparse
+import sys
+
+# --- Configuration ---
+GRID_W = 16
+GRID_H = 16
+
+# Formula constants
+BLACK_LEVEL = 1024.0
+SCALE_FACTOR = 3071 # Divisor to map the range to 0-255
+
+def load_and_process_yaml(input_filename, target_ct):
+ # 1. Load the YAML file
+ try:
+ with open(input_filename, 'r') as f:
+ data = yaml.safe_load(f)
+ except FileNotFoundError:
+ print(f"Error: Input file '{input_filename}' not found.")
+ return None, None, None
+
+ # 2. Find the LensShadingCorrection block
+ lsc_data = None
+ for algo in data['algorithms']:
+ if 'LensShadingCorrection' in algo:
+ lsc_data = algo['LensShadingCorrection']
+ break
+
+ if not lsc_data:
+ print("Error: LensShadingCorrection block not found.")
+ return None, None, None
+
+ # 3. Extract the set for the specific Color Temperature (CT) provided in arguments
+ sets = lsc_data['sets']
+ target_set = next((item for item in sets if item['ct'] == target_ct), None)
+
+ if not target_set:
+ print(f"Error: Set for Color Temperature {target_ct} not found in '{input_filename}'.")
+ return None, None, None
+
+ print(f"Found data for CT {target_ct}. Applying formula: (x - {int(BLACK_LEVEL)}) / {SCALE_FACTOR} ...")
+
+ # 4. Get Raw Data
+ r_raw = np.array(target_set['r'])
+ b_raw = np.array(target_set['b'])
+ gr_raw = np.array(target_set['gr'])
+ gb_raw = np.array(target_set['gb'])
+
+ # Calculate Green Channel (Average of GR and GB)
+ g_raw = (gr_raw + gb_raw) / 2.0
+
+ # 5. Define the calculation logic
+ def apply_formula(data_array):
+ """
+ Applies the specific user formula:
+ 1. Subtract Black Level (1024)
+ 2. Divide by the Scale Factor (3071)
+ 3. Multiply by 255 and convert to integer
+ """
+ result = ((data_array - BLACK_LEVEL) / SCALE_FACTOR) * 255
+ return result.astype(int)
+
+ # 6. Apply calculation to all channels
+ r_final = apply_formula(r_raw)
+ g_final = apply_formula(g_raw)
+ b_final = apply_formula(b_raw)
+
+ return r_final, g_final, b_final
+
+def save_custom_grid_yaml(output_filename, r, g, b, target_ct):
+
+ # Helper function to format the array as a visual grid string
+ def format_array_as_grid_string(arr):
+ lines = []
+ # Loop through the array in chunks of 16 (GRID_W)
+ for i in range(0, len(arr), GRID_W):
+ row = arr[i:i+GRID_W]
+ # Join numbers with commas
+ row_str = ", ".join(map(str, row))
+ lines.append(f" {row_str}")
+ # Wrap in brackets to form a valid YAML list, but visually formatted
+ return "[\n" + ",\n".join(lines) + "\n ]"
+
+ # Write the file manually to ensure specific formatting
+ with open(output_filename, 'w') as f:
+ f.write(f"description: 'LSC Fixed Formula ((x-{int(BLACK_LEVEL)})/{SCALE_FACTOR})'\n")
+ f.write(f"source_ct: {target_ct}\n")
+ f.write(f"grid_size: [{GRID_W}, {GRID_H}]\n")
+ f.write(f"formula_used: '(RawValue - {int(BLACK_LEVEL)}) / {SCALE_FACTOR} -> [0..255]'\n")
+ f.write(f"channels:\n")
+
+ f.write(" red: " + format_array_as_grid_string(r) + "\n")
+ f.write(" green: " + format_array_as_grid_string(g) + "\n")
+ f.write(" blue: " + format_array_as_grid_string(b) + "\n")
+
+ print(f"Success! Saved formatted grid to '{output_filename}'")
+
+# --- Main Execution ---
+if __name__ == "__main__":
+ # 1. Setup Argument Parser
+ parser = argparse.ArgumentParser(description="Convert LSC YAML data to shader grid format.")
+ parser.add_argument("ct", type=int, help="The Color Temperature to process (e.g. 2700, 5000, 6500)")
+
+ # 2. Parse arguments
+ args = parser.parse_args()
+ ct_val = args.ct
+
+ # 3. Construct filenames based on the CT value
+ # Assumes input file is named 'tuning_XXXX.yaml'
+ input_file = f'tuning{ct_val}.yaml'
+ output_file = f'lsc_shader_16x16_{ct_val}_fixed.yaml'
+
+ print(f"--- Processing for Color Temp: {ct_val} ---")
+
+ # 4. Run Process
+ r, g, b = load_and_process_yaml(input_file, ct_val)
+
+ if r is not None:
+ save_custom_grid_yaml(output_file, r, g, b, ct_val)
new file mode 100644
@@ -0,0 +1,76 @@
+import yaml
+import numpy as np
+import matplotlib.pyplot as plt
+
+# 1. Load the data
+try:
+ with open('tuning2700.yaml', 'r') as f:
+ data = yaml.safe_load(f)
+except FileNotFoundError:
+ print("Error: 'tuning.yaml' not found. Please ensure the file exists.")
+ exit()
+
+# 2. Find LensShadingCorrection safely
+lsc_data = None
+for algo in data['algorithms']:
+ if 'LensShadingCorrection' in algo:
+ lsc_data = algo['LensShadingCorrection']
+ break
+
+if not lsc_data:
+ print("Error: LensShadingCorrection block not found in YAML.")
+ exit()
+
+# 3. Extract the set for disirable Kelvin
+kelvin = 2700
+sets = lsc_data['sets']
+target_set = next((item for item in sets if item['ct'] == kelvin), None)
+
+if not target_set:
+ print("Error: CT 6500 not found in sets.")
+ exit()
+
+# 4. Get lists and normalize (1024 = 1.0 gain)
+r_list = np.array(target_set['r'])
+gr_list = np.array(target_set['gr'])
+gb_list = np.array(target_set['gb'])
+b_list = np.array(target_set['b'])
+
+r_norm = r_list / 1024.0
+b_norm = b_list / 1024.0
+# Average the two greens for the shader
+g_norm = (gr_list + gb_list) / 2.0 / 1024.0
+
+# 5. Reshape into 17x17 Grids
+grid_size = (17, 17)
+r_grid = r_norm.reshape(grid_size)
+g_grid = g_norm.reshape(grid_size)
+b_grid = b_norm.reshape(grid_size)
+
+# 6. Visualization
+# We create 3 separate plots to see the data distribution correctly
+fig, axs = plt.subplots(1, 3, figsize=(15, 5))
+
+# Plot Red
+im1 = axs[0].imshow(r_grid, cmap='viridis')
+axs[0].set_title('Red Gain Map')
+fig.colorbar(im1, ax=axs[0])
+
+# Plot Green
+im2 = axs[1].imshow(g_grid, cmap='viridis')
+axs[1].set_title('Green Gain Map')
+fig.colorbar(im2, ax=axs[1])
+
+# Plot Blue
+im3 = axs[2].imshow(b_grid, cmap='viridis')
+axs[2].set_title('Blue Gain Map')
+fig.colorbar(im3, ax=axs[2])
+
+plt.suptitle(f"LSC Gain Maps (Center ~1.0, Corners > 1.0) for collor temprature {kelvin}")
+plt.show()
+
+# 7. Prepare Texture for Export (Optional)
+# Stack them for your shader: (17, 17, 3)
+lsc_texture = np.dstack((r_grid, g_grid, b_grid))
+print(f"Final Texture Shape: {lsc_texture.shape}")
+print(f"Sample Blue Value at Corner: {b_grid[0,0]}")