特征检测 - 大图片中的小项目

时间:2012-07-23 09:20:58

标签: opencv computer-vision

假设您有两张图片。在一个你有一个小图标(像小于300X300像素)。第二个是一个非常大的,在你内部有一个(或多个)较小的图标实例(当然在不同的规模,旋转)。

手头的任务是在大图像中找到图标的实例。你们怎么接近这个?

我试图通过使用OpenCV库来使用基于特征的对象检测,但是对于拥挤的大图像(包含许多特征点),匹配是不确定的。我尝试过使用BRUTE / FLAN匹配算法的SURF / OBJ特征提取器。

根据我的经验,匹配似乎没有注意到两个图像上的特征点之间的几何关系。作为可视化帮助,我附加了两个示例图像的特征点的实例。 enter image description here

这是一个更难的任务实例。我突出了大图中的图标。 enter image description here

2 个答案:

答案 0 :(得分:6)

基于有限的经验,对于遇到此类问题的其他人,我有三条建议。

1)使用FindObject by Mathieu Labbé

进行试验

这是一个非常好的工具,它帮助我快速进行实验,找到特征检测/描述的良好设置组合。只需将图标作为对象加载,然后将样本大图像作为场景加载。然后调整,直到您的应用程序获得可靠的结果。作为奖励,他最近添加了BRISK和FREAK非专利保护功能检测/描述方法。

2)获得逼真的分辨率

您正在搜索的大型场景中的图标对象和实际图标的分辨率是如此不同。根据我的理解,这些方法的尺度不变性实际上非常有限。看看优秀的comparisons done by Ievgen Khvedchenia。通过将图像调整到您期望的范围的中间位置,可以获得更好的结果。

3)使图标样本图像更逼真(例如,模糊)

与#2相关,我发现在更逼真的场景中搜索时样本图像非常清晰并不能很好地工作。我将高斯应用于我的锐利样本,使它们与我期望找到的更相似。下面有一个例子。奇怪的公式只是确保内核维度是所需的奇数。

def proportional_gaussian(image):
    kernel_proportion = 0.005
    kernel_w = int(2.0 * round((image.shape[1]*kernel_proportion +1)/2.0)-1)
    kernel_h = int(2.0 * round((image.shape[0]kernel_proportion +1)/2.0)-1)
    return cv2.GaussianBlur(image, (kernel_w, kernel_h), 0)

希望能有所帮助。

答案 1 :(得分:2)

您的功能匹配方法很好。如果可以使用颜色,请使用预处理来查找感兴趣的区域,例如histogram backprojection,然后进行斑点提取和一些形状分析。

您应该匹配从大图像到小图像的所有要素。这导致许多匹配,内部很少。

由于您的图标是平面图标,因此您可以将单应性作为匹配的几何约束。 无需编写任何代码,您可以尝试使用OpenCV示例“descriptor_extractor_matcher”,该示例可以在OpenCV源的samples目录中找到。

./descriptor_extractor_matcher SURF SURF BruteForce NoneFilter icon.jpg image.jpg 3

有关详细信息,请参阅descriptor_extractor_matcher的帮助输出。

您可能会尝试切换图像的顺序,我不记得哪一个是训练图像,哪一个是查询图像。

关于此类物体检测的论文是David Lowe的“尺度不变关键点的独特图像特征”。在本文的第7.3节中,他描述了他处理非常低的内部/异常值比率的方法,这似乎是你的情况。

祝你好运!