使用自定义内核/图像过滤器在二维数组中查找特定模式

问题描述

给出图片im

>>> np.random.seed(0)
>>> im = np.random.randint(0,100,(10,5))
>>> im
array([[44,47,64,67,67],[ 9,83,21,36,87],[70,88,12,58],[65,39,87,46,88],[81,37,25,77,72],20,80,69,79],[47,82,99,[49,29,19,14],[39,32,65,9,57],[32,31,74,23,35]])

例如,找到此图像特定片段的最佳方法是什么

>>> im[6:9,2:5]
array([[82,[19,57]])

如果不存在特定的组合(可能是由于噪声),我希望有一个相似性度量,该度量搜索具有相似分布的线段,并告诉我im的每个像素,同意是。例如类似

array([[0.03726647,0.14738364,0.04331007,0.02704363,0.0648282 ],[0.02993497,0.04446428,0.0772978,0.1805197,0.08999   ],[0.12261269,0.18046972,0.01985607,0.19396181,0.13062801],[0.03418192,0.07163043,0.15013723,0.12156613,0.06500945],[0.00768509,0.12685481,0.19178985,0.13055806,0.12701177],[0.19905991,0.11637007,0.08287372,0.0949395,0.12470202],[0.06760152,0.13495046,0.06344035,0.1556691,0.18991421],[0.13250537,0.00271433,0.12456922,0.97,0.194389  ],[0.17563869,0.10192488,0.01114294,0.09023184,0.00399753],[0.08834218,0.19591735,0.07188889,0.09617871,0.13773224]])

示例代码是python。 我认为应该有一个将内核与im相关联的解决方案。但是,这将带来一个问题,即具有相同值但已缩放的线段将给出更清晰的响应。

解决方法

模板匹配将是解决该问题的方法之一。当然,深度学习/ ML也可以用于更复杂的匹配。

大多数图像处理库都支持某种匹配功能,该功能可以比较一组2张图像-参考图像和要匹配的图像。在OpenCV中,它返回一个可用于确定匹配项的分数。匹配方法使用支持缩放和/或旋转不变匹配的各种功能。当心您计划使用的方法中的许可限制。

如果图像可能并不总是准确的,则可以使用标准偏差(StdDev)允许允许的偏差,然后将其分类为存储桶。根据要匹配图像的条件,也可以使用直方图匹配(除非使用特定通道,否则照明,颜色可能很重要)。使用直方图会避免整体匹配模板。

参考以进行模板匹配:

,

感谢banerjk的出色回答-template matching就是解决方案!

一些备份方法

考虑到我与内核相关的想法,有一些进展: 当人们将图像与模板相关联时(即我在问题中称为目标片段),机会很大,即相关图像中最强的点(相对于平均强度)与模板位置相匹配(请参见{{1} }和im)。好像我不是第一个提出这个想法的人,可以从第39页的lecture notes中看到。

但是,并非总是如此。此方法或多或少仅检测模板中最大值处的重量。在此示例中,m的构造使得它欺骗了这个概念。

如果事先在图像上应用一些过滤器(例如中值),可能会变得更加可靠。

我只想在这里提及它,因为它在某些情况下可能具有优势(与Wikipedia的template_matching实现相比,它应具有更高的性能)。

示例

im2

输出

import numpy as np
from scipy import ndimage

np.random.seed(0)
im = np.random.randint(0,100,(10,5))
t = im[6:9,2:5]
print('t',t,sep='\n')

m = ndimage.correlate(im,t) / ndimage.correlate(im,np.ones(t.shape))
m /= np.amax(m)

print('im',im,sep='\n')
print('m',m,sep='\n')

print("this can be 'tricked',however")

im2 = im.copy()
im2[6:9,:3] = 0
im2[6,1] = 1

m2 = ndimage.correlate(im2,t) / ndimage.correlate(im2,np.ones(t.shape))
m2 /= np.amax(m2)

print('im2',im2,sep='\n')
print('m2',m2,sep='\n')

也许有人可以在讲义的背景上做出贡献。

更新:在第一页的J. P. Lewis,“Fast Normalized Cross-Correlation”,Industrial Light and Magic.中进行了讨论。