Proporrò una risposta che funzioni rapidamente e perfettamente se si sta cercando exact match
sia in termini di dimensioni che di valori di immagine.
L'idea è quella di calcolare una ricerca di forza bruta del voluto h x w
modello un'immagine più grande H x W
in. L'approccio bruteforce consisterebbe nel guardare tutte le possibili finestre h x w
sull'immagine e verificare la corrispondenza pixel per pixel all'interno del modello. Questo tuttavia è molto costoso dal punto di vista computazionale, ma può essere accelerato.
im = np.atleast_3d(im)
H, W, D = im.shape[:3]
h, w = tpl.shape[:2]
Utilizzando la smart integral images uno in grado di calcolare molto velocemente la somma all'interno di una finestra h x w
a partire da ogni pixel. Un'immagine integrale è una tabella riassume zona (array sommati cumulativo), che può essere calcolato con NumPy molto velocemente:
sat = im.cumsum(1).cumsum(0)
e ha davvero belle proprietà, come il calcolo della somma di tutti i valori all'interno una finestra con solo 4 operazioni aritmetiche:

Così, calcolando la somma del modello e la congruenza con la somma di h x w
finestre oltre l'immagine integrale, è facile trovare un elenco di "possibili windows "dove la somma dei valori interni è uguale alla somma dei valori in t lui modello (una rapida approssimazione).
iA, iB, iC, iD = sat[:-h, :-w], sat[:-h, w:], sat[h:, :-w], sat[h:, w:]
lookup = iD - iB - iC + iA
Quanto sopra è una vettorizzazione NumPy del funzionamento mostrato nelle immagini per tutte le possibili h x w
rettangoli sopra l'immagine (quindi, molto veloce).
Ciò ridurrà molto il numero di finestre possibili (a 2 in uno dei miei test). L'ultimo passo, consiste nel controllare le corrispondenze esatte con il modello:
posible_match = np.where(np.logical_and.reduce([lookup[..., i] == tplsum[i] for i in range(D)]))
for y, x in zip(*posible_match):
if np.all(im[y+1:y+h+1, x+1:x+w+1] == tpl):
return (y+1, x+1)
noti che qui y
e x
coordinate corrispondono al punto A nell'immagine, che è la fila precedente e colonna al modello.
Mettendo tutto insieme:
def find_image(im, tpl):
im = np.atleast_3d(im)
tpl = np.atleast_3d(tpl)
H, W, D = im.shape[:3]
h, w = tpl.shape[:2]
# Integral image and template sum per channel
sat = im.cumsum(1).cumsum(0)
tplsum = np.array([tpl[:, :, i].sum() for i in range(D)])
# Calculate lookup table for all the possible windows
iA, iB, iC, iD = sat[:-h, :-w], sat[:-h, w:], sat[h:, :-w], sat[h:, w:]
lookup = iD - iB - iC + iA
# Possible matches
possible_match = np.where(np.logical_and.reduce([lookup[..., i] == tplsum[i] for i in range(D)]))
# Find exact match
for y, x in zip(*possible_match):
if np.all(im[y+1:y+h+1, x+1:x+w+1] == tpl):
return (y+1, x+1)
raise Exception("Image not found")
Funziona sia con scala di grigi e immagini a colori e viene eseguito in 7ms
per un'immagine 303x384
a colori con un modello 50x50
.
Un esempio pratico:
>>> from skimage import data
>>> im = gray2rgb(data.coins())
>>> tpl = im[170:220, 75:130].copy()
>>> y, x = find_image(im, tpl)
>>> y, x
(170, 75)
E per ilustrate il risultato:

immagine originale a sinistra, a destra il modello. E qui la corrispondenza esatta:
>>> fig, ax = plt.subplots()
>>> imshow(im)
>>> rect = Rectangle((x, y), tpl.shape[1], tpl.shape[0], edgecolor='r', facecolor='none')
>>> ax.add_patch(rect)
E per ultimo, solo un esempio del possible_matches
per il test:

La somma sopra le due finestre nell'immagine è lo stesso, ma l'ultimo passaggio della funzione filtra quello che non corrisponde esattamente al modello.
Una domanda veloce: si può presumere che l'immagine "piccola" apparirà nell'immagine "grande" sempre nella sua dimensione originale e esattamente con i suoi valori originali? O hai bisogno di gestire immagini 'piccole 'di dimensioni variabili che potrebbero essere' interpolate' e gestire le variazioni di 'illuminazione'? Voglio dire, tu parli di "corrispondenza esatta", è davvero esatto? –
Stai garantendo SEMPRE l'uso del formato 'PNG'? Chiedo a beause 'JPEG' subire la quantizzazione e la compressione con perdita e le cose che sono apparentemente identiche possono differire nella loro rappresentazione interna. –