如何在相机预览中消除滚动快门效果?

时间:2019-10-09 13:17:47

标签: java android android-camera

我正试图通过拍摄闪烁的LED来向手机发送数据。在大多数情况下,这都可以正常工作,但是对于某些帧,我在相机预览中会得到滚动快门效果,这会扰乱我的数据传输。有没有办法消除这种卷帘效果?

我正在使用Google的cameraAPI2和Nexus 6(但在三星S7上看到了相同的效果)。我以20 fps录制,并且LED以20 Hz的频率闪烁。我的图片使用YUV_420_888的格式为320x240。 这是我当前对CaptureRequest的设置:

CONTROL_AE_MODE CONTROL_AE_MODE_OFF

CONTROL_AWB_MODE CONTROL_AWB_MODE_OFF

EDGE_MODE EDGE_MODE_OFF

CONTROL_MODE CONTROL_MODE_OFF

SENSOR_EXPOSURE_TIME 500000

SENSOR_FRAME_DURATION 50000000

我已经尝试过将曝光时间和帧长设置为无效。 只需打开股票相机应用程序并关闭LED灯,即可观察到相同的效果。 Example

图片的右半部分显示旧框架,左半部分显示新框架。

是否可以解决此问题? Android是否有摄像头垂直同步?

编辑:我将频率更改为20Hz。

编辑2 :我通过使用opencv在图像上执行Canny Edge Detection,然后执行标准Hough Line Transformation使其工作。从霍夫线变换获得线坐标后,我检查了线是否水平。然后,我沿着这条线分割图像,仅将较大的区域用于计算。

1 个答案:

答案 0 :(得分:1)

滚动快门效果源于以下事实:具有CMOS图像传感器的相机最经常逐行(逐行(或逐列))顺序读取像素数据,因此无法捕获构成一个图像帧的单独行/列在同一时间点。

由于卷帘快门是图像传感器的物理特性,因此没有“相机垂直同步”。

除了切换到全局快门图像传感器(例如CCD或某些较新的CMOS传感器)之外,您还可以尝试提高快门速度/减少相机的曝光时间,以最大程度地减少问题。

您可以参考this question作为具体方向,以了解如何找到相机可用的快门速度。

更新:您可以尝试将相机的快门速度设置为最快设置,然后将LED闪烁频率与相机帧频(1 / 30s)相匹配。这样,LED的闪烁应该始终在图像采集的同一时间点,并且滚动快门效果也不会出现任何问题。

Update2:,如评论中所述,您的设置现在似乎可以这样工作。您有一个LED,可以每50毫秒更改其状态(亮或灭)。您有一台摄像机可以捕获50毫秒内的场景以生成一张图像。最左边的列在这50毫秒的开始处,最右边的列在这50毫秒的结尾处(反之亦然,您需要弄清楚这一点)。由于LED的50毫秒周期与摄像机的50毫秒捕获时间不同步,因此LED的状态变化很可能会在所生成的摄像机图像的中间发生,这会将图像在黑暗中分开并明亮的一半。

这是图像上随机LED序列的样子:

LED sequence:   ... 0  |  1  |  1  |  0  |  1  |  0  |  0  |  0 ...

Image sequence: ... | 0 1 | 1 1 | 1 0 | 0 1 | 1 0 | 0 0 | 0 0 | ...

管道表示LED何时可以更改状态以及图像何时完成一帧捕获。

您可以在图中看到,假设频率相同,则旧状态和新状态之间的图像划分总是保持在同一图像列。您所要做的就是检测行将图像划分的位置(应该可以在计算机视觉上实现),然后仅始终查看图像的一半以查看该一半是否发生了变化。理想情况下,您应该查看稍后记录的一半,因为那一半可以为您提供来自LED的最新信息。

我希望有帮助。