2010-06-15 72 views
19

Estoy tratando de usar python para determinar si una imagen (pequeña) está dentro de otra imagen (grande).Cómo encontrar una imagen dentro de otra imagen usando python

¿Alguna sugerencia antes de llevarme completamente por el camino equivocado?

/edit: Ok, algunas ideas: estoy usando PIL, y estoy convirtiendo cada imagen al modo 'P' para que pueda comparar cada píxel como un entero. Estoy tratando de implementar algo así como una búsqueda de cadenas Boyer-Moore o el algoritmo Knuth-Morris-Pratt, pero en 2 dimensiones.

Tal vez esto ayude: en lugar de buscar ABC in XXXABCXXX (respuesta = 4) estamos buscando

ABC  
DEF  
GHI  

en

XXXXX   
XABCX   
XDEFX  
XGHIX  
XXXXX 

(respuesta = (2,2))

+1

¿Está buscando exactamente la imagen pequeña o podría rotar/sesgar/escalar la imagen/etc.? –

+0

1 imagen pequeña exactamente. – Zach

+1

Zach, ¿alguna vez ha resuelto esto? Estoy en el mismo barco en este momento – mikew

Respuesta

8

EDIT: Ok, aquí es la manera ingenua para hacer esto:

import Image, numpy 

def subimg(img1,img2): 
    img1=numpy.asarray(img1) 
    img2=numpy.asarray(img2) 

    #img1=numpy.array([[1,2,3],[4,5,6],[7,8,9]]) 
    #img2=numpy.array([[0,0,0,0,0],[0,1,2,3,0],[0,4,5,6,0],[0,7,8,9,0],[0,0,0,0,0]]) 

    img1y=img1.shape[0] 
    img1x=img1.shape[1] 

    img2y=img2.shape[0] 
    img2x=img2.shape[1] 

    stopy=img2y-img1y+1 
    stopx=img2x-img1x+1 

    for x1 in range(0,stopx): 
     for y1 in range(0,stopy): 
      x2=x1+img1x 
      y2=y1+img1y 

      pic=img2[y1:y2,x1:x2] 
      test=pic==img1 

      if test.all(): 
       return x1, y1 

    return False 

small=Image.open('small.tif') 
big=Image.open('big.tif') 

print subimg(small, big) 

funciona Bien, pero quiero acelerarlo. Creo que la clave está en la "prueba" de la matriz que podríamos usar para omitir algunas posiciones en la imagen.

Editar 2: asegúrese de utilizar imágenes en un formato sin pérdidas para probar esto.

En Mac, instale la almohadilla y from PIL import Image

+0

¿Cómo podemos convertir al modo 'P' .... qué pasa si mi imagen es' png' o 'jpg' – vks

6

Sikuli lo hace usando OpenCV, vea here cómo funciona match_by_template y luego use los enlaces de Python OpenCV para hacer lo mismo. Hacerlo sin OpenCV debería ser difícil, echar un vistazo a la documentación OpenCV, búsqueda de comparación de plantillas, etc ...

3

sé que es un poco tarde, pero se puede utilizar Boyer-Moore a buscar la primera línea de la imagen pequeña en cada una de las líneas de la imagen grande. En el momento en que encuentra una coincidencia, tiene la posición X e Y y solo tiene que comprobar si el resto de las líneas de la imagen más pequeña coincide con el resto de las líneas de la imagen más grande comenzando en la posición X e Y + 1,2, 3, ... En el primer desajuste continúe con la búsqueda de la primera línea. No creo que puedas llegar más rápido que esto.

+0

¿Podría publicar algún código de ejemplo? – Zach

+0

Yo también apreciaría mucho un ejemplo de cómo usar Boyer-Moore (-Horspool) en el espacio 2d – mikew

+2

, en realidad esta respuesta solo optimiza en una dimensión, en el plano X.está acelerando la búsqueda de la búsqueda horizontal usando B-M al desplazarse. pero luego estás haciendo una búsqueda ingenua en el plano veritcal, ya que nunca te estás desplazando hacia abajo. Aún así, es muy intuitivo y definitivamente una mejora – mikew

0

Eche un vistazo a mi respuesta a una pregunta similar para un code example using OpenCV. La conversión de PIL a numpy es directa, p. solo use np.array(pilimage).

Cuestiones relacionadas