安卓相机2:如何实现半自动快门速度优先模式



目标

  • 使用连接到移动车辆上的Android智能手机拍摄图像
  • 频率:1 Hz
  • 参考型号:谷歌像素3a
  • 感兴趣的物体:车辆前方的道路
  • 图片用途:作为机器学习(如RNN)的输入,以识别道路/道路表面的损坏
  • 捕获环境:室外,仅在阴天

当前状态

  • 捕获作品(由于数据大小的原因,目前使用JPEG而不是RAW)
  • 自动曝光作品
  • 静态焦距作品

挑战

  • 图片中的道路表面往往很模糊
  • 运动模糊的来源主要来自抖动的车辆/固定电话
  • 为了减少运动模糊,我们希望使用"快门速度优先模式">
    • 即最小化快门速度=>增加ISO(接受增加噪声)
    • 只有一个光圈(f/1.8)可用
    • Camera2 API中没有"快门速度优先模式"(简称:Tv/S模式)
    • CameraX API(尚未)提供我们所需的功能(静态聚焦、Tv/S模式)

步骤

  • 将快门速度设置为支持的最快曝光(轻松)
  • 自动调整自动曝光的ISO设置(例如,此公式)
  • 要计算ISO,唯一缺少的部分是光照水平(EV)

问题

  • 在使用固定快门速度的情况下,如何在拍摄过程中连续估计EV以自动调整ISO

迄今为止的想法:

  1. 如果我可以在不实际启用AE_MODE_ON的情况下从Camera2自动曝光(AE)例程中读取"建议",那么我可以很容易地计算EV。然而,到目前为止,我还没有为此找到API。我想如果不路由设备,这是不可能的
  2. 如果环境光传感器将提供自动曝光(计算EV)所需的所有信息,这也将非常容易。然而,据我所知,它只测量入射光,而不是反射光,因此测量没有考虑照片中的实际物体(它们的表面如何反射光)
  3. 如果我能从最后一次拍摄的像素中获得信息,这也是可行的(如果计算时间适合两次拍摄之间的时间)。然而,根据我的理解,像素的"大"在很大程度上取决于捕捉到的物体,即如果捕捉到的对象的亮度发生变化(路边有许多"黑马"或"白熊"),我会计算出糟糕的EV值
  4. 在实际捕获之间捕获自动曝光的图像,并根据在实际捕获的中间捕获中使用的自动选择设置计算光照级别。根据我的理解,这将是一种相对"好"的方式,但在资源方面相当困难——我不确定两次捕获之间的可用时间是否足够

也许我看不到更简单的解决方案。有人做过这样的事吗?

是的,您需要实现自己的自动曝光算法。所有"真正的"AE都要经过传感器捕捉到的图像,所以理论上你可以构建出同样擅长猜测正确光线水平的东西。

在实践中,你不太可能匹配它,这既是因为你有一个更长的反馈回路(AE算法可以在同步要求上欺骗一点,并比应用程序更快地更新传感器设置),也是因为AE算法可以使用硬件统计单位(收集整个场景的直方图和平均值),这使它更高效。

但一个简单的自动曝光算法是对整个场景(或场景的一部分,或场景的每十个像素,等等)进行平均,如果平均值低于半个最大值,则增加ISO,如果高于,则减少ISO。换句话说,一个基本的反馈控制回路。所有关于稳定性、收敛性等问题都适用。因此,对控制理论的一些理解在这里会很有帮助。我建议从相机向ImageReader输出低分辨率YUV(可能是640x480?),用作源数据,然后只看Y通道。在这种情况下,没有太多的数据可以篡改。

或者,正如hb0所提到的,如果你的户外条件非常有限,你可以尝试对每个条件的值进行硬编码。但室外亮度的范围可能相当大,因此这需要进行一些适当的测试以确保它能工作,再加上每次手动选择正确的值。

当图片仅在特定光线情况下拍摄时,如"室外多云":

表格值可以用于曝光值(EV),而不是使用光测量。

示例

  • 室外多云(OC)的EV100(iso100)=13
  • OC的EV(动态iso)=EV100+log2(iso/100)

使用这个公式和那些公式,我们可以从计算iso

  • 光圈(固定)
  • 快门速度(手动选择)

此外,我们可以添加一个UI选项来选择"轻度情况",如:

  • 室外,多云
  • 室外,阳光充足
  • 等等

这可能不是最准确的方法,但目前这是继续原型设计的第一种简单方法。

最新更新