这不是最好的解决方案,但这是一个解决方案。我想学习更好的技术:
如果不打算旋转或缩放它们,则可以使用图像的简单互相关。无论大图像中的小图像出现在哪里,都会出现一个明亮的峰值。
您可以使用FFT方法来加快互相关,但是如果您只是将小源图像与大目标图像进行匹配,则蛮力乘加法有时(通常不是)更快。
资源:
目标:
互相关:
这两个亮点是匹配的位置。
但是示例图像中确实有一个轮换参数,因此它本身无法工作。如果仅允许旋转而不进行缩放,则仍然可以使用互相关,但是您需要进行互相关,旋转源,将其与整个目标图像进行互相关,再次进行旋转等。所有旋转。
请注意,这不一定会找到图像。如果源图像是随机噪声,而目标图像是随机噪声,则除非以正确的角度进行搜索,否则您将找不到它。在正常情况下,它可能会找到它,但是它取决于图像属性和搜索角度。
此页面显示了如何完成此操作的示例,但未提供算法。
总和高于某个阈值的任何偏移量都是匹配项。您可以通过将源图像与其自身相关联并将所有总和除以该数字来计算匹配的优劣。完美匹配将是1.0。
但是,这在计算上将非常繁琐,并且可能有更好的方法来匹配点的模式(我想知道)。
使用灰度和FFT方法的快速Python示例:
from __future__ import division
from pylab import *
import Image
import ImageOps
source_file = 'dots source.png'
target_file = 'dots target.png'
# Load file as grayscale with white dots
target = asarray(ImageOps.invert(Image.open(target_file).convert('L')))
close('all')
figure()
imshow(target)
gray()
show()
source_Image = ImageOps.invert(Image.open(source_file).convert('L'))
for angle in (0, 180):
source = asarray(source_Image.rotate(angle, expand = True))
best_match = max(fftconvolve(source[::-1,::-1], source).flat)
# Cross-correlation using FFT
d = fftconvolve(source[::-1,::-1], target, mode='same')
figure()
imshow(source)
# This only finds a single peak. Use something that finds multiple peaks instead:
peak_x, peak_y = unravel_index(argmax(d),shape(d))
figure()
plot(peak_y, peak_x,'ro')
imshow(d)
# Keep track of all these matches:
print angle, peak_x, peak_y, d[peak_x,peak_y] / best_match
1色位图
但是,对于1色位图,这会快得多。互相关变为:
- 将源图像放在目标图像上
- 将源图像移动1个像素
- ...
将灰度图像阈值化为二进制,然后执行此操作可能就足够了。
点云
如果源和目标都是点模式,则一种更快的方法是找到每个点的中心(与已知点互相关一次,然后找到峰)并将它们存储为一组点,然后匹配源通过旋转,平移并找到两组最接近点之间的最小平方误差来确定目标。