忽略亮度的图像比较算法

11

我正在寻找一种算法,可以用来比较两个图像并确定它们之间是否存在显著差异。所谓“显著”,是指如果你拍摄了一个房间的两张照片,其中一张墙上有一只大蜘蛛,你应该能够检测到它。我对被检测到的内容或者位置不感兴趣,我只需要知道有些东西不同。该算法需要忽略亮度。如果房间在白天变得更明亮或更暗,算法应该忽略这种情况。

即使您不知道这样的算法,任何指向正确方向的提示都会有所帮助。

谢谢!


照片是从完全相同的视角拍摄的吗?你是在尝试制作安全摄像头软件吗? - Will
1
随着时间变化形状发生变化的阴影怎么样?你不能把它们归咎于亮度。 - Alexey Frunze
是的,这些照片都是从完全相同的位置拍摄的。相机从未移动过。这是为了一个安全应用程序。如果阴影非常强烈以至于改变了形状,那么也应该被检测到。 - Johann
你需要在使用案例上做到顶尖水平。一只蜘蛛可以移动得非常缓慢,如果设计不当,蜘蛛可能会从屏幕的一侧移动到另一侧,同时对你的摄像头来说是看不见的。 - UmNyobe
如果爬虫在图像捕获之间出现,它们就会被抓住。如果它们可以跑过捕获速率,那就没问题了。我不是要抓超人。 - Johann
@AndroidDev 注意,你接受的答案并没有真正展示如何有效地比较两个不同的图像。我以为你想要这个? - mmgp
4个回答

4
我会尝试对你的二维数据进行高通滤波。
根据傅里叶,可以通过分析信号中包含的频率,将每个信号转换为“频率空间”。这也适用于二维信号,如图像。
通过“高通滤波器”,您可以去除所有低频部分,例如常量偏移和缓慢的梯度。如果应用于图像,则可作为简单的“边缘检测”算法。查看示例可能会更容易理解:

High-pass filtering of images

我从网上获取了一张墙上蜘蛛的图片(左上角)。然后我降低了这张图片的亮度(左下角)。对于两个版本,我都使用 GIMP (此插件) 应用了高通滤波器。对于两个输入图像,输出看起来非常相似。

我的建议:先应用高通滤波器,然后查看差异。

可能出现的问题

按照要求,以下是我能想象到的一些问题。

  • 没有清晰的边缘:如果您想检测的对象没有清晰的边缘,那么您可能会使用高通滤波器将其过滤掉。但那些对象可能是什么?它们必须是巨大的、平坦的(不产生阴影)和无结构的。

  • 只有颜色不同,亮度相同:如果对象只在颜色方面有所不同,但亮度与背景相同,则灰度转换可能会成为一个问题。但如果您遇到这个问题,只需分别分析 R、G、B 数据,然后至少一个通道应该有助于检测对象,否则,您就看不到它了。

编辑 作为对于???的回复,如果你也调整了高通滤波后的图像级别(当然全都是0.5*256),只要将其标准化到0, 256的范围内,你就会得到

With adjusted levels

也许这并不比你的结果更糟。但是,HP滤波器很简单,并且在使用FFT时非常快速。

妙用FFT!非常棒的方法!我还会提高对比度以获得更好的分离效果,并且甚至在白天拍照片,然后用它来规范未来照片的亮度。计算交叉相关也可以帮助量化两张照片之间的差异程度,如果不想通过视觉比较它们的话。 - Fredrik
我对一些事情感到有点困惑。高通滤波器会导致彩色图像转换为灰度图像吗?还是我必须先创建一个灰度图像,然后将其通过高通滤波器传递?我不确定该在Google上搜索哪种用于图像的高通滤波器。我知道它们用于音频。您能建议我应该寻找哪些高通成像滤波算法吗?我需要编写代码,因此插件是无用的。 - Johann
傅里叶并没有以任何方式创建高通滤波器,但他阐述了任何波形都可以由不同频率的正弦和余弦波之和构成的公式。此外,并未明确使用哪种高通滤波器,但如果像Sobel这样简单的过滤器,则使用FFT很可能不会提供任何速度提升。 FFT在有较大滤波器时非常有用,因为在频域中卷积是两个傅里叶变换之间的逐点乘法。最后,亮度没有被忽略,因为此答案使用RGB颜色空间。 - mmgp
傅里叶从未以任何方式创建高通滤波器 - 谁声称过?我只是使用了傅里叶的想法来介绍高通滤波器的概念。特别是对于图像,我看到许多同事对“图像中存在频率”感到惊讶。我也从未提到过FFT,这只是一种过滤的方法之一。最后:是的,亮度被忽略了。每个高通滤波器做的第一件事情是(简化):减去平均信号,因此只有与平均值的偏差保留下来。因此,“基线”亮度被忽略了。 - Thorsten Kranz
你曾经真正使用过频率滤波器吗?你曾经比较过经过滤波和未经滤波的信号吗? - Thorsten Kranz
显示剩余8条评论

0

把像素的亮度成分去掉怎么样:

Red_ratio = Red / (Red + Blue + Green)
Blue_ratio = Blue / (Red + Blue + Green)
Green_ratio = Green / (Red + Blue + Green)

0
如果相机完全静止,所有差异都是由环境光线和/或相机曝光设置引起的,那么通过归一化2个图像来忽略亮度(和对比度)是可行的。
从每个图像的所有像素中减去各自的图像平均值(平均像素值),然后取差值。这将处理亮度。
如果你想处理对比度,计算每个图像的方差(在将平均值调整为0之后),并将像素值乘以可以使它们达到相同方差的因子。现在,差异也将不受对比度的影响了(假设没有过度/欠曝光区域)。

这是我已经尝试过的方法。但是,我将RGB作为单个值(例如0xaabbcc)并基于减去这些值来归一化图像。结果发现,当颜色相距较远时,方差非常不一致。我认为我需要添加RGB值并使用它代替。我没有理解您最后一段关于如何考虑对比度的内容。您能否提供一个4x4像素图像的简单示例?谢谢! - Johann

0
一个常见的方法是对相机拍摄的图像进行时间平均,并检测任何超过给定阈值的差异。
需要将一个图像保留在内存中,这将是平均图像。我们称之为“avg”。
每次相机拍照(称为“pic”)时,您需要:
- 对“avg”和“pic”的绝对像素值差异进行求和。 - 如果超过阈值,则表示有物体在相机前移动。 - 否则,修改“avg”,使它稍微收敛到“pic”。您需要找到适当的公式,例如 `avg = avg * 0.95 + pic * 0.05`。
在这里,您的参考图像会因为阳光和阴影的变化而随着一天的时间而改变。

这种方法的问题在于,当你开始依赖平均值时,即使图片中有一个小但有效的对象不应该出现在那里,它对整体价值的影响也可能很小或没有影响,因为图像的其他部分可能会因阳光(或阴影)而改变,并抵消无效对象的存在。即使阳光只有轻微的影响,当平均时也会累加。我认为有必要考虑每个像素的亮度,或者像Thorsten Kranz建议的那样,完全去除亮度。 - Johann
@AndroidDev 嗯,如果您不随时间修改参考图像,则阴影将创建“移动边缘”并被检测为“移动对象”。换句话说,您需要一些方法来检测快速移动的物体并忽略慢速移动的物体。 - Nicolas Repiquet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接