È possibile utilizzare correlato. Dovrai impostare i valori neri su -1 e i valori bianchi su 1 (o viceversa) in modo da conoscere il valore del picco della correlazione e che si verifichi solo con la lettera corretta.
Il seguente codice fa ciò che penso si desideri.
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
Emette (array([37]), array([84]))
, le posizioni dei offset impostati nel codice.
È probabile che se la dimensione della lettera moltiplicata per la dimensione del grande array è più grande di circa Nlog (N), dove N è la dimensione corrispondente del grande array in cui stai cercando (per ogni dimensione), quindi probabilmente aumenterai la velocità usando un algoritmo basato su fft come scipy.signal.fftconvolve
(tenendo presente che dovrai girare ogni asse di uno dei set di dati se stai usando una convoluzione piuttosto che una correlazione - flipud
e fliplr
). L'unica modifica sarebbe quella di c assegnazione:
c = signal.fftconvolve(a, numpy.fliplr(numpy.flipud(b)), 'valid')
Confrontando i tempi delle dimensioni di cui sopra:
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
fonte
2012-06-18 08:54:16
Wow, grande risposta (timing ancora)! Ho alcuni test da eseguire. – DaveO
Qualcosa mi è appena venuto in mente, puoi avere delle regioni "non importa" del tuo submatrix impostando il valore su 0. Ciò significa che quei valori non avranno alcun impatto sulla correlazione incrociata. Il valore 'max_peak' potrebbe quindi essere trovato come' max_peak = b [b! = 0] .size' (questo funzionerebbe indipendentemente dal fatto che tu abbia o meno 0 valori). –
Quindi ho passato il pomeriggio a modificare il mio codice e l'ho fatto funzionare! Diciamo che sono state trovate 2 occorrenze di una forma 2x3 a (array ([0, 6]), array ([1, 7])), il che significa che gli angoli in alto a sinistra sono [0, 1] e [6, 7]. Quello che voglio fare è essere in grado di indicizzare tutte le celle 2x3 della forma e assegnarle a 0, quindi sulla prossima forma che stiamo cercando non controlleremo quella parte dell'immagine (come indicato sopra). Come posso utilizzare il valore restituito di correlata/fftconvolve per indicizzare la forma 2D senza utilizzare i loop? Ordinamento di una sezione di elenco di posizioni. – DaveO