RAW config is stored in config json

This commit is contained in:
2025-08-03 17:47:27 +02:00
parent a0ba27b35c
commit bbedfe6d35
3 changed files with 189 additions and 47 deletions

View File

@ -1,6 +1,7 @@
import dearpygui.dearpygui as dpg import dearpygui.dearpygui as dpg
import rawpy import rawpy
import numpy as np import numpy as np
import ast
from PIL import Image from PIL import Image
from .pipeline_stage_widget import PipelineStageWidget from .pipeline_stage_widget import PipelineStageWidget
@ -42,6 +43,20 @@ class OpenRawWidget(PipelineStageWidget):
"four_color_rgb": False, "four_color_rgb": False,
} }
self.demosaic_combo_tag = dpg.generate_uuid()
self.color_space_combo_tag = dpg.generate_uuid()
self.output_bps_combo_tag = dpg.generate_uuid()
self.use_cam_wb_tag = dpg.generate_uuid()
self.auto_wb_tag = dpg.generate_uuid()
self.wb_r_slider_tag = dpg.generate_uuid()
self.wb_g_slider_tag = dpg.generate_uuid()
self.wb_b_slider_tag = dpg.generate_uuid()
self.bright_slider_tag = dpg.generate_uuid()
self.no_auto_bright_tag = dpg.generate_uuid()
self.gamma_slider_tag = dpg.generate_uuid()
self.half_size_tag = dpg.generate_uuid()
self.four_color_tag = dpg.generate_uuid()
self.manager.bus.subscribe( self.manager.bus.subscribe(
"process_full_res", self._on_process_full_res, True) "process_full_res", self._on_process_full_res, True)
@ -60,90 +75,125 @@ class OpenRawWidget(PipelineStageWidget):
dpg.add_file_extension(".*") dpg.add_file_extension(".*")
with dpg.group(tag=self.config_group): with dpg.group(tag=self.config_group):
# -- Open / Reprocess buttons --
with dpg.group(horizontal=True): with dpg.group(horizontal=True):
dpg.add_button(label="Open File...", dpg.add_button(label="Open File...", callback=self._on_open_file)
callback=self._on_open_file) dpg.add_button(label="Reprocess", callback=self._process_and_publish)
dpg.add_button(label="Reprocess",
callback=self._process_and_publish)
# -- Demosaic combo --
dpg.add_combo( dpg.add_combo(
label="Demosaic", label="Demosaic",
items=[alg.name for alg in rawpy.DemosaicAlgorithm], items=[alg.name for alg in rawpy.DemosaicAlgorithm],
default_value=rawpy.DemosaicAlgorithm.AHD.name, default_value=self.rawconfig["demosaic_algorithm"].name,
callback=lambda s, a, u: self.rawconfig.__setitem__( callback=lambda s,a,u: self.rawconfig.__setitem__(
"demosaic_algorithm", rawpy.DemosaicAlgorithm[a]) "demosaic_algorithm", rawpy.DemosaicAlgorithm[a]
),
tag=self.demosaic_combo_tag
) )
# -- Color space combo --
dpg.add_combo( dpg.add_combo(
label="Color Space", label="Color Space",
items=[cs.name for cs in rawpy.ColorSpace], items=[cs.name for cs in rawpy.ColorSpace],
default_value=rawpy.ColorSpace.sRGB.name, default_value=self.rawconfig["output_color"].name,
callback=lambda s, a, u: self.rawconfig.__setitem__( callback=lambda s,a,u: self.rawconfig.__setitem__(
"output_color", rawpy.ColorSpace[a]) "output_color", rawpy.ColorSpace[a]
),
tag=self.color_space_combo_tag
) )
# -- Bits per sample --
dpg.add_combo( dpg.add_combo(
label="Output Bits", label="Output Bits",
items=["8", "16"], items=["8","16"],
default_value="16", default_value=str(self.rawconfig["output_bps"]),
callback=lambda s, a, u: self.rawconfig.__setitem__( callback=lambda s,a,u: self.rawconfig.__setitem__(
"output_bps", int(a)) "output_bps", int(a)
),
tag=self.output_bps_combo_tag
) )
# -- Checkboxes & sliders --
dpg.add_checkbox( dpg.add_checkbox(
label="Use Camera WB", label="Use Camera WB",
default_value=True, default_value=self.rawconfig["use_camera_wb"],
callback=lambda s, a, u: self.rawconfig.__setitem__( callback=lambda s,a,u: self.rawconfig.__setitem__("use_camera_wb", a),
"use_camera_wb", a) tag=self.use_cam_wb_tag
) )
dpg.add_checkbox( dpg.add_checkbox(
label="Auto WB", label="Auto WB",
default_value=False, default_value=self.rawconfig["use_auto_wb"],
callback=lambda s, a, u: self.rawconfig.__setitem__( callback=lambda s,a,u: self.rawconfig.__setitem__("use_auto_wb", a),
"use_auto_wb", a) tag=self.auto_wb_tag
) )
dpg.add_slider_float( dpg.add_slider_float(
label="Manual WB R Gain", label="Manual WB R Gain",
default_value=1.0, min_value=0.1, max_value=4.0, default_value=self.rawconfig["user_wb"][0],
callback=lambda s, a, u: self.config.__setitem__( min_value=0.1, max_value=4.0,
"user_wb", (a, self.rawconfig["user_wb"][1], self.rawconfig["user_wb"][2], self.rawconfig["user_wb"][3])) callback=lambda s,a,u: self.rawconfig.__setitem__(
"user_wb", (a, self.rawconfig["user_wb"][1],
self.rawconfig["user_wb"][2], self.rawconfig["user_wb"][3])
),
tag=self.wb_r_slider_tag
) )
dpg.add_slider_float( dpg.add_slider_float(
label="Manual WB G Gain", label="Manual WB G Gain",
default_value=1.0, min_value=0.1, max_value=4.0, default_value=self.rawconfig["user_wb"][1],
callback=lambda s, a, u: self.config.__setitem__( min_value=0.1, max_value=4.0,
"user_wb", (self.rawconfig["user_wb"][0], a, a, self.rawconfig["user_wb"][3])) callback=lambda s,a,u: self.rawconfig.__setitem__(
"user_wb", (self.rawconfig["user_wb"][0], a,
self.rawconfig["user_wb"][2], self.rawconfig["user_wb"][3])
),
tag=self.wb_g_slider_tag
) )
dpg.add_slider_float( dpg.add_slider_float(
label="Manual WB B Gain", label="Manual WB B Gain",
default_value=1.0, min_value=0.1, max_value=4.0, default_value=self.rawconfig["user_wb"][2],
callback=lambda s, a, u: self.config.__setitem__( min_value=0.1, max_value=4.0,
"user_wb", (self.rawconfig["user_wb"][0], self.rawconfig["user_wb"][1], self.rawconfig["user_wb"][2], a)) callback=lambda s,a,u: self.rawconfig.__setitem__(
"user_wb", (self.rawconfig["user_wb"][0],
self.rawconfig["user_wb"][1], a,
self.rawconfig["user_wb"][3])
),
tag=self.wb_b_slider_tag
) )
dpg.add_slider_float( dpg.add_slider_float(
label="Bright", label="Bright",
default_value=1.0, min_value=0.1, max_value=4.0, default_value=self.rawconfig["bright"],
callback=lambda s, a, u: self.rawconfig.__setitem__("bright", a) min_value=0.1, max_value=4.0,
callback=lambda s,a,u: self.rawconfig.__setitem__("bright", a),
tag=self.bright_slider_tag
) )
dpg.add_checkbox( dpg.add_checkbox(
label="No Auto Bright", label="No Auto Bright",
default_value=False, default_value=self.rawconfig["no_auto_bright"],
callback=lambda s, a, u: self.rawconfig.__setitem__( callback=lambda s,a,u: self.rawconfig.__setitem__(
"no_auto_bright", a) "no_auto_bright", a
),
tag=self.no_auto_bright_tag
) )
dpg.add_slider_float( dpg.add_slider_float(
label="Gamma", label="Gamma",
default_value=1.0, min_value=0.1, max_value=3.0, default_value=self.rawconfig["gamma"],
callback=lambda s, a, u: self.rawconfig.__setitem__("gamma", a) min_value=0.1, max_value=3.0,
callback=lambda s,a,u: self.rawconfig.__setitem__("gamma", a),
tag=self.gamma_slider_tag
) )
dpg.add_checkbox( dpg.add_checkbox(
label="Half-size", label="Half-size",
default_value=False, default_value=self.rawconfig["half_size"],
callback=lambda s, a, u: self.rawconfig.__setitem__( callback=lambda s,a,u: self.rawconfig.__setitem__(
"half_size", a) "half_size", a
),
tag=self.half_size_tag
) )
dpg.add_checkbox( dpg.add_checkbox(
label="4-color RGB", label="4-color RGB",
default_value=False, default_value=self.rawconfig["four_color_rgb"],
callback=lambda s, a, u: self.rawconfig.__setitem__( callback=lambda s,a,u: self.rawconfig.__setitem__(
"four_color_rgb", a) "four_color_rgb", a
),
tag=self.four_color_tag
) )
with dpg.group(tag=self.busy_group, show=False): with dpg.group(tag=self.busy_group, show=False):
@ -229,3 +279,53 @@ class OpenRawWidget(PipelineStageWidget):
return return
self.manager.pipeline.publish( self.manager.pipeline.publish(
self.pipeline_stage_out_id, self.img_full, True) self.pipeline_stage_out_id, self.img_full, True)
def get_config(self):
config = super().get_config()
config["raw_config"] = { k:str(v) for k, v in self.rawconfig.items() }
return config
def set_config(self, config):
super().set_config(config)
raw_cfg = config.get("raw_config", {})
if raw_cfg:
# parse each back into Python types
for k, v in raw_cfg.items():
if k == "demosaic_algorithm":
# "DemosaicAlgorithm.AHD" → "AHD"
name = v.split(".", 1)[1]
self.rawconfig[k] = rawpy.DemosaicAlgorithm[name]
elif k == "output_color":
name = v.split(".", 1)[1]
self.rawconfig[k] = rawpy.ColorSpace[name]
elif k == "output_bps":
self.rawconfig[k] = int(v)
elif k in ("use_camera_wb","use_auto_wb",
"no_auto_bright","half_size","four_color_rgb"):
self.rawconfig[k] = (v == "True")
elif k in ("bright","gamma"):
self.rawconfig[k] = float(v)
elif k == "user_wb":
self.rawconfig[k] = tuple(ast.literal_eval(v))
# now that rawconfig is back to real types, update the UI
self._update_raw_ui()
def _update_raw_ui(self):
"""Push current self.rawconfig values back into all controls."""
# combos want the enum.name or string
dpg.set_value(self.demosaic_combo_tag, self.rawconfig["demosaic_algorithm"].name)
dpg.set_value(self.color_space_combo_tag, self.rawconfig["output_color"].name)
dpg.set_value(self.output_bps_combo_tag, str(self.rawconfig["output_bps"]))
# checkboxes & sliders
dpg.set_value(self.use_cam_wb_tag, self.rawconfig["use_camera_wb"])
dpg.set_value(self.auto_wb_tag, self.rawconfig["use_auto_wb"])
dpg.set_value(self.wb_r_slider_tag, self.rawconfig["user_wb"][0])
dpg.set_value(self.wb_g_slider_tag, self.rawconfig["user_wb"][1])
dpg.set_value(self.wb_b_slider_tag, self.rawconfig["user_wb"][2])
dpg.set_value(self.bright_slider_tag, self.rawconfig["bright"])
dpg.set_value(self.no_auto_bright_tag, self.rawconfig["no_auto_bright"])
dpg.set_value(self.gamma_slider_tag, self.rawconfig["gamma"])
dpg.set_value(self.half_size_tag, self.rawconfig["half_size"])
dpg.set_value(self.four_color_tag, self.rawconfig["four_color_rgb"])

View File

@ -141,10 +141,10 @@ Collapsed=0
DockId=0x00000022,0 DockId=0x00000022,0
[Window][###103] [Window][###103]
Pos=984,649 Pos=984,19
Size=216,151 Size=216,679
Collapsed=0 Collapsed=0
DockId=0x00000032,0 DockId=0x0000003F,0
[Window][###139] [Window][###139]
Pos=984,600 Pos=984,600
@ -224,6 +224,29 @@ Size=216,561
Collapsed=0 Collapsed=0
DockId=0x00000039,0 DockId=0x00000039,0
[Window][###123]
Pos=984,634
Size=216,166
Collapsed=0
DockId=0x0000003E,0
[Window][###102]
Pos=984,19
Size=216,781
Collapsed=0
DockId=0x0000003D,0
[Window][###124]
Pos=984,700
Size=216,100
Collapsed=0
DockId=0x00000040,0
[Window][###122]
Pos=987,597
Size=216,100
Collapsed=0
[Docking][Data] [Docking][Data]
DockSpace ID=0x7C6B3D9B Window=0xA87D555D Pos=0,19 Size=1200,781 Split=X DockSpace ID=0x7C6B3D9B Window=0xA87D555D Pos=0,19 Size=1200,781 Split=X
DockNode ID=0x00000037 Parent=0x7C6B3D9B SizeRef=982,781 Split=X DockNode ID=0x00000037 Parent=0x7C6B3D9B SizeRef=982,781 Split=X
@ -240,7 +263,7 @@ DockSpace ID=0x7C6B3D9B Window=0xA87D555D Pos=0,19 Siz
DockNode ID=0x00000013 Parent=0x0000000D SizeRef=196,156 Split=Y Selected=0xB4AD3310 DockNode ID=0x00000013 Parent=0x0000000D SizeRef=196,156 Split=Y Selected=0xB4AD3310
DockNode ID=0x0000001F Parent=0x00000013 SizeRef=270,469 Split=Y Selected=0xD36850C8 DockNode ID=0x0000001F Parent=0x00000013 SizeRef=270,469 Split=Y Selected=0xD36850C8
DockNode ID=0x00000035 Parent=0x0000001F SizeRef=270,691 Selected=0xB4AD3310 DockNode ID=0x00000035 Parent=0x0000001F SizeRef=270,691 Selected=0xB4AD3310
DockNode ID=0x00000036 Parent=0x0000001F SizeRef=270,88 Selected=0xB7116FC5 DockNode ID=0x00000036 Parent=0x0000001F SizeRef=270,88 Selected=0x8773D56E
DockNode ID=0x00000020 Parent=0x00000013 SizeRef=270,154 Selected=0x0531B3D5 DockNode ID=0x00000020 Parent=0x00000013 SizeRef=270,154 Selected=0x0531B3D5
DockNode ID=0x0000000E Parent=0x0000000B SizeRef=196,373 Selected=0x3BEDC6B0 DockNode ID=0x0000000E Parent=0x0000000B SizeRef=196,373 Selected=0x3BEDC6B0
DockNode ID=0x0000000C Parent=0x00000009 SizeRef=196,105 Selected=0x4F81AB74 DockNode ID=0x0000000C Parent=0x00000009 SizeRef=196,105 Selected=0x4F81AB74
@ -270,7 +293,13 @@ DockSpace ID=0x7C6B3D9B Window=0xA87D555D Pos=0,19 Siz
DockNode ID=0x00000024 Parent=0x00000027 SizeRef=216,781 Split=Y Selected=0xCF08B82F DockNode ID=0x00000024 Parent=0x00000027 SizeRef=216,781 Split=Y Selected=0xCF08B82F
DockNode ID=0x00000025 Parent=0x00000024 SizeRef=216,579 Split=Y Selected=0xCF08B82F DockNode ID=0x00000025 Parent=0x00000024 SizeRef=216,579 Split=Y Selected=0xCF08B82F
DockNode ID=0x00000031 Parent=0x00000025 SizeRef=216,628 Selected=0x052342BF DockNode ID=0x00000031 Parent=0x00000025 SizeRef=216,628 Selected=0x052342BF
DockNode ID=0x00000032 Parent=0x00000025 SizeRef=216,151 Selected=0xCF08B82F DockNode ID=0x00000032 Parent=0x00000025 SizeRef=216,151 Split=Y Selected=0xCF08B82F
DockNode ID=0x0000003B Parent=0x00000032 SizeRef=216,634 Split=Y Selected=0xCF08B82F
DockNode ID=0x0000003F Parent=0x0000003B SizeRef=216,679 Selected=0xCF08B82F
DockNode ID=0x00000040 Parent=0x0000003B SizeRef=216,100 Selected=0x30E0C534
DockNode ID=0x0000003C Parent=0x00000032 SizeRef=216,145 Split=Y Selected=0x82C01924
DockNode ID=0x0000003D Parent=0x0000003C SizeRef=216,613 Selected=0xF268919F
DockNode ID=0x0000003E Parent=0x0000003C SizeRef=216,166 Selected=0x82C01924
DockNode ID=0x00000026 Parent=0x00000024 SizeRef=216,200 Selected=0x032CD220 DockNode ID=0x00000026 Parent=0x00000024 SizeRef=216,200 Selected=0x032CD220
DockNode ID=0x00000028 Parent=0x0000002B SizeRef=216,781 Split=Y Selected=0xB5C8EB4F DockNode ID=0x00000028 Parent=0x0000002B SizeRef=216,781 Split=Y Selected=0xB5C8EB4F
DockNode ID=0x00000029 Parent=0x00000028 SizeRef=216,609 Selected=0xB5C8EB4F DockNode ID=0x00000029 Parent=0x00000028 SizeRef=216,609 Selected=0xB5C8EB4F

View File

@ -39,6 +39,19 @@
"pipeline_config": { "pipeline_config": {
"stage_in": null, "stage_in": null,
"stage_out": 2 "stage_out": 2
},
"raw_config": {
"demosaic_algorithm": "DemosaicAlgorithm.AHD",
"output_color": "ColorSpace.sRGB",
"output_bps": "16",
"use_camera_wb": "True",
"use_auto_wb": "False",
"user_wb": "(1.0, 1.0, 1.0, 1.0)",
"bright": "1.0",
"no_auto_bright": "False",
"gamma": "1.0",
"half_size": "False",
"four_color_rgb": "False"
} }
} }
}, },