【问题标题】:What is the most efficient way to match templates in a Numpy array?在 Numpy 数组中匹配模板的最有效方法是什么?
【发布时间】:2018-07-16 08:52:16
【问题描述】:

我有一个大小为 2000*4000 的 numpy 数组,其中包含二进制值。我有一个模板,我想与我的源数组匹配。目前我正在源数组上运行一个滑动窗口。虽然这种方法效果很好,但非常耗时。我猜本机实现会快得多。也可以匹配多次出现的模板吗?

类似

x = [[0 0 1 1 1 1 1 0 0]
     [0 0 1 1 0 0 0 0 0]
     [0 0 1 1 0 0 0 0 0]
     [0 0 1 1 0 0 0 0 0]]

template = [[1 1 1 1]
            [1 0 0 0]
            [1 0 0 0]]

cords = np.matchtemplate(x, template)

理想情况下,打印绳索应该给出一个元组列表,其中包含匹配段的对角坐标。

print(cords)

[[(0, 3), (6, 2)]]

【问题讨论】:

  • 只是一个想法:如何将您的模板作为 2D 内核运行互相关以找到候选位置(即 xtemplate 之间的良好匹配),然后只检查周围的邻域候选人职位?互相关可以非常有效地完成......

标签: python arrays numpy image-processing sliding-window


【解决方案1】:

正如@MPA 所建议的,这将提供候选人名单:

from scipy import signal

match = np.sum(template)
tst = signal.convolve2d(x, template[::-1, ::-1], mode='valid') == match
candidates = np.argwhere(tst)

这给出了 (0, 2)(0, 3) 作为您的示例。


对于二元矩阵,可以按照@Paul 的建议:

from scipy import signal

match = np.sum(template)
tst = signal.convolve2d(x, (2 * template - 1)[::-1, ::-1], mode='valid') == match
positions = np.argwhere(tst)

这为您的示例提供(0, 3)

【讨论】:

  • 你可以使用2*template - 1;这样你就会得到实际的点击而不是候选人。顺便提一句。 argwhere 直接给出坐标元组。
【解决方案2】:

使用 OpenCV 的解决方案:

import cv2

result = cv2.matchTemplate(
    x.astype(np.float32),
    template.astype(np.float32),
    cv2.TM_SQDIFF)

positions = np.argwhere(result == 0.0)

这为您的示例提供(0, 3)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-28
    • 1970-01-01
    • 2015-07-14
    • 1970-01-01
    • 1970-01-01
    • 2018-11-30
    • 1970-01-01
    • 2023-03-30
    相关资源
    最近更新 更多