我正在做一个玩具项目,涉及处理一堆用间隔计拍摄的照片图像。基本上,我想用它们做一个时间流逝,并进行一些修正,以便剪辑更整洁。我使用佳能dSLR。
我需要一个函数,在给定JPEG文件的情况下,它会计算出“平均场景亮度”。结果应该是一个简单的数字;不需要在任何绝对光度单位中表达,我只做相对比较。因此,例如,你拍摄一些房间的照片,然后函数返回“5.0”。然后在灯光下添加第二个灯泡,与第一个灯泡完全相同,放在旁边,再次拍摄。该功能现在应该为您提供“10.0”。
因此,我目前对此功能的实现结合了以下几点:ISO感光度,快门速度,光圈(从EXIF中提取)和平均图像亮度。 Exif的东西显然更重要,因为在自动模式下,相机会尝试使用这样的设置,因此图像亮度会出现在灰色中点附近。 然而,ISO /快门/光圈设置的分辨率均为1/3或更低,因此检测图像亮度对于“微调”非常重要。
当我这样做的时候,我得到了一些明显的虚假结果,而且我挖的越多,我就越困惑。所以最后我设置了一个“几乎认真”的实验:
测试设置: 房间里有一个简单的墙壁,用白炽灯点亮,照明非常均匀。 使用两个相机来比较结果:5D与50mm素数,350D与35mm素数。 到墙的距离:约3米。 所有照片均以1/10秒的快门速度拍摄。 相机设置:手动,“忠实模式”(无增强功能,无饱和度或对比度凹凸),Tungsten WB,无自定义功能,JPEG-Fine,sRGB色彩空间。镜头没有过滤器。照明不会改变,我只改变ISO和光圈设置。 以下是我得到的结果:
Avg Spd ISO Aperture
1. 0.3507, 0.10, 100, f/2.8
2. 0.5382, 0.10, 200, f/2.8
3. 0.3557, 0.10, 200, f/4.0
4. 0.2709, 0.10, 200, f/5.0
5. 0.2118, 0.10, 200, f/5.6
6. 0.1718, 0.10, 200, f/6.3
7. 0.1459, 0.10, 200, f/7.1
8. 0.1112, 0.10, 200, f/8.0
9. 0.0883, 0.10, 200, f/9.0
第一列是平均像素值(直接来自JPEG),在整个图像上取平均值,转换为灰度为(R + G + B)/ 3。通过将[0..255]范围除以255,将颜色在[0..1]范围内标准化。 因此,在1)和2)之间,我只改变ISO设置,图像应该变为亮度的两倍,但平均像素值仅上升53%(没有任何过度曝光的区域)。
2..3:光圈一个停止,所以图像应该变亮一半,所以1)和3)同意(额外的亮度可能是由于渐晕减少)
3..5:再次,一次停止,5)应该是3)的亮度的一半
5..8:同样,应该是一半(这基本上没问题)。
这一切都非常非常奇怪。顺便说一句,两台相机之间的结果是一致的,这表明这不仅仅是特定型号的特殊性。
这不会应用任何伽马校正。 JPEG读取代码使用C ++,基本上遵循IJG示例代码(djpeg
实用程序)。现在,JPEG保存了伽马校正值,因此像素值应被视为sRGB颜色空间中的值(获取源像素,转换为[0..1],并应用sRGB->linear RGB transform。让我们试试:
Avg Spd ISO Aperture
1. 0.1140, 0.10, 100, f/2.8
2. 0.2746, 0.10, 200, f/2.8
3. 0.1175, 0.10, 200, f/4.0
4. 0.0682, 0.10, 200, f/5.0
5. 0.0424, 0.10, 200, f/5.6
6. 0.0287, 0.10, 200, f/6.3
7. 0.0213, 0.10, 200, f/7.1
8. 0.0133, 0.10, 200, f/8.0
9. 0.0092, 0.10, 200, f/9.0
我也尝试了“普通”伽马校正(gamma = 2.2),结果与sRGB校正案非常相似。
所以我非常,非常困惑。 有人可以解释相机JPEG的RGB强度如何真正被解释为,因为我没有想法:)
答案 0 :(得分:8)
所以,当我继续阅读时,这个谜团慢慢展开。
虽然相机的传感器理论上能够测量线性光强度,但它显然不会这样做,而是模仿摄影胶片的行为,这有着众所周知的非线性响应(例如,见this ,图3)。 因此,dSLR的响应曲线远不是线性的,但更像是这样:
因此,如果没有精确校准,从像素值中获取绝对场景亮度是不切实际的。
然而,我只想对照片进行亮度调整,并且对我来说有一个近似正确的亮度估计就可以了,所以我继续重建相机的传输功能(佳能350D):
白色数据点对应于各种光圈值下的不同曝光(f / 22,f / 20,f / 18,f / 16等,以1/3级为增量)。正如上图所示,X轴在输入亮度方面是对数的,而Y轴在像素值方面是线性的(在伽马校正之后)。假设图形在单位平方中,我还通过五阶多项式计算了近似拟合曲线:
(((((- 6.76219 * x) + 12.0459) * x - 5.8683) * x + 1.72338) * x - 0.148753) * x + 0.0105364;
表示[0.05,1]
中的x所以,如果你有原始(“真实”)亮度,获得像素值会像这样:
将此转换定义为 T ,我的应用程序中的整个工作流现在都是这样的: