Usted puede uso correlacionar. Tendrá que establecer sus valores de negro a -1 y sus valores de blanco a 1 (o viceversa) para que sepa el valor del pico de la correlación, y que solo ocurra con la letra correcta.
El siguiente código hace lo que creo que desea.
import numpy
from scipy import signal
# Set up the inputs
a = numpy.random.randn(100, 200)
a[a<0] = 0
a[a>0] = 255
b = numpy.random.randn(20, 20)
b[b<0] = 0
b[b>0] = 255
# put b somewhere in a
a[37:37+b.shape[0], 84:84+b.shape[1]] = b
# Now the actual solution...
# Set the black values to -1
a[a==0] = -1
b[b==0] = -1
# and the white values to 1
a[a==255] = 1
b[b==255] = 1
max_peak = numpy.prod(b.shape)
# c will contain max_peak where the overlap is perfect
c = signal.correlate(a, b, 'valid')
overlaps = numpy.where(c == max_peak)
print overlaps
Esto da salida a (array([37]), array([84]))
, las ubicaciones de las compensaciones establecidas en el código.
Usted encontrará probablemente que si el tamaño de letra multiplicado por su gran tamaño de la matriz es más grande que aproximadamente Nlog (N), donde N es el tamaño correspondiente de la gran variedad en la que usted está buscando (para cada dimensión), entonces probablemente obtendrá una velocidad usando un algoritmo basado en fft como scipy.signal.fftconvolve
(teniendo en cuenta que necesitará voltear cada eje de uno de los conjuntos de datos si está utilizando una convolución en lugar de una correlación - flipud
y fliplr
). La única modificación sería la de asignar c:
c = signal.fftconvolve(a, numpy.fliplr(numpy.flipud(b)), 'valid')
Comparando los tiempos en los tamaños más arriba:
In [5]: timeit c = signal.fftconvolve(a, numpy.fliplr(numpy.flipud(b)), 'valid')
100 loops, best of 3: 6.78 ms per loop
In [6]: timeit c = signal.correlate(a, b, 'valid')
10 loops, best of 3: 151 ms per loop
Wow, gran respuesta (incluso los tiempos)! Tengo algunas pruebas para ejecutar. – DaveO
Algo se me acaba de ocurrir, puede tener las regiones "no me importa" de su submatriz estableciendo el valor en 0. Esto significa que esos valores no tendrán ningún impacto en la correlación cruzada. El valor 'max_peak' podría ser encontrado como' max_peak = b [b! = 0] .size' (esto funcionaría independientemente de si tiene 0 valores). –
¡Así que he pasado la tarde editando mi código y lo he hecho funcionar! Digamos que se encontraron 2 ocurrencias de una forma de 2x3 en (matriz ([0, 6]), matriz ([1, 7])), lo que significa que las esquinas superiores izquierdas son [0, 1] y [6, 7]. Lo que quiero hacer es poder indexar todas las celdas de 2x3 de la forma y asignarles 0 por lo que en la siguiente forma que estamos buscando no vamos a verificar esa parte de la imagen (según su comentario anterior). ¿Cómo puedo usar el valor de retorno de correlate/fftconvolve para indexar la forma 2d sin usar loops? Tipo de una porción de lista de ubicación. – DaveO