关于python:使用scikit-image搜索所有模板

Search for all templates using scikit-image

我正在尝试遵循SciKit Image关于模板匹配的教程(请在此处检查)。Themplate matching

仅使用这个例子,我想在图片中找到所有匹配的硬币(马克西玛),而不仅仅是这一个得分最高的硬币。我在考虑使用:

1
maxima = argrelextrema(result, np.greater)

但问题是它也发现了非常小的局部极大值,这只是一个噪音。有没有任何方法来筛选numpy数组并找到最强的maxima?谢谢!


为了找到所有的硬币,文件建议"…你应该使用一个合适的寻峰功能。"最简单的可能是peak_local_max(如注释所示),它也来自skimage,这里有一个手册页。在*参数中使用一些合理的数字可以得到响应图像中的峰值。

文件中还讨论了关于位移峰值的第二条评论。

"请注意,match_模板输出中的峰值对应于模板的原点(即左上角)。"

您可以手动更正(通过模板边长转换峰值),也可以将pad_inputbool设置为True源,作为副产品,这意味着响应函数中的峰值在最大重叠点与模板的中心对齐。

将这两个位组合成一个脚本,我们得到如下结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import numpy as np
import matplotlib.pyplot as plt

from skimage import data
from skimage.feature import match_template
from skimage.feature import peak_local_max # new import!

image = data.coins()
coin = image[170:220, 75:130]

result = match_template(image, coin,pad_input=True) #added the pad_input bool

peaks = peak_local_max(result,min_distance=10,threshold_rel=0.5) # find our peaks

# produce a plot equivalent to the one in the docs
plt.imshow(result)
# highlight matched regions (plural)
plt.plot(peaks[:,1], peaks[:,0], 'o', markeredgecolor='r', markerfacecolor='none', markersize=10)

氧化镁


我一直在挖掘并找到一些解决方案,但不幸的是,我不确定我是否知道脚本中到底做了什么。我对这里的脚本做了一些修改:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
neighborhood_size = 20   #how many pixels
threshold = 0.01  #threshold of maxima?

data_max = filters.maximum_filter(result, neighborhood_size)
maxima = (result == data_max)
data_min = filters.minimum_filter(result, neighborhood_size)
diff = ((data_max - data_min) > threshold)
maxima[diff == 0] = 0

x_image,y_image = [], []
temp_size = coin.shape[0]

labeled, num_objects = ndimage.label(maxima)
slices = ndimage.find_objects(labeled)
x, y = [], []
for dy,dx in slices:
    x_center = (dx.start + dx.stop - 1)/2
    x.append(x_center)
    y_center = (dy.start + dy.stop - 1)/2
    y.append(y_center)

fig, (raw,found) = plt.subplots(1,2)
raw.imshow(image,cmap=plt.cm.gray)
raw.set_axis_off()
found.imshow(result)
found.autoscale(False)
found.set_axis_off()
plt.plot(x,y, 'ro')
plt.show()

这样做:Found all maxima

我还意识到,与原始图像相比,发现的峰的坐标发生了偏移。我认为差异来自模板大小。我会在发现更多信息时更新。

编辑:通过轻微的代码修改,我还可以在输入图像上找到位置:

1
2
3
4
x_image_center = (dx.start + dx.stop - 1 + temp_size) / 2
x_image.append(x_image_center)
y_image_center = (dy.start + dy.stop - 1 + temp_size) / 2
y_image.append(y_image_center)

氧化镁