news 2026/10/16 1:55:36

为什么NegPy不简单反相胶片负片?暗房级HD曲线与ISO-R分级流水线深度解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
为什么NegPy不简单反相胶片负片?暗房级HD曲线与ISO-R分级流水线深度解析

【免费下载链接】NegPy

Tool for processing film negatives.

项目地址:https://gitcode.com/gh_mirrors/ne/NegPy
点击查看免费下载

NegPy 是一款专为胶片负片扫描打造的暗房级处理工具(Tool for processing film negatives)。为什么它不直接"一键反相",而是引入 H&D 曲线与 ISO-R 分级流水线?因为负片记录的是对数密度而非线性明暗,简单取反只会得到一张"反过来的负片"——发灰、发闷、层次尽失。本文带你深度解析这套负片处理的核心算法与完整流水线。

为什么简单反相会毁掉负片细节?

很多新手以为:负片 = 照片的镜像,取反像素就好。但扫描仪读到的其实是一组光透过率,NegPy 直接在线性 RGB(output_color=raw、gamma=1、统一白平衡)上工作,随后做对数转换:

  • 密度是日志值:胶片密度 $D = \log_{10}(\text{参考透过率} / \text{实际透过率})$,负片的高光和阴影在胶片上是被"压缩"过的,直接反相无法还原这段压缩。
  • 橙色蒙版不是全局色偏:彩色负片每个通道的橙蒙版浓度不同。NegPy 对每个通道独立做百分位定界(0.01%–99.99% 窗口)并拉伸到 [0,1],让橙色蒙版和片基色被各自"中和"掉,而不是用一张白卡颜色去猜。
  • 打印需要曲线:暗房里放大机下的相纸天然带 toe(趾部)、直线段、shoulder(肩部)三段特性。NegPy 把这条曲线完整搬进了算法,反相只是"打印"的第一步。

一句话:NegPy 不是在"反相",而是在模拟一次暗房放大(详见 docs/PIPELINE.md 的 "The Print" 一节)。

暗房级H&D曲线:在密度空间里"打印"照片

🎞️ 这是整个引擎的心脏。归一化后的信号进入密度空间,经过一条非对称 toe-linear-shoulder 特性曲线:

  • 中间是一段斜率为 $k$ 的直线(由 ISO-R 分级决定);
  • toe(阴影端)软着陆到纸黑 $D_{max} = 2.3$;
  • shoulder(高光端)软着陆到纸白 $D_{min} = 0.06$(Paper White Base 可关闭,退回 0);
  • 两端都是softplus 软拐点,用toe_sharpness_base/shoulder_sharpness_base控制膝盖锐度,而非硬截断——所以拉伸到界外的调子会被曲线"卷"回来,而不是直接死黑死白。

曲线核心计算(CPU 引擎,CPU/GPU/图表共用同一数据源):

v1 = d_min_eff + logaddexp(0, a_hl * (v - d_min_eff)) / a_hl # shoulder → 纸白 res = d_max_eff - logaddexp(0, a_sh * (d_max_eff - v1)) / a_sh # toe → 纸黑

源码:negpy/features/exposure/logic.py#L465-L495,常数定义见 negpy/features/exposure/models.py#L144-L165

最后一步把打印密度换算回场景线性光:$I_{out} = 10^{-D}$。之后还有Paper Black开关:关闭时做黑点补偿(类似 ICC 相对比度量软校样),开启则保留纸张抬升的 D-max($10^{-2.3} \approx 0.005$),让最深处"黑得有纸味"。

在这条基础曲线之上,NegPy 还提供了一整套暗房工具:Preflash(预闪光)、Zone Density(分区密度)、Split Grade(分区分级)、Dodge & Burn(加光减光蒙版)、Contrast Mask(对比度蒙版,即暗房 unsharp mask)、Diffusion(扩散片模拟),以及对每个染料层(R/G/B)独立的crossover 修正——因为 CMY 色彩过滤只能"平移"某一层的曲线,只有形状修正才能修掉阴影与高光色偏不一致的问题。

内置纸张档案:从Ilford到Kodak的打印特性

🧪 纸张档案(Paper Profile)只改变 H&D 曲线的形状($D_{max}/D_{min}$、toe/shoulder 锐度与高度、中间调 gamma),对比度仍归 Grade 管。内置档案按处理模式分组:

纸张档案类型D-max特点
Neutral(默认)通用2.3与默认曲线逐位一致
Ilford Multigrade FB Classic黑白2.15纤维纸,阴影更深、膝盖更锐
Foma Fomatone MG Classic黑白2.0暖调氯化溴化,经典石印纸
Kodak Polymax II RC黑白2.13依 G-26 数据表曲线拟合
Kodak Portra EnduraRA42.65依 E-4021 数据表拟合
Kodak Ultra EnduraRA42.61依 E-4020 数据表拟合
Fujicolor Crystal ArchiveRA42.35鲜艳蓝绿,估算参数

档案定义:negpy/features/exposure/papers.py#L96-L239;Kodak 系列用 scripts/fit_paper_profile.py 对着数据表曲线拟合到 RMS ≤ 0.05 D 才接受。RA4 彩色纸还带染料耦合矩阵(如 Endura 的青染吸收部分绿光)与片基色 tint,模拟真实相纸的"串色"。

档案是模式感知的:彩色负片只出现 RA4 纸,黑白负片只出现黑白纸,幻灯片(E-6)只有 Neutral——存下来的不兼容值会自动回落到 Neutral,永远不会"泄漏"进渲染。

ISO-R分级教程:像暗房选纸一样调对比度

💡 NegPy 的对比度不用抽象的 0–5 数字,而是采用摄影标准ISO 纸级曝光范围(R 值):

  • 滑杆范围R50(很硬)→ R180(很软),默认R115,其中 R110 ≈ 经典 2 级灰纸;
  • 斜率换算:$k = 2.9 \times \text{负片密度范围} / (R/100)$,钳制在 [2.0, 10.0]——即"对比度 = 负片密度范围 ÷ 纸张曝光范围",和真实分级纸的物理定义完全一致;
  • 旧版 0–5 纸级编辑自动迁移:$R = 150 - 20 \cdot G$,观感不变。

换算实现:negpy/features/exposure/logic.py#L861-L875(grade_to_slope/slope_to_grade)

每个蒙版还能有自己的Local Grade(以 ISO-R 点偏移帧级分级),相当于"用一个更硬的滤镜烧天空"。

自动测光:Auto Density 与 Auto Grade 如何工作

这两个助手默认开启,且只读有纹理的区域(块中值 + 纹理投票,避免片基、天空和大白墙干扰测光):

助手策略目标密度
Auto Density以 0.46 为假设锚点,按 20% 强度向实测值拉取,限幅 ±0.12锚点打印至 0.75 D
Auto Grade按纹理密度范围(P10–P90)做"部分 ISO R 匹配",平的画面给一点提亮、硬的画面不硬推正常负片目标 0.85
Shadow Reach最暗纹理调子(P99)必须打出 ≥1.9 D,不足则抬高斜率(永不降低)1.9 D(直线段)
Highlight Hold最亮纹理调子(P2)若打过0.10 D,自动补一个高光减光0.10 D
Shadow Hold对 Shadow Reach 尾巴做部分提亮(强度 0.40,上限 0.3)只提亮、不减光

实现:Shadow Reach negpy/features/exposure/logic.py#L1077-L1090、Highlight Hold negpy/features/exposure/logic.py#L1093-L1109、Auto Grade 因子 negpy/features/exposure/logic.py#L1032-L1039

此外还有Set Targets面板:这八个瞄准值(锚点打印密度、测光信任度、Shadow Reach 目标等)可以按自己的扫描仪和口味整体校准,属于"标定"而非"编辑",对已处理的帧同样生效。

负片处理流水线:从扫描到成图的9个阶段

📷 完整渲染顺序(各阶段串联,前级缓冲传给后级):

#阶段干什么源码位置
0修复烘焙IR 去尘/划痕检测,写回线性源(非阶段,先于几何)negpy/features/retouch
1Geometry旋转、畸变校正、tilt/swing、自动裁切negpy/features/geometry
2Scan Normalization平面场校正、传感器串色解混、对数转换、百分位定界与拉伸negpy/features/exposure/normalization.py
3The PrintH&D 曲线 + ISO-R 分级(本文主角)negpy/features/exposure
4CLAHECIELAB L* 上的局部对比度(8×8 瓦片)negpy/features/lab
5Lab Scanner Mode色度降噪、饱和度、肤色保护、锐化、辉光、红晕同上
6Alt Processes石印 / 晒蓝 / Sabattier(仅黑白模式)negpy/features/lith 等
7Toning六浴化学调色"银台账" + 分割调色negpy/features/toning
8Finish边缘暗角、冲裁胶片边、装框、导出锐化negpy/features/finish

色彩管理上,工作空间始终是线性 RGB(Adobe RGB 原色 + D65),Adobe RGB TRC 是引擎最后一步 OETF;软校样是一张 65³ 的 3D LUT 而非渲染阶段,导出时转换到目标色域并内嵌 ICC 档案——预览、缩略图与导出因此永远一致。

谁适合使用NegPy?

  • 🎞️ 拥有负片/幻灯片扫描件(Plustek、Coolscan、SANE 扫描仪或相机 RAW)的胶片玩家;
  • 想要"开箱即打印"的自然观感,又不想放弃暗房式手工控制(分级、加光减光、调色、石印);
  • 在意无损编辑(源文件永不改动,编辑存于本地 SQLite,可选.negpy旁挂文件)与预览-导出一致性(CPU/GPU 引擎逐位对齐)。

延伸阅读与源码导航

  • 完整管线数学:docs/PIPELINE.md
  • 面板与控件使用手册:docs/USER_GUIDE.md
  • 串色解混档案(.toml):docs/CROSSTALK.md 与 crosstalk/
  • H&D 曲线与分级核心:negpy/features/exposure/logic.py
  • 纸张档案数据:negpy/features/exposure/papers.py
  • 数据表曲线拟合脚本:scripts/fit_paper_profile.py

【免费下载链接】NegPy

Tool for processing film negatives.

项目地址:https://gitcode.com/gh_mirrors/ne/NegPy
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/16 1:54:38

TwinCAT 2.0从入门到精通:PDF手册实战指南与避坑技巧

简介:《TwinCAT 2.0从入门到精通》是面向Beckhoff自动化系统工程师的实践型教程,由拥有近15年倍福技术工作经验的Lizzy Chen编写,非官方发行。内容聚焦TwinCAT 2这一PC-based控制平台,覆盖系统配置、PLC编程、EtherCAT与K-Bus I/O…

作者头像 李华
网站建设 2026/10/16 1:48:57

微信小程序折线图选型实战:wx-f2 替代 ECharts 的轻量方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/16 1:48:47

双串电池均衡方案:MP2642GR-Z与PIC24FV16KA302软硬件实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华