darktable AI 任务详解:Object Mask、Raw Denoise、Denoise 与 Upscale 的模型规范与集成指南
【免费下载链接】darktabledarktable is an open source photography workflow application and raw developer项目地址: https://gitcode.com/GitHub_Trending/da/darktable
darktable 的 AI 子系统基于 ONNX Runtime,为摄影工作流提供四类神经网络任务:交互式对象抠图(Object Mask)、传感器级原始降噪(Raw Denoise)、成片降噪(Denoise)与超分辨率放大(Upscale)。本文以 dev-doc/AI_Tasks.md 为主线,逐项拆解每个任务的任务键(task key)、模型 I/O 规格、预处理/后处理流程、分块(tiling)策略、config.json清单格式与 ONNX 导出要求,并结合 src/common/ai 目录下的实际实现(segmentation、restore、restore_rgb、restore_raw_bayer、restore_raw_linear)与消费端 src/libs/neural_restore.c 给出源码级佐证。读完本文,你将能够判断一个 ONNX 模型能否接入 darktable、如何为每个任务编写正确的config.json、如何导出符合规范的模型,以及每个任务在运行时实际经历了哪些处理环节。
系统的整体架构、构建开关(USE_AI)、执行提供方(provider)选择与"如何新增一个 AI 任务"的完整指南,参见 dev-doc/AI.md。
一、任务总览
darktable 的 AI 任务由config.json中的task字段标识,运行时通过模型注册表(model registry)按任务键查找"当前激活模型",再由对应模块加载执行。四类任务及其对应关系如下:
| 任务 | 任务键task | 核心 API | 消费端 |
|---|---|---|---|
| 对象抠图 Object Mask | "mask" | src/common/ai/segmentation.h | src/develop/masks/object.c |
| 原始降噪 Raw Denoise(Bayer) | "rawdenoise" | src/common/ai/restore_raw_bayer.h | src/libs/neural_restore.c |
| 原始降噪 Raw Denoise(Linear) | "rawdenoise" | src/common/ai/restore_raw_linear.h | src/libs/neural_restore.c |
| 成片降噪 Denoise | "denoise" | src/common/ai/restore_rgb.h | src/libs/neural_restore.c |
| 超分辨率 Upscale | "upscale" | src/common/ai/restore_rgb.h | src/libs/neural_restore.c |
模型清单 data/ai_models.json 中登记了各任务的默认模型:mask-object-sam21-small(mask)、denoise-nind(denoise)、rawdenoise-nind(rawdenoise)、upscale-realplksr(upscale),并通过"default": true指定默认启用项、min_version声明模型包的最低版本要求。
二、Object Mask:基于 SAM/SAM2/SegNext 的交互式抠图
2.1 任务定位
Object Mask 提供交互式对象抠图能力,模型基于 SAM(Segment Anything)、SAM 2.1 或 SegNext 系列。任务键为"mask",API 位于 src/common/ai/segmentation.h,由暗房(darkroom)的蒙版管理器消费,入口为 src/develop/masks/object.c。
2.2 工作流程
从用户交互到最终蒙版的完整流程如下:
- 用户在蒙版管理器中选择对象蒙版工具;
- 图像被导出为 sRGB uint8 格式,交给 SAM 编码器(encoder)编码,编码每张图像只运行一次并缓存结果;
- 用户点击放置前景/背景点(point prompt);
- 每次点击运行轻量级解码器(decoder),生成一张蒙版;
- 迭代精化:上一次的低分辨率蒙版被回馈给解码器,逐步改善精度;
- 蒙版被缩放到图像原始尺寸,作为 darktable 蒙版形状(mask shape)应用。
2.3 支持的模型架构
| 架构 | config.json中的arch | 编码器输出张量数 | 蒙版候选数 | 支持 Box 提示 |
|---|---|---|---|---|
| SAM 2.1 | "sam2" | 3 个 | 3(多蒙版 multi-mask) | 是 |
| SegNext | "segnext" | 2 个 | 1(单蒙版 single-mask) | 否 |
源码中 segmentation.c 通过读取模型注册表中的arch字段来区分模型类型:"sam"或"sam2"归入 SAM 类,"segnext"归入 SegNext 类,未知 arch 直接返回 NULL 并打印[segmentation] unknown arch日志。dt_seg_supports_box()用于向 UI 报告当前模型是否支持框选提示。
2.4 编码器(Encoder)规格
编码器输入固定为[1, 3, 1024, 1024]的 float32 张量,即预处理后的图像。预处理由segmentation.c完成,顺序如下:
- 最长边缩放至 1024 px(双线性插值),保持宽高比;
- 短边补零(zero-pad)至 1024×1024;
- 归一化:SAM 使用 ImageNet 均值/方差;SegNext 缩放到 [0, 1];
- HWC 布局转 CHW。
编码器典型输出:
| 输出 | Shape | 说明 |
|---|---|---|
| 0 | [1, 256, 64, 64] | 图像嵌入(image embeddings) |
| 1 | [1, 32, 256, 256] | 高分辨率特征 |
| 2(仅 SAM2) | [1, 64, 128, 128] | 中分辨率特征 |
2.5 解码器(Decoder)规格
解码器输入按索引排列,前 E 个输入是编码器输出的透传(E 为编码器输出张量数,SAM2 为 3、SegNext 为 2),其后依次为:
| 索引 | 名称 | Shape | 说明 |
|---|---|---|---|
| 0..E-1 | encoder outputs | 随架构变化 | 编码器输出透传 |
| E | point_coords | [1, N+1, 2] | 提示点坐标(N 个真实提示 + 1 个 SAM 填充点) |
| E+1 | point_labels | [1, N+1] | 1=前景,0=背景,-1=填充 |
| E+2 | mask_input | [1, 1, 256, 256] | 上一轮低分辨率蒙版 |
| E+3 | has_mask_input | [1] | 首次点击为 0.0,精化时为 1.0 |
解码器输出:
| 索引 | 名称 | Shape | 说明 |
|---|---|---|---|
| 0 | masks | [1, M, 1024, 1024] | 蒙版 logits(sigmoid 之前的值) |
| 1 | iou_predictions | [1, M] | 每个蒙版的预测 IoU |
| 2 | low_res_masks | [1, M, 256, 256] | 供迭代精化使用 |
其中 M 为蒙版候选数(SAM2 为 3,SegNext 为 1)。提示点结构在dt_seg_point_t中定义:x/y为原始图像空间像素坐标,label取值 0=背景、1=前景、2=框左上角、3=框右下角(框提示仅 SAM 支持,需先用dt_seg_supports_box()确认)。
2.6 蒙版后处理
解码器输出到最终蒙版的转换步骤:
- 选取预测 IoU 分数最高的蒙版;
- 裁掉补零区域(zero-padded region);
- 双线性缩放到原始图像尺寸;
- 应用 sigmoid:
mask = 1 / (1 + exp(-logits)); - 输出值域为 [0, 1]。
dt_seg_compute_mask()返回的正是这个 [0,1] 浮点蒙版缓冲(宽度×高度,调用方用g_free()释放)。在 segmentation.c 的采样实现中可以看到,蒙版从编码图像坐标映射到原图时采用基于亮度的引导重采样(guide-based upsampling),并对 sigmoid 前的 logits 值应用apply_sigmoid分支,与文档描述的后处理链一致。
2.7 迭代精化
- 首次解码:
has_mask_input = 0.0,解码器忽略mask_input; - 后续解码:上一轮
low_res_masks回馈为mask_input,has_mask_input = 1.0; dt_seg_reset_prev_mask():仅清除缓存的上一轮蒙版,保留图像嵌入,使下一次计算从头开始;dt_seg_reset_encoding():清除全部缓存(包括图像嵌入),图像切换时必须调用。
从 segmentation.h 的注释可以看到,dt_seg_encode_image/dt_seg_compute_mask/dt_seg_reset_*之间必须由调用方串行化(context 内部不做线程同步):编码器通常在后台线程执行,解码器在 UI 线程的用户点击回调中运行,二者会共同改写prev_mask状态。此外,解码器加载时被强制固定到 CPU 执行提供方并禁用图优化(DT_AI_OPT_DISABLED),注释给出的原因是解码器轻量、硬件加速收益有限,且可规避 SegNext 解码图(如Concat->Reshape)在 ORT 图优化下的问题。
为缓解首次点击的卡顿,dt_seg_warmup_decoder()会在dt_seg_load()之后于后台线程运行一次哑推理,把 ONNX Runtime 首次Run()的惰性编译与显存分配成本移出用户交互路径。分割模块还支持编码器嵌入的磁盘缓存(dt_seg_disk_cache_save/load),以图像 ID 为键、以畸变模块参数哈希(distort_hash)做失效判断,命中缓存时可直接跳过重新编码。
2.8 config.json 示例与目录布局
{ "id": "mask-object-sam21-small", "name": "mask sam2.1 hiera small", "description": "Segment Anything 2.1 (Hiera Small) for interactive masking", "task": "mask", "arch": "sam2", "backend": "onnx" }目录布局要求编码器与解码器作为两个独立的 ONNX 文件同目录存放:
mask-object-sam21-small/ config.json encoder.onnx decoder.onnx模型 ID 遵循<task>-<subtask>-<model>[-<size>]命名规范(详见 dev-doc/AI.md),例如mask-object-sam21-small、mask-object-segnext-b2hq。
2.9 ONNX 导出约束
解码器导出脚本维护在 darktable-ai 模型仓库中。导出必须满足以下硬性约束:
- 不得包含
orig_im_size输入; masks输出必须固定在 1024×1024(将F.interpolate编入计算图,而不是依赖外部缩放);low_res_masks输出为 256×256;- 所有空间维度必须是具体值,禁止
num_labels之类的符号维度; - 只允许
num_points保持动态。
三、Raw Denoise:传感器级原始降噪
3.1 任务定位
Raw Denoise 在 darktable 主处理管线之前、直接在 raw CFA 马赛克层面做降噪,输出为 DNG 文件,重新导入后按普通 raw 走完整管线调色。任务键为"rawdenoise",共享 API 为 src/common/ai/restore.h,消费端同样是 src/libs/neural_restore.c。
两个管线变体共享同一任务键,按传感器类型路由:
| 变体 | API | 适用传感器 | 输出 |
|---|---|---|---|
| Bayer | src/common/ai/restore_raw_bayer.h | RGGB / BGGR / GRBG / GBRG(统一强制裁剪到 RGGB 原点) | CFA Bayer DNG(uint16,保持原 CFA 模式) |
| Linear | src/common/ai/restore_raw_linear.h | X-Trans、Foveon、带 CFA 模式的单色传感器等无法打包为 4 通道 Bayer 的类型 | LinearRaw DNG(3 通道 float 去马赛克) |
传感器分类由dt_restore_classify_sensor()完成,它依据图像标志与 rawspeed 填充的buf_dsc.filters将 raw 归类为BAYER、XTRANS、LINEAR或UNSUPPORTED(非 raw、纯单色等无法路由的输入),并据此选择对应的 loader:dt_restore_load_rawdenoise_bayer/dt_restore_load_rawdenoise_xtrans/dt_restore_load_rawdenoise_linear。当前 X-Trans loader 会回退到 Linear 变体,保留独立的 loader 入口是为了未来可以通过仅修改 manifest 的方式接入专用的 X-Trans 模型。
3.2 工作原理
Bayer 变体(RGGB 家族):
- 直接从 rawspeed 加载 raw CFA 马赛克(不经过去马赛克,除 rawprepare 外不做 darktable 预处理);
- 预处理:逐通道黑电平扣除、逐通道白平衡归一化(默认使用由
adobe_XYZ_to_CAM推导的日光白平衡)、按像素位点(site)范围归一化; - 将 2T×2T 的 CFA 块打包为 T×T 的 4 通道张量(RGGB 顺序为 R、G1、G2、B;非 RGGB 传感器被强制裁剪到 RGGB 原点);
- 分块推理:模型内部通过 PixelShuffle 完成去马赛克,返回 3 通道 2T×2T 的 camRGB 块;
- 后处理:反转归一化与白平衡,可选标量均值匹配(
match_gain)以保持各块增益一致; - 重新马赛克回原 CFA 布局,通过
dt_imageio_dng_write_cfa_bayer写入 uint16 马赛克到 CFA Bayer DNG。
Linear 变体(X-Trans、Foveon 等):
- 运行最小 darktable 管线(
rawprepare → highlights → demosaic),关闭色温,在完整传感器分辨率下得到 camRGB raw-ADC 单位的 3 通道 float 缓冲——复用 darktable 自带的传感器感知去马赛克(AMaZE / VNG / Markesteijn / …)而非自研; - 应用日光白平衡与
camRGB → lin_rec2020矩阵; - 可选的标量曝光提升至
target_mean(训练分布默认 0.30); - 分块推理,逐块
match_gain; - 反转曝光提升、矩阵与白平衡,恢复 camRGB raw;
- 通过
dt_imageio_dng_write_linear写入 LinearRaw DNG。
两个变体完成后都会自动导入图库、与源图像分组,并继承用户标签(与 denoise/upscale 共用同一_import_image路径,见 src/libs/neural_restore.c)。
3.3 模型输入输出契约
Bayer(input_kind: bayer_v1):
| 张量 | 名称 | Shape | 类型 | 说明 |
|---|---|---|---|---|
| 输入 0 | input | [1, 4, T, T] | float32 | 打包后的半分辨率 CFA 块,通道序 R G1 G2 B,值为(raw - black) / range * wb_norm |
| 输出 0 | output | [1, 3, 2T, 2T] | float32 | 去马赛克后的 camRGB,与输入同 WB/曝光框架 |
Linear(input_kind: linear_v1):
| 张量 | 名称 | Shape | 类型 | 说明 |
|---|---|---|---|---|
| 输入 0 | input | [1, 3, T, T] | float32 | 3 通道平面块,默认色彩空间lin_rec2020 |
| 输出 0 | output | [1, 3, T, T] | float32 | 同输入空间的去噪块 |
契约标签(input_kind)是硬性约束:声明了但实际不匹配的input_kind属于加载硬错误,不静默回退(loader 拒绝打开打包错误的 ONNX,并通过dt_control_log反馈);早于该契约标签的 manifest 按bayer_v1兼容处理。
以 src/common/ai/restore.h 的实现注释为准,bayer_v1的详细约定包括:通道提取从 CFA 的 R 原点开始,因此 BGGR/GRBG/GBRG 传感器也会按 RGGB 方式打包,与 RawNIND 训练时"先把非 RGGB 传感器物理裁剪到 RGGB 原点再分块"的做法一致;bayer_orientation可取force_rggb(默认)或native;wb_norm可取daylight(默认,由相机adobe_XYZ_to_CAM推导 D65)、as_shot或none;edge_pad默认mirror_cropped,即在有效 RGGB 裁剪矩形内部做镜像填充,使角落块看到与训练一致的反射。输出端,除非声明output_scale: absolute,否则 loader 默认在重新马赛克前应用match_gain(标量均值匹配)。
3.4 分块策略
- 块尺寸按顺序尝试(Bayer 路径为半分辨率):512、384、256、192;
- 重叠:每边 16 个打包像素(= 32 个传感器像素);
- Bayer 路径的角落块在有效 RGGB 裁剪矩形内部做镜像填充(
variants.bayer.edge_pad: mirror_cropped,与 RawNIND 训练一致)。
由于静态 ONNX 导出声明了固定的输入 H×W,dt_restore_get_tile_size()返回模型内置的块尺寸(Bayer 为打包空间即半传感器单位),调用方必须精确按此尺寸分块,没有推理失败的兜底。
3.5 config.json 示例与目录布局
{ "id": "rawdenoise-nind", "name": "raw denoise NIND", "description": "RawNIND raw-domain denoise (Bayer + Linear)", "task": "rawdenoise", "github_asset": "rawdenoise-nind.dtmodel", "default": true, "variants": { "bayer": { "input_kind": "bayer_v1", "onnx": "model_bayer.onnx", "bayer_orientation": "force_rggb", "wb_norm": "daylight", "edge_pad": "mirror_cropped" }, "linear": { "input_kind": "linear_v1", "onnx": "model_linear.onnx", "input_colorspace": "lin_rec2020", "wb_norm": "as_shot", "target_mean": 0.30 } } }rawdenoise-nind/ config.json model_bayer.onnx model_linear.onnxvariants结构让一个模型包同时携带 Bayer 与 Linear 两个 ONNX 文件,由调用方根据传感器分类选择加载哪个变体;github_asset指向.dtmodel发布资产(zip 归档,内含 config.json 与 ONNX 文件)。
四、Denoise:成片神经网络降噪
4.1 任务定位
Denoise 对已显影(developed)图像做神经网络推理降噪。任务键为"denoise",加载器dt_restore_load_denoise与推理函数dt_restore_process_tiled分别位于 src/common/ai/restore.h 与 src/common/ai/restore_rgb.h,消费端为 src/libs/neural_restore.c。
4.2 工作流程
- darktable 将图像通过完整处理管线导出(白平衡、曝光、镜头校正等),得到线性 Rec.709 的 float4 RGBA 像素;
- restore 模块将线性 RGB 转为 sRGB,带重叠地分块,逐块送入 ONNX 模型;
- 输出块重新拼接后转回线性 RGB;
- 可选地,基于 DWT(离散小波变换)的细节恢复把原图中的精细纹理融合回降噪结果;
- 结果写为带 ICC 配置文件与 EXIF 的 TIFF;
- TIFF 自动导入图库、与源图像分组,并继承源图的用户标签(内部
darktable|*自动标签跳过),使输出仍能出现在基于标签的收藏中。
导入逻辑在 src/libs/neural_restore.c 的_import_image()中实现:除标签外还会从源图复制星级评分、颜色标签、地理位置与标题描述等数据库元数据,并把新图加入源图所在分组;若源图当时是分组代表图,还会将输出提升为新的分组代表。
4.3 模型规格
单输入模型(NAFNet、UNet、NIND):
| 张量 | 名称 | Shape | 类型 | 说明 |
|---|---|---|---|---|
| 输入 0 | input | [1, 3, H, W] | float32 | sRGB 图像,NCHW 平面布局,值域 [0,1] |
| 输出 0 | output | [1, 3, H, W] | float32 | 去噪后的 sRGB 图像,同布局 |
- H 与 W 是动态维度(运行时由块尺寸决定);
- 输入与输出空间尺寸必须一致(scale = 1x)。
多输入模型(FFDNet):
| 张量 | 名称 | Shape | 类型 | 说明 |
|---|---|---|---|---|
| 输入 0 | input | [1, 3, H, W] | float32 | sRGB 图像 |
| 输入 1 | sigma | [1, 1, H, W] | float32 | 噪声水平图,值 = sigma / 255.0 |
| 输出 0 | output | [1, 3, H, W] | float32 | 去噪图像 |
多输入模型需在config.json中设置"num_inputs": 2。
4.4 色彩空间约定
模型工作在 sRGB 空间,色彩转换由 restore 模块负责:
- 推理前:线性 Rec.709 → sRGB(IEC 61966-2-1);
- 推理后:sRGB → 线性 Rec.709。
4.5 分块策略
- 块尺寸按顺序尝试:2048、1536、1024、768、512、384、256;
- 每边重叠 64 像素;
- 内存预算为 darktable 可用内存的 1/4;
- 边界处理:镜像填充(mirror padding)。
从 restore_rgb.c 的dt_restore_process_tiled()实现可以看到具体分块几何:step = T - 2*O(T 为块尺寸,O 为重叠),输出步长为step*scale,按cols × rows网格平铺,并对块输入、块输出与行缓冲做失败可恢复的内存分配(g_try_malloc)。块尺寸的解析与 OOM 重试(tile ladder 降级)在 src/common/ai/restore.c 的_resolve_tile_size()中完成。推理失败时还提供dt_restore_reload_session_cpu()作为兜底——在 GPU 推理失败(不支持的算子、显存不足、EP 崩溃)时卸载原会话并在 CPU 提供方上重建,同一次任务最多尝试一次 CPU 回退。
4.6 细节恢复(DWT)
基于离散小波变换的亮度细节恢复流程:
- 提取亮度残差:
原始 - 降噪; - 用 5 波段小波分解滤波;
- 高频细波段(噪声)被激进阈值化;
- 低频粗波段(纹理)被保留;
- 滤波后的残差以用户可控强度混合回结果。
在实现中,细节恢复强度通过 darktablerc 键plugins/lighttable/neural_restore/detail_recovery_bands调节(逗号分隔的各波段阈值乘数),实际小波处理调用dwt_denoise()(声明于 restore_rgb.c 顶部,对应src/common/dwt.c)。此外,对于具备阴影提升(shadow boost)能力的模型,dt_restore_process_tiled()会在分块前对整图做一次深阴影占比分析(_image_has_deep_shadows),一次性决定是否启用阴影提升曲线,保证所有块采用同一标志、避免逐块接缝。
4.7 config.json 示例与 ONNX 导出
{ "id": "denoise-nind", "name": "denoise nind", "description": "UNet denoiser trained on NIND dataset", "task": "denoise", "backend": "onnx", "num_inputs": 1 }推荐的 PyTorch 导出方式(H/W 保持动态以便运行时自由选块):
torch.onnx.export(model, dummy_input, "model.onnx", input_names=["input"], output_names=["output"], dynamic_axes={ "input": {2: "height", 3: "width"}, "output": {2: "height", 3: "width"} })五、Upscale:超分辨率放大
5.1 任务定位
Upscale 对已显影图像做 2 倍或 4 倍超分辨率放大。任务键为"upscale",加载器dt_restore_load_upscale_x2/dt_restore_load_upscale_x4位于 src/common/ai/restore.h,推理与 Denoise 共用 src/common/ai/restore_rgb.h 的dt_restore_process_tiled,消费端同为 src/libs/neural_restore.c。
5.2 工作原理
处理管线与 Denoise 相同,区别仅在于输出尺寸被放大:
- 2x:输出为
[1, 3, H*2, W*2]; - 4x:输出为
[1, 3, H*4, W*4]。
单个模型可通过两个独立 ONNX 文件同时提供两种倍率:
model_x2.onnx提供 2x 放大;model_x4.onnx提供 4x 放大。
5.3 模型规格
| 张量 | 名称 | Shape | 类型 | 说明 |
|---|---|---|---|---|
| 输入 0 | input | [1, 3, H, W] | float32 | sRGB 图像,NCHW 布局 |
| 输出 0 | output | [1, 3, H*S, W*S] | float32 | 放大后的 sRGB 图像(S = 缩放倍数) |
5.4 分块与流式写出
- 块尺寸按顺序尝试:512、384、256、192(比 Denoise 小,因为存在 scale² 的内存放大系数);
- 每边重叠 16 像素;
- TIFF 流式写出:扫描线直接写出、不缓冲完整放大结果——这对大图至关重要,60MP 图像做 4x 放大需要约 3.6GB 内存。
dt_restore_process_tiled()通过行写出器(dt_restore_row_writer_t)逐行落盘,正是为满足这一内存约束而设计的接口。
5.5 config.json 示例与目录布局
{ "id": "upscale-bsrgan", "name": "upscale bsrgan", "description": "BSRGAN 2x and 4x blind super-resolution", "task": "upscale", "github_asset": "upscale-bsrgan.dtmodel", "default": true }upscale-bsrgan/ config.json model_x2.onnx model_x4.onnx六、任务清单规范与通用约束
综合四类任务,config.json的核心字段约定如下(完整字段表见 dev-doc/AI.md):
| 字段 | 必填 | 默认值 | 说明 |
|---|---|---|---|
id | 是 | -- | 全局唯一标识 |
name | 是 | -- | UI 中显示的模型名 |
description | 否 | "" | 简短描述 |
task | 否 | "general" | 任务类型:"denoise"、"upscale"、"mask"、"rawdenoise"等 |
backend | 否 | "onnx" | 后端类型(目前仅"onnx") |
arch | 否 | "" | 模型架构(如"sam2"、"segnext") |
num_inputs | 否 | 1 | 模型输入数量 |
模型发现机制为:扫描模型目录(自定义路径或<user_data_dir>/darktable/models/,Linux/macOS 为~/.local/share/darktable/models/,Windows 为%APPDATA%\darktable\models\)下各子目录中的config.json,先发现者优先(重复 ID 跳过)。下载的模型也解压到同一路径,因此下载后立即可被发现。用户可在偏好设置中开启 AI 功能并下载模型,相关实现见 src/common/ai_models.c 与 src/gui/preferences_ai.c。
对任何新接入的任务,可遵循 dev-doc/AI.md 的"新增 AI 功能"四步流程:在 src/common/ai 下创建处理模块(不透明类型 + 包装dt_ai_*调用)→ 在 src/CMakeLists.txt 的USE_AI段登记源文件 → 在 data/ai_models.json 添加模型条目 → 创建 UI 消费模块(lighttable 模块放src/libs/、darkroom IOP 放src/iop/),UI 层只允许包含src/common/ai/的头文件,不得直接包含ai/backend.h或common/ai_models.h。
七、小结
darktable 的 AI 任务体系围绕统一的 ONNX Runtime 后端与模型注册表展开,四类任务各有清晰的输入输出契约:
- Object Mask(
mask):编码器 + 解码器两段式,编码结果缓存、解码结果迭代精化,SAM2 支持多蒙版与框提示、SegNext 仅单蒙版点提示,解码器强制 CPU 执行; - Raw Denoise(
rawdenoise):在 CFA 域工作,Bayer 变体(bayer_v1,4 通道打包、模型内 PixelShuffle 去马赛克、输出 CFA Bayer DNG)与 Linear 变体(linear_v1,复用 darktable 去马赛克、输出 LinearRaw DNG)共享任务键并按传感器路由,input_kind契约不匹配即为硬错误; - Denoise(
denoise):sRGB 域推理(Rec.709 ↔ sRGB 双向转换),支持单/双输入模型(FFDNet 的 sigma 图),配套 DWT 细节恢复与可选阴影提升; - Upscale(
upscale):与 Denoise 同管线,输出按 scale 放大,采用更小的分块与 TIFF 流式写出控制内存峰值。
每个任务的config.json都是模型可被 darktable 识别与正确执行的关键:task决定路由,arch决定分割模型的加载分支,variants/num_inputs等字段进一步细化加载行为。遵循本文给出的张量规格、预处理顺序与导出约束,即可为 darktable 制作符合规范的 ONNX 模型包(.dtmodel),并借助源码级文档 dev-doc/AI.md 将其完整接入现有工作流。
【免费下载链接】darktabledarktable is an open source photography workflow application and raw developer项目地址: https://gitcode.com/GitHub_Trending/da/darktable
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考