如何科学而正确地去除色罩?

从负片转换、去色罩、校色,到整卷管理与高质量导出,都在一个独立的本地工作区完成。

大家好,我是 Billy,一名胶片摄影爱好者。

拍摄胶片之后,我经常会遇到一个很具体的问题:扫描或翻拍本身并不算困难,但真正进入后期时,负片转换往往需要在多个软件之间来回切换。

扫描文件要先导入图库,再处理橙色片基,接着调整黑白场、色彩平衡和反差,最后还要重新整理文件名、胶卷信息和导出结果。处理一张照片尚且麻烦,处理完整一卷时,这些重复工作会迅速放大。

更重要的是,负片转换并不是简单地把 RGB 数值反相。直接在 sRGB 图像上做反相,常常会出现暗部偏蓝、高光断层、肤色不自然,以及不同照片之间颜色不一致等问题。

市面上已经有一些成熟的商业方案,但其中一部分需要依赖 Lightroom Classic 等宿主软件,并采用额外的商业许可。并且某些软件并没有实现科学去色罩原理。对于希望使用独立桌面应用、完全本地处理,或者希望了解和参与底层实现的摄影师来说,选择并不算多。

所以,我和一位同济设计专业的同学一起,做了 NexFilm Engine。

NexFilm 主界面

它是一款面向胶片扫描工作流的独立桌面应用,重点解决四件事:

  • 胶片负片转换与去色罩
  • 胶片范围和透视校正
  • 整卷照片的批量管理与处理
  • 面向存档和分享的高质量输出

NexFilm Engine v1.0 现已在 GitHub 开源,采用 GPL-3.0-only 协议,Windows 和 macOS 用户可以免费下载使用。

一、NexFilm 适合做什么?

NexFilm 并不是要替代 Photoshop、Lightroom 或其他完整后期软件。

它更像是一间独立的数字暗房,专门负责胶片扫描之后最关键、最容易重复的一段流程:

导入负片,确认有效画面区域,完成反相和基础校色,批量处理同卷照片,并按照归档或分享需求导出。

软件支持常见相机 RAW 格式,包括 DNG、NEF、CR3、ARW、RAF、RW2 等,也支持 TIFF、JPEG、PNG,以及部分扫描仪或 Flextight 工作流中的 FFF 文件。

不同格式的结果会受到相机、扫描仪、输入配置文件和具体采集方式影响。尤其是 JPEG 文件,并不能保证拥有完整的线性数据,因此更适合作为兼容输入,而不是最理想的校色源。目前校色效果最好的是各相机翻拍的底片。

技术实现上,NexFilm 使用 Rust、Tauri、SQLite 和 WebGL。对使用者来说,这些技术最终体现为三点:

  1. 大尺寸预览时仍然可以实时调整。
  2. 编辑参数、胶卷资料和预览图都保存在本地。
  3. 核心工作流不依赖云端服务,原始扫描文件不会被覆盖或上传。

二、从导入到导出的完整工作流

1. 按胶卷建立档案

NexFilm 的基本单位不是“随手打开的一张图片”,而是一卷胶片。

导入整卷照片时,可以填写画幅、相机、胶片型号和拍摄日期。软件会按照胶卷建立本地记录,方便之后继续编辑、追加画面、修改元数据或重新定位源文件。

如果只是临时处理几张散片,也可以使用 Loose Import,或者直接将文件拖入窗口。

NexFilm 不会复制或修改原始扫描文件。应用保存的是源文件路径、预览图、胶卷信息和编辑参数。因此,移动原图之后,需要在软件中使用 Locate File 重新关联。

整卷导入 胶片元数据设定

2. 自动识别胶片范围

进入 Develop 工作区后,第一步通常是确认胶片的有效成像区域。

NexFilm 提供 Auto Area,可以尝试自动识别胶片边缘。检测完成后,仍然建议检查四个角和边缘位置。对于边框明显、画幅规则的扫描,可以直接拖动边缘进行微调。

如果相机、镜头、灯板和底片夹的位置固定,同一卷中的照片通常具有相似几何关系。此时可以使用 Batch Apply,将已经确认的裁切和透视参数应用到同卷其他画面。(在1.0版本这个功能还未经验证)

但这项功能有一个前提:照片的机位和底片位置确实足够一致。如果每张底片的位置差异较大,仍然应该逐张检查。

自动胶片范围识别

3. Auto Invert 与基础校色

确认有效区域后,点击 Auto Invert。

软件会先分析当前画面中的有效图像区域,估计密度范围,再生成正片预览。这个过程会尽量排除裁切区域外的空白、大片边框和齿孔对结果的干扰。

完成反相后,可以继续使用以下工具:

  • Density Limits:调整 D-Min 和 D-Max,重新定义画面的有效密度范围。
  • Printer Lights:使用红/青、绿/洋红、蓝/黄的互补色关系进行色彩平衡。
  • Exposure 与 Gamma:调整整体亮度和中间调反差。
  • Highlights 与 Shadows:控制高光和暗部的过渡。
  • Saturation、Temperature、Tint:进行常规色彩修正。
  • Color / B&W:在彩色和黑白模式之间切换。
  • Sample Sprocket Hole:从齿孔或未曝光片基区域采样,辅助估计片基颜色。
  • LUT:使用内置的 Kodak、Ilford 打印胶片或相纸风格,也可以载入自定义 .cube 文件。

需要说明的是,LUT 更适合被理解为风格和输出映射,而不是胶片型号的完整物理校准。通常建议先完成去色罩和密度调整,再使用 LUT 进行风格控制。

调整图片参数

4. 复制设置与整卷批处理

完成一张照片的基础调整后,可以按类别复制参数。

例如,只复制:

  • 密度范围
  • Printer Lights
  • LUT
  • 几何校正
  • 齿孔设置

这样可以避免把某一张照片的曝光修正、裁切位置和色彩风格全部无差别复制到其他画面。

对于光线、机位和冲洗条件一致的一整卷照片,这种方式可以显著减少重复调整工作。

5. 输出与接触印样

NexFilm 支持导出选中画面,也支持整卷导出。

输出格式包括:

  • 16 位 TIFF
  • 8 位 TIFF
  • 16 位 PNG
  • 8 位 JPEG

同时可以选择输出色彩空间、尺寸、放大策略、锐化、JPEG 质量、命名模板和重名处理方式。

如果需要存档或继续在其他软件中精修,建议优先选择 16 位 TIFF。JPEG 更适合日常分享和网络发布。

此外,NexFilm 还提供 Contact Sheet 功能,可以根据胶卷型号、拍摄日期、相机和画面编号生成接触印样,适合胶卷归档、挑片和社交媒体分享。

135胶卷的接触印相卡片

三、为什么负片转换不能只是“反相”?

这是 NexFilm 最核心的部分。

胶片扫描得到的 RGB 数值,并不等同于最终照片中的亮度和颜色。对于彩色负片来说,扫描数据同时受到以下因素影响:

  • 胶片橙色片基
  • 三层染料的光谱吸收
  • 翻拍灯板或扫描仪的光谱
  • 相机和扫描仪的响应曲线
  • 输入文件的 Gamma 或 ICC 配置
  • 曝光、黑位和扫描动态范围

如果直接对一个已经编码过的 sRGB 文件做数值反相,实际上是在错误的空间中运算。

因此,NexFilm v1.0 的处理流程可以简化为:

输入文件
  ↓
识别输入方式并线性化
  ↓
线性 RGB → 透射率
  ↓
透射率 → 光学密度
  ↓
扣除片基密度
  ↓
去除通道串扰
  ↓
D-Min / D-Max 归一化
  ↓
曝光、Gamma、Printer Lights 和 LUT
  ↓
目标色彩空间与最终输出

下面逐步解释这条管线。

1. 先把输入转换到线性数据

RAW 文件通常包含相机传感器记录的线性响应,但它仍然需要经过解码、黑位和白位处理、相机白平衡以及相机矩阵转换。

NexFilm 的 RAW 解码路径会使用线性输出,并将数据统一到当前版本使用的固定 Linear sRGB 密度采集坐标中。

对于 JPEG 和 PNG,软件默认按照 sRGB 解释;如果文件包含能够识别的 ICC 配置文件,则优先使用该配置。扫描仪 FFF 则按照其文件结构进行解析,并使用相应的传递曲线进行线性化。

这里的“线性”非常重要。

Gamma 编码后的数值更适合显示和存储,但不适合直接表示光量。只有在线性空间中,像素值的比例关系才可以近似对应实际接收到的光量。

2. 用透射率计算光学密度

胶片负片本质上是一个光学透射介质。

可以把经过线性化后的像素值视作相对透射率 T,然后计算:

 D_{\text{raw}} = -\log_{10}(T)

其中:

  • T 越大,表示透过的光越多。
  • T 越小,表示胶片吸收的光越多。
  • D 越大,表示光学密度越高。

为什么要使用对数?

因为胶片的密度本来就是对数意义上的量。在透射率空间中,多个光学因素往往表现为乘法;进入密度空间后,它们会变成更容易处理的加法。

这也是为什么在密度域调整曝光和色彩,通常比在 Gamma 编码后的 RGB 上直接拉曲线更稳定。

当输入值接近零时,软件会使用一个极小正数作为下限,避免对零取对数产生无穷大。这能保证计算稳定,但并不意味着输入文件真的拥有无限动态范围。

3. 扣除胶片片基

彩色负片的橙色片基会覆盖整个画面。

如果不先处理片基,反相后的结果往往会严重偏色,尤其是暗部和中间调。

设图像密度为 D_{\text{image}},片基密度为 D_{\text{base}},那么净密度可以写成:

 D_{\text{net}} = D_{\text{image}} - D_{\text{base}}

由于:

 -\log_{10}(T_{\text{image}}) - [-\log_{10}(T_{\text{base}})] = -\log_{10}\left( \frac{T_{\text{image}}}{T_{\text{base}}} \right)

所以,密度域的减法,本质上对应透射率的相对除法。

这一步可以有效减轻橙色片基和拍摄灯板色温带来的整体偏移。但它有一个前提:片基采样最好来自同一套相机、镜头、灯板和曝光条件。它不是一个对所有设备都通用的固定白平衡值。

4. 处理染料通道之间的串扰

彩色负片的三层染料并不是理想的 R、G、B 三个独立通道。

一个通道的变化可能会影响另外两个通道。如果只对三个通道分别做独立反相,颜色容易出现互相污染。

NexFilm v1.0 在彩色模式下使用一组固定的 3×3 去串扰矩阵,对扣除片基后的密度进行经验性校正:

 D_{\text{corrected}} = M \cdot D_{\text{net}}

这里的矩阵可以理解为 Status M 思路的工程近似,用来减轻染料通道之间的影响。

需要明确的是,v1.0 使用的并不是针对每一台相机、每一块灯板和每一种胶片单独测量得到的完整 Status M 标定结果。它属于绑定在当前线性 sRGB 捕获域中的经验估计,不能被理解为对所有设备和胶片都成立的通用物理常数。

黑白模式则会把密度合成为单通道,并使用固定 Linear sRGB 捕获域中的亮度权重:

 Y = 0.2126R + 0.7152G + 0.0722B

这能让黑白负片的整体明暗关系更加稳定。

5. 自动估计 D-Min 和 D-Max

完成密度计算后,还需要确定画面中哪些部分应该对应输出的暗部和高光。

NexFilm 的 Auto Invert 会在预览数据上建立每通道 65,536 档直方图,然后根据密度分布估计有效的 D-Min 和 D-Max。

它不是简单地取全图最暗和最亮的两个像素,而是通过尾部统计减少灰尘、划痕、边框和极端孤立像素的影响。对于彩色画面,还可以使用来自相同像素位置的通道样本,避免 R、G、B 各自从不同物体上选出端点。

最终,密度会按照选定范围归一化:

 N = \frac{D - D_{\min}}{D_{\max} - D_{\min}}

然后再应用 Gamma、高光、阴影和 Printer Lights 等控制。

因此,D-Min 和 D-Max 并不只是传统意义上的“黑场”和“白场”,它们同时决定了画面的整体反差、色彩分离和高光过渡。Auto Invert 是一个起点,而不是不需要检查的最终答案。

6. 为什么 v1.0 没有直接把密度计算放进 ProPhoto?

这是一个容易被宣传文案说错的地方。

更大的色域不等于更适合直接进行胶片密度测量。一般情况下:

 -\log_{10}(Ax) \neq A[-\log_{10}(x)]

也就是说,不能先把数据通过一个普通 RGB 矩阵变换到另一个色彩空间,再假设密度结果仍然等价。

因此,NexFilm v1.0 将密度测量固定在经过验证的 Linear sRGB 捕获域中。这样做的优点是定义明确、行为可测试,也避免把“工作色域更大”和“密度测量更准确”混为一谈。

Linear ProPhoto、f32 浮点缓冲区、更加完整的输入配置文件以及设备级标定,是后续版本的设计方向,而不是 v1.0 已经完成的全部能力。

7. 预览与导出的色彩处理

NexFilm 的 WebGL 预览和全尺寸导出使用同一套核心密度处理逻辑。

在最终导出阶段,软件会根据目标色彩空间进行矩阵转换,重新编码为对应的输出传递函数,并嵌入匹配的 ICC 配置文件。支持的输出空间包括 sRGB、Display P3、Adobe RGB、Rec.2020、ProPhoto RGB、ACEScg 和 ACES2065-1。

量化、锐化和 JPEG 压缩都尽量放在最终输出阶段完成,避免在中间处理时过早损失精度。

四、它适合哪些人?

NexFilm 比较适合以下场景:

  • 使用数码相机翻拍胶片负片。
  • 使用扫描仪生成 TIFF 或 FFF 文件。
  • 希望按整卷管理照片,而不是逐张处理。
  • 希望在 Lightroom 之外拥有一个独立的负片转换工具。
  • 需要批量导出 16 位 TIFF 或接触印样。
  • 关注本地处理、数据隐私和开源许可。

它暂时不适合以下期待:

  • 希望直接获得针对每一款胶片的实验室级特性曲线。
  • 希望通过一张 24 色卡就完成所有相机、灯板和胶片的自动标定。
  • 希望完全不检查自动检测结果。
  • 主要使用严重压缩的 JPEG,并期待和线性 RAW 相同的校色空间。

胶片转换本身仍然受到拍摄光源、底片状态、冲洗条件、扫描设备和输入文件质量的影响。软件可以提供稳定的处理框架,但不能替代采集环节的控制。

五、目前的限制与使用建议

目前 v1.0 的 Windows 和 macOS 安装包尚未进行代码签名,macOS DMG 也尚未经过 Apple 公证。首次启动时,系统可能显示安全提示,请确认安装包来自官方 Releases 页面。

另外,RAW 和 FFF 的兼容性仍然取决于具体相机或扫描仪型号。遇到无法打开的文件时,建议在 Issue 中提供系统版本、设备型号、文件格式和错误信息,但不要上传包含隐私内容的原片。

使用时建议注意以下几点:

  1. 尽可能使用 RAW 或高位深 TIFF,不要把 JPEG 作为主要校色源。
  2. 翻拍时保持灯板、相机、镜头和曝光条件稳定。
  3. Auto Area 完成后先检查有效画面区域。
  4. Batch Apply 只用于几何位置确实一致的画面。
  5. Sample Sprocket Hole 时,应选择干净、未曝光且没有漏光的片基区域。
  6. 批量导出前,先导出一张样片检查亮度、色彩和 ICC。
  7. 始终保留原始扫描文件,并备份 NexFilm 的本地数据目录。

其次,1.0版本还有很多未经验证的BUG。如果发现BUG,欢迎与作者取得联系反馈。

六、未来计划

NexFilm v1.0 先把完整的本地工作流搭建起来。后续版本会继续完善以下方向:

  • 更明确的相机、扫描仪和灯板输入配置。
  • 暗场与平场校正。
  • 基于 f32 浮点和更宽工作空间的处理路径。
  • 针对固定设备组合的密度标定。
  • 参考控制条、透射目标和胶片特性曲线。
  • 更完善的胶片与冲洗条件管理。
  • 24 色卡辅助的相机和光源配置。

其中,24 色卡可以帮助建立相机和光源的输入配置,但它不能单独解决负片三层染料的全部串扰问题。更可靠的校准还需要固定采集条件,并使用参考透射目标或控制条进行独立验证。

七、下载与反馈

NexFilm Engine v1.0 完全开源,采用 GPL-3.0-only 协议。

请使用电脑访问官方 GitHub Releases 页面:

下载 NexFilm Engine v1.0

目前提供:

  • Windows 10 ⁄ 11 x64
  • macOS Apple Silicon
  • macOS Intel

Releases 页面中的 Source code 压缩包不是可直接运行的安装包,请根据电脑架构下载对应的安装程序或 DMG。

如果 NexFilm 对你的胶片工作流有所帮助,欢迎在 GitHub 提交 Issue,反馈具体设备、文件格式和使用场景。也欢迎为项目点亮 Star,帮助更多胶片摄影师发现这个工具。

NexFilm 还处在持续完善阶段,但它希望先把一件事做好:让胶片扫描之后的负片转换,变成一个独立、透明、可复现,并且真正属于摄影师自己的数字暗房。

发布时建议把配图顺序安排为:主界面、导入胶卷、Film Area 与透视校正、反相前后对比、参数面板、Contact Sheet。原文中的“60fps”“完美去色罩”“完全遵循 Cineon”“Linear ProPhoto 已作为当前内部工作空间”等表述,建议不要使用,换成上面这种可验证的说法会更稳妥。

编辑于 2026-08-05 · 著作权归作者所有