假设我有一个图像文件/URL,并且我希望我的软件在最多 100 个图像(或至少在那个数量级)中搜索它。软件应该找到的目标图像应该是与给定图像“相同”的图像,但它仍然应该能够“原谅”对其中任何一个的轻微处理(这两个图像可能被不同地裁剪,或者它们被压缩不同)。问题是 - 这是一项可行的任务,因为在搜索之前我不会有任何图像(即,在搜索之前不会有任何索引。)它是否可能在亚秒内工作时间(请记住,比较集非常小)。如果可行,我可以使用哪些工具来完成这项任务?这可能是软件组件,甚至是在线服务(我可以接受它来证明概念)。OpenSURF帮帮我吗?为了进一步集中我的问题-我不是在问要使用哪种算法,此时我宁愿使用现有的工具/API/服务。
3 回答
软件应该找到的目标图像应该是与给定图像“相同”的图像,但它仍然应该能够“原谅”对其中任何一个的轻微处理。
如果“轻微处理”不涉及旋转,而只涉及“裁剪”,那么简单的互相关应该可以工作,如果可以进行透视校正、旋转、镜头畸变校正,那么事情就复杂多了。
我认为这种方法对轻微的颜色校正非常宽容。无论如何,如果需要,您始终可以将两个图像都转换为灰度并比较灰度版本。
为了进一步集中我的问题-我不是在问要使用哪种算法,此时我宁愿使用现有的工具/API/服务。
您可以cvMatchTemplate
从 OpenCV 库开始(链接指向 API 的 C 版本,但它也可用于 C++ 和 Python)。使用裁剪后的图像作为模板,并在所有图像中查找它。
如果您比较的图像在浅色背景上有深色特征,您可能会从使用CV_TM_CCOEFF
orCV_TM_CCOEFF_NORMED
方法中受益。它们都从两个图像中减去模板区域的平均值。归一化方法 ( CV_TM_*_NORMED
) 通常工作得更好,但比它们的非归一化对应物慢。
您可以考虑在互相关之前对图像进行一些预处理。如果您首先对它们进行归一化,则互相关对轻微的亮度/对比度修改不太敏感。如果您按照@misha 的建议首先检测边缘,您将丢失颜色/亮度信息,但轮廓重叠的结果会好得多。
jetxee 让您走上正轨。但是,如果您只是使用模板匹配,则可能会遇到背景干扰模板匹配结果的问题。例如,如果您的模板是建筑物并且您的背景主要是浅色(例如沙漠沙子),那么模板匹配将失败,因为较浅的背景总是会返回比较暗的模板更高的互相关。这是这个问题的一个例子。
您解决它的方式与链接中的相同:
- 对您的模板和目标图像执行边缘检测。
- 扔掉原始模板和图像
- 使用边缘检测模板和边缘检测目标图像执行模板检测
至于宽容轻微的处理,边缘检测步骤将照顾到这一点。只要两个图像中的边缘没有被显着修改(模糊、光学失真),该方法就可以工作。
我知道您不是专门寻找算法,但尽管如此,让我建议以下可以非常有效地完成您正在尝试做的事情......
对于同一图像的裁剪版本,包括旋转,Fourier-Mellin 变换或对数极坐标变换(注意艺术性的半裸图 - 但是很好的来源)将为您提供平移、旋转和比例系数之间的两个图像,允许确定从一个图像到另一个图像需要哪些操作。