使用OpenCV过滤波动的灯光

时间:2016-06-28 12:57:51

标签: c++ opencv vision

我需要使用OpenCV在网络摄像头镜头中进行相当敏感的颜色(亮度)测量。我遇到的问题是环境光波动,这使得很难得到准确的结果。我正在寻找一种方法来不断更新视频的连续帧,以消除全局光照差异。我尝试过滤掉的灯光变化会在大部分或全部图像中全局发生。我试图计算差异并减去它,但运气不佳。有没有人对如何处理这个问题有任何建议?

编辑: 下面的2张图片来自同一视频,颜色稍有放大。如果你在它们之间交替,你会发现光线有轻微变化,可能是由于云层向外移动。问题是这些变化掩盖了我可能想要检测的任何其他颜色变化。

所以我想过滤掉这些特殊的变化。鉴于我只需要捕获的部分帧,我认为应该可以过滤掉其他镜头中发生的灯光变化。在我感兴趣的领域之外。

我尝试使用dft捕捉变化中的主导频率,以简单地忽略光照的变化。但我对该功能的使用还不够熟悉。我一直只使用opencv一周,所以我还在学习。

enter image description here enter image description here

3 个答案:

答案 0 :(得分:5)

简答:对整个照明进行时间低通滤波

从概念上考虑照明作为表示像被照射到场景上的光通量之类的值的时间序列。你理想的情况是这个函数是恒定的,但第二好的情况是它变化尽可能慢。 low-pass filter更改的功能可以快速变化,变化速度变慢。基本步骤如下:(1)计算总照度函数(2)使用低通滤波器计算新的照明函数(3)将原始图像序列标准化为新的照度值。

(1)计算照明函数的最简单方法是将图像中每个像素的所有亮度值相加。在简单的情况下,这甚至可能有效;你可能会从我的语气中猜出有很多警告。

一个重要的问题是,您更喜欢将照明值添加到某些色彩空间(例如HSV)中,而不是添加一些物理光照度。从色彩空间回到房间中的实际光线需要图像中不存在的数据,例如图像中每个表面的光谱反射率,因此不太可能。作为此代理,您只能使用图像的一部分,即具有一致反射率的图像。在样本图像中,可以使用图像顶部的桌面。选择几何区域并从中计算总照明数。

与此相关,如果您的图像区域中的相机已经饱和,则您丢失了大量信息,并且总照度值不会与物理照明很好地相关。简单地删除任何这样的区域(但是在所有帧中一致地进行)。

(2)计算照明功能的低通滤波器。这些变换是每个信号处理包的基本部分。我不太了解OpenCV是否知道它是否具有适当的功能,因此您可能需要另一个库。有许多不同类型的低通滤波器,但它们都应该给你类似的结果。

(3)一旦你有一个低通时间序列,你想用它作为总照明的归一化函数。计算低通系列的平均值并除以它,得到平均值为1的时间序列。现在通过将图像中的照度乘以归一化因子来变换每个图像。关于理想地在物理照明空间而不是颜色空间中工作的所有警告都适用。

答案 1 :(得分:2)

如果信号变化是全局的,您应该尝试在视频中的时间t计算每个图像中每条线i的平均值m(i,t)。没有波动的光比率m(i,t)/ m(i,t + 1)必须始终为1。如果存在全局变化,则每个i m(i,t)/ m(i,t + 1)必须是常数。最好使用平均值m(i,t)/ m(i,t + 1)(对于所有i)。该平均值可用于在时间t校正您的图像。

你可以使用像m(i,0)/ m(i,t)这样的比例在0时刻成为参考 您可以使用列或圆盘矩形代替行;

答案 2 :(得分:1)

我认为您可以将homomorphic filtering应用于每个帧以计算帧的反射率分量。然后,您可以跟踪选定点的变化反射率。

根据图像形成的照度 - 反射率模型,给定位置处的像素值是照度和反射率的乘积:f(x,y) = i(x,y) . r(x,y)。照明i往往在整个图像(或在您的情况下,框架)中缓慢变化,反射率r往往会快速变化。

使用同态滤波,您可以滤除照明组件。它取上述等式的对数,因此ln照明和反射分量成为加法:ln(f(x,y)) = ln(i(x,y)) + ln(r(x,y))。现在,您应用高通滤波器来保留反射分量(因此滤除了缓慢变化的照明分量)。请查看herehere,了解有关该过程的详细说明。

应用滤镜后,您将获得估算的反射帧r^(x,y,t)