process_exr 是一组 EXR 处理脚本以及围绕它们构建的 Web Workbench。所有
脚本都可以单独以 CLI 方式运行,但日常工作流推荐通过 Workbench 把它们
串成可视化的 pipeline。
| 路径 | 说明 |
|---|---|
workbench/ |
FastAPI 后端、服务注册表、Workflow 引擎和插件入口 |
workbench/static/ |
单文件 React UMD 前端(无构建步骤) |
workbench/nodes/ |
插件节点目录,落地 register(registry) 即被自动加载 |
workflows/examples/ |
官方示例 Workflow(建议作为模板复制使用) |
workflows/user/ |
本地草稿 Workflow,已加入 .gitignore |
configs/ |
process.py、taa.py、check_input.py 等脚本所用 JSON |
input/、output/ |
输入/输出工作区,已加入 .gitignore |
process.py 等顶层脚本 |
处理类 CLI(被 Workbench 当成子进程调用) |
workbench_cli.py |
不打开 Web UI 时的 Workflow CLI |
workbench_window.py |
用 pywebview 在独立窗口中加载 Workbench |
requirements.txt |
Workbench + 处理脚本的依赖 |
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -U pip
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -r .\process_exr\requirements.txtexr_to_video.py 额外依赖系统中的 ffmpeg。读写 EXR 需要在调用 cv2
之前设置环境变量:
$env:OPENCV_IO_ENABLE_OPENEXR = '1'仓库根目录提供一键脚本:
.\start_process_exr_workbench.bat # 启动独立 workbench 窗口
.\start_process_exr_workbench.bat --server-only # 只启动 FastAPI 服务
.\start_process_exr_workbench.bat --current-window或者手动运行:
python -m uvicorn process_exr.workbench.api:app --host 127.0.0.1 --port 8000打开 http://127.0.0.1:8000/ 即可使用图形化 Workbench。环境变量
WORKBENCH_HOST、WORKBENCH_PORT 可覆盖默认地址。
- 左侧节点库:所有注册过的服务按类别分组列在左侧。
- 中间 Workflow 区:管理
variables、添加/排序节点、保存或预览。 - 右侧 Inspector:编辑当前节点的参数,按必填 / 基础 / 高级 / 诊断分组。
- 顶部操作:保存、预览(变量渲染后)、Dry Run(只生成命令与运行目录)、 播放(真正执行);屏幕右上角红色按钮可中止运行。
- 运行结果面板:底部显示状态、进度、事件列表,右侧箭头可折叠。
- 运行记录写入
output/workbench_runs/<workflow_id>/<run_id>/,包括渲染后 的配置、命令、stdout / stderr 日志和每一步的result.json。
最小可运行 Workflow 的结构:
模板支持:
{{var_name}}:来自variables或foreach注入的变量。{{steps.<step_id>.summary.x}}/{{steps.<step_id>.outputs.<id>.path}}: 引用上游步骤结果。- 当整个值就是一个模板时,数组/对象会以原始结构传递;混合在字符串里时会做字符串替换。
加载老 Workflow(含 scene_list 或 sequence_discovery 步骤)时,引擎会
自动迁移为 folder_discovery。
不开 UI 时可直接使用 workbench_cli.py:
python .\process_exr\workbench_cli.py list-services
python .\process_exr\workbench_cli.py list-workflows
python .\process_exr\workbench_cli.py preview-workflow `
.\process_exr\workflows\examples\<workflow>.json
python .\process_exr\workbench_cli.py run-workflow `
.\process_exr\workflows\examples\<workflow>.json --dry-run无需修改 services.py 即可扩展节点:
-
在
process_exr/workbench/nodes/下新建my_plugin.py。 -
实现入口函数:
from process_exr.workbench.services import ServiceRegistry def register(registry: ServiceRegistry) -> None: registry.register(definition, handler)
-
definition与handler的写法可参考services.py中_register_cli_tool_services/_register_direct_services的实现。 -
重启 Workbench,新节点会自动出现在左侧节点库。
模块名以 _ 开头会被忽略,方便存放共享辅助代码;加载失败的插件会写入
日志但不会阻断主进程。
虽然推荐用 Workbench 串联,但每个脚本都仍可单独运行,详细参数见
--help 输出。常用入口:
python .\process_exr\process.py --list-configs
python .\process_exr\process.py --config-name process60
python .\process_exr\check_input.py --list-configs
python .\process_exr\check_input.py --config-name check60
python .\process_exr\taa.py --list-configs
python .\process_exr\taa.py --config-name taa
python .\process_exr\tonemapInput.py --input <dir> --output <dir> --operation tonemap
python .\process_exr\shadowmap_ops.py dilate --input <exr> --output <exr> --radius 5
python .\process_exr\batch_errormap.py --input <dir> --output <dir> `
--image-contains ours --reference-contains gt
python .\process_exr\setAlphaToOne.py --input <dir>
python .\process_exr\exr_to_video.py <dir>process.py 与 check_input.py 支持的 JSON 字段、taa.py 的调参建议等
详细文档保存在 configs/ 下示例文件中,建议直接复制示例修改。
- 序列通常按
<scene>_<fps>命名,例如Bunker_60、Town_30。 process.py的merge_sequences用于把低帧率序列覆盖到高帧率时间线上。- TAA 期望 color 与 motion vector 序列分别位于两个根目录,按同名子目录配对。
更复杂场景请直接参考 workflows/examples/ 下的官方示例。
{ "id": "demo", "name": "Demo", "variables": { "input_root": { "default": "E:/.../process_exr/input" } }, "steps": [ { "id": "discover", "type": "folder_discovery", "config": { "input_root": "{{input_root}}" } }, { "id": "loop", "type": "foreach", "config": { "items": "{{steps.discover.summary.items}}", "item_name": "scene" }, "steps": [ { "id": "tonemap", "type": "tonemap", "config": { "input": "{{scene.path}}", "output": "E:/.../tmp/{{scene.name}}", "operation": "tonemap" } } ] } ] }