我正在做一个玩具项目,涉及处理一堆使用间隔计拍摄的照片图像。基本上,我想将它们制作成时间流逝视频,并进行一些修正,使得剪辑更整洁。我使用佳能数码单反相机。
我需要一个函数,可以给定一个JPEG文件,找出“平均场景亮度”。结果应该是一个简单的数字;不需要用任何绝对光度单位来表达,我只做相对比较。因此,例如,你拍了一张房间的照片,函数返回“5.0”。然后你在灯光旁边加了第二个完全相同类型的灯泡,再次拍摄。现在该函数应该给你“10.0”。
因此,我目前的这个函数实现结合了几个方面:ISO速度、快门速度、光圈(从EXIF中提取)和平均图像亮度。显然,Exif信息更重要,因为在自动模式下,相机会尝试使用这样那样的设置,所以图像亮度围绕中灰点左右。 然而,ISO/快门/光圈设置的分辨率都不到1/3档,因此检测图像亮度对于“微调”非常重要。
当我进行此操作时,我得到了一些明显错误的结果,我挖掘得越深,就越感到困惑。因此最终我设置了一个“几乎严肃”的实验:
测试设置: 一个房间里的简单墙壁,使用白炽灯照明,光线比较均匀。 使用两台相机进行比较:50毫米定焦镜头的5D和35毫米定焦镜头的350D。 离墙距离:约3米。 所有照片都以1/10秒快门速度拍摄。 相机设置:手动,“忠实模式”(无增强、无饱和度或对比度提升),钨丝白平衡,无自定义功能,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..1]范围内进行归一化,通过将[0..255]范围除以255来实现。因此,在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
我还尝试了“普通”的伽马校正(伽马=2.2),结果与sRGB校正情况非常相似。
所以我非常困惑。 有人能解释一下从相机JPEG中提取的RGB强度应该如何真正解释吗?因为我已经没有任何想法了 :)