简易的黑场分析和动态范围计算脚本

简易的黑场分析和动态范围计算脚本

前言

相机的动态范围的测量,对于普通用户来说,曾经是完全不可能的事情。兰拓虽然很早就发布了自家的EDR计算方法,但是对于SNR-based DR,以前只有dxo使用自研的精密灰阶目标和dxo analyzer来对原始数据进行分析,得出结果。

后来随着dxo自己乱作导致公信力逐渐减弱,手机榜彻底沦为笑柄,相机传感器和镜头榜也几乎完全停止更新,photons to photos(ptp) PDR图表变成了摄影圈赛博斗蛐蛐的最佳神器。ptp的数据实际上是全球网友贡献的,使用站长bclaff公开的工具和流程,就可以获得数据。虽然看起来很不错,但是就连网站正式公布的数据,精度也会受到数据采集者的操作手法的限制(可能是屏幕脏,以及虚焦程度不够),出现数据偏低的情况。(我有一个实例可以证明,但是不公布了,没啥意义)。说明他的看似简单的流程,对很多人(甚至包括首次使用的我)来说,还是过于复杂。

本文介绍一种更简单(我觉得已经简单到没法再简单了)的流程,来对自己的相机的逐档ISO动态范围进行测量,并生成与PDR图表很相似的图表。其实方法和结果都很老套,我的一点点小工作主要是把流程进行了简化。

首先明确一下,本文测量的动态范围,是基于fwc / readout_noise的“饱和动态范围(Saturation DR, sat dr)”。公式如下:

SatDR(EV, f-stops) = log_2(\frac{MaxDN}{\sigma_{ReadoutDN}} )

其中,Max_DN根据文件位数在py脚本内手工设定,σ_ReadoutDN从黑场raw中心256*256区域统计得出,混合通道统计,不去除hot pixels。

这个dr被很多人称为Engineering DR(EDR),或者“理论动态范围”,其实就是兰拓发布的算法。但是由于bclaff把snr=1=0dB的DR也称为EDR(The low endpoint for Engineering Dynamic Range is determined by where the SNR curve crosses the value of 1.),我自己造了这个术语,并且在任何场合下都避免单独使用EDR,以免造成混淆和误解。

每档ISO对应的sat dr使用一张黑场raw就可以进行测量,多张同时测量可以形成一个曲线。SNR-based dr的测量不在本文讨论范围内,可以参考我的其余文章。逐档PDR如果ptp网站上没有自己的机器,还是建议走一遍官方sop,还可以顺手给站长发一下数据。


测量方法

我使用一个py脚本来进行计算。简单说来,就是先拍摄一组黑场raw放在同一个文件夹下,再将这个文件夹拖拽到脚本上运行,稍等片刻即可得到结果。

脚本支持下列工作模式:

单个机身逐档ISO,单个机身的MS和ES对比,多台机身对比


标准操作流程SOP如下:

准备工作:盖上镜头盖,快门调到最高,光圈调到最小,单反相机遮住取景器,MF,先将iso调到最低(包含扩展),格式调到无损raw,关闭所有降噪功能,在暗室内。最好是冷机,也可以冷机热机对照。

拍摄工作:先选择机械快门,每小档ISO按一下快门,然后调高1小档,直到iso最高。例如100 -> 125, ..., 102400

额外工作:同一台机身,可以选择电子快门,将ISO调到最低,重复上述拍摄工作。也可以选择另一台机身,重复上述拍摄工作。

文件导出和测量:把raw文件从卡里拷进电脑,所有raw文件(MS vs ES,或者不同机身)放在同一个文件夹下。再把这个文件夹放到py脚本所在目录(可选)。然后再把文件夹拖拽到脚本上,等待脚本运行完毕即可。

MAX_DN = 16383

BASE_ISO = 100

这两项脚本选项可能需要根据实际情况修改,例如12bit raw的max dn是4095,16bit对应16383,10bit对应1023,z7的base iso是64。

MAX_DN可以拍一张完全过曝的raw,再到raw digger里关闭BL,再在顶部面板查看:

测量很简单,将文件夹拖动到脚本执行即可:


结果分析

运行过程大致如上图所示。等cmd窗口消失就完事了。刷新之后会多出来一个excel文件,双击打开(这是z7和a7m5的对比模式):

根据上图,最重要的两列数据,A-ISO和E-饱和DR,形成了图表1:“ISO vs Saturation DR”。

这个图表实际上和ptp的逐档PDR很相似,只是DR标准不一样:

可以看到,z7的max sat dr是13.62,a7m5是14.86,暴打了。

还可以从图表上看到一些额外的信息:

黑线z7的BaseISO=64,扩展ISO的DR不变;ISO400时DR跃升,说明有DCG切换。ISO6400以后的曲线整体轻微上升,ptp里给了上三角标scaling。我目前没有判定这个项目的办法。这里说明dcg引入的所谓“iso不变性”其实不是很准确。在极端低光环境下,如果没有需要重点保护的高光,还是要拉高iso来获得更低的读噪。

红线a7m5的dr逐档下降,没有DCG跳变点。很容易被误认为是没有dcg,bclaff就犯过这个错误并且对自己的结论十分自信,结果在dpreview论坛上再次发帖引用horshark的正确结论给自己打脸。


另一个文件夹,a7m5 MS vs ES的测量结果如下:

黑线是MS机械快门,红线是ES电子快门(我无法自动提取series name,需要自己匹配)

可以看到电子快门的sat dr只有12.96,这是半堆栈提高速度之后需要承受的代价。

ptp PDR图表如下:

可以看到MS和ES在高感的PDR几乎完全一致,但是sat dr还是有少许区别(MS高约+0.4ev)。

而且能看到明显的dcg导致的dr跳变了。红黑线对比,就可以发现,黑线之所以没有明显跳变,一定是使用了DCG融合技术,把dual conversion的数据“焊接”到了一起。官方名称叫做“DCG-HDR”,我一般统称为DGO。

F列DCG融合DR就是一个简易的计算结果,它是将BASE_ISO的额外高光焊接到当前档位之后获得的理论总dr,会比实机数据略高。数据与BASE_ISO的设定有关,不一定准确,仅供参考。(可以看到理论fusion dr比实机的高0.53ev。)它首次出现时对应的iso档位,就是DCG跳变档位。cmd的运行log里也会有单独的提示。例如,上图电子快门下ISO1000首次出现。

下方的ISO vs ISO-Normalized Read Noise图表,是计算iso / base_iso的倍数,再将读出噪声除以这个倍数,得到“iso归一化”下的读噪,可以更明显的看到dcg噪声骤减情况。纵轴是对数刻度,1大格是1档。它的曲线形状和走向,和ptp网站提供的Input-referred Read Noise Chart比较相似但是不完全相同。ptp网站还提供了Read Noise in DNs Chart,我的这个chart算是二者的结合。


与SNR=1=0dB DR的差异

sat dr与SNR=1=0dB DR的差异一般情况下差异较小。例如我的z7使用高密度步进靶图的扫描结果如下:

数据从19个raw里扫描2亿ROI得到,精度极高

dxo screen dr = 13.47, 比sat dr低0.16(约1/6ev),这是正常现象,因为sat dr仅考虑读出噪声,snr=1时有少量散粒噪声,并且z7的RB通道有额外的数字放大导致snr微降和曲线扭曲。

sat dr可以与dxo screen dr进行直接对比(可以预扣除0.3ev),差异小于1/3ev可视为完全相同。

另外,如果希望计算打印模式(例如dxo print的8MP)下的sat dr,需要读者自己列公式计算:

DR_{print}=DR + log_2(\sqrt{\frac{PW\times PH}{8,000,000}})

这是dxo的计算公式(页面已经下线,可从此处访问)。

其中PW是图宽,PH是图高,例如z7是8256*5504,8MP下可获得+1.25ev的增益

(但是dxo使用的数据是包含OB区的,z7是8288*5520所以网站发布的增益是+1.26。另外它的z7的screen dr是13.29,这是它测得不准。)


脚本和示例文件分享

本文使用的脚本公开如下,可以免费随意使用。

通过网盘分享的文件:20260414黑场分析和satDR计算
链接: pan.baidu.com/s/1XVy7Ex 提取码: 1111

“a7m5 -lite”是a7m5的整档iso示例文件,体积较大,也可以不下载。


Energy Spectrum能量谱计算和降噪判断

这是ptp独有的权威功能。我对此进行了一些研究,成果如下:

Photons to Photos同款能量谱(Energy Spectrum)

相关脚本文件也在上述分析地址里。

结论

盖上镜头盖,拍摄一组raw,拖拽一下文件夹,双击excel文件,就可以完成dr测量,还可以顺便看到dcg跳变点以及有没有融合,我真的想不出更简单的办法了。相机厂应该把这个功能直接集成到机身内部,通过菜单直接显示dr,方便赛博斗蛐蛐。

编辑于 2026-04-18 · 著作权归作者所有