如何去除相机预览中的滚动快门效果?

How to remove rolling shutter effect in camera preview?

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

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

CONTROL_AE_MODE CONTROL_AE_MODE_OFF

CONTROL_AWB_MODE CONTROL_AWB_MODE_OFF

EDGE_MODE EDGE_MODE_OFF

CONTROL_MODE CONTROL_MODE_关闭

SENSOR_EXPOSURE_TIME 500000

SENSOR_FRAME_DURATION 50000000

我已经试过曝光时间和帧持续时间,但没有效果。 只需打开库存相机应用程序并近距离拍摄 LED,即可观察到相同的效果。 Example

图片右半边为旧框,左半边为新框

有办法解决这个问题吗? Android 有相机垂直同步吗?

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

编辑 2:我通过执行 Canny 边缘检测然后使用 opencv 对图像进行标准霍夫线变换来使其工作。从霍夫线变换得到线坐标后,我检查了线是否水平。然后我沿着这条线分割图像,只使用较大的区域进行计算。

滚动快门效应源于这样一个事实,即带有 CMOS 图像传感器的相机通常逐行(或逐列)顺序读取像素数据,因此将构成一个图像帧的 rows/columns 分开不是在同一时间点捕获的。

没有 "camera vsync",因为滚动快门是图像传感器构建方式的物理 属性。

除了切换到全局快门图像传感器(如 CCD 或一些较新的 CMOS 传感器)之外,您还可以尝试增加相机的快门 speed/reducing 曝光时间以尽量减少问题。

您可以参考 作为如何找出相机可用快门速度的具体指导。

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

Update2: 正如评论中所讨论的,您的设置现在似乎是这样工作的。您有一个 LED,它可以每 50 毫秒改变一次状态(打开或关闭)。您有一台相机,可以在 50 毫秒的过程中捕捉一个场景以生成一幅图像。最左边的列在这 50 毫秒的开始,最右边的列在这 50 毫秒的结尾(反之亦然,您需要弄清楚)。由于 LED 的 50 ms 周期与相机的 50 ms 捕获时间不同步,因此在生成的相机图像中间可能会发生 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 的最新信息。

希望对您有所帮助。