查找较小数组最匹配较大数组的位置

Find location where smaller array matches larger array the most

我需要找到一个较小的二维数组 array1 与另一个二维数组 array2 中最接近的位置。

我只能访问 numpy。

我目前正在尝试使用 Tversky formula 但未绑定它。

效率是最重要的部分,因为这会 运行 很多次。下面显示的我当前的解决方案非常慢。

for i in range(array2.shape[0] - grid_size):
    for j in range(array2.shape[1] - grid_size):
        r[i, j] = np.sum(array2[i:i+grid_size, j:j+grid_size] == array1 ) / (np.sum(array2[i:i+grid_size, j:j+grid_size] != array1 ) + np.sum(Si[i:i+grid_size, j:j+grid_size] == array1 ))

编辑: 目标是找到较小图像与另一图像匹配的位置。

这是一种基于 FFT/convolution 的最小化欧氏距离的方法:

import numpy as np
from numpy import fft

N = 184
n = 46
pad = 192

def best_offs(A,a):
    A,a = A.astype(float),a.astype(float)
    Ap,ap = (np.zeros((pad,pad)) for _ in "Aa")
    Ap[:N,:N] = A
    ap[:n,:n] = a
    sim = fft.irfft2(fft.rfft2(ap).conj()*fft.rfft2(Ap))[:N-n+1,:N-n+1]
    Ap[:N,:N] = A*A
    ap[:n,:n] = 1
    ref = fft.irfft2(fft.rfft2(ap).conj()*fft.rfft2(Ap))[:N-n+1,:N-n+1]
    return np.unravel_index((ref-2*sim).argmin(),sim.shape)

# example
# random picture
A = np.random.randint(0,256,(N,N),dtype=np.uint8)
# random offset
offy,offx = np.random.randint(0,N-n+1,2)
# sub pic at random offset
# randomly flip half of the least significant 75% of all bits
a = A[offy:offy+n,offx:offx+n] ^ np.random.randint(0,64,(n,n))

# reconstruct offset
oyrec,oxrec = best_offs(A,a)
assert offy==oyrec and offx==oxrec

# speed?
from timeit import timeit
print(timeit(lambda:best_offs(A,a),number=100)*10,"ms")

# example with zero a
a[...] = 0
# make A smaller in a matching subsquare
A[offy:offy+n,offx:offx+n]>>=1

# reconstruct offset
oyrec,oxrec = best_offs(A,a)
assert offy==oyrec and offx==oxrec

样本运行:

3.458537160186097 ms