Acelere la iteración sobre matrices Numpy / imagen OpenCV cv2

Tengo 3 arreglos numpy de forma> (500, 500). Estoy tratando de iterar sobre ellos simultáneamente. He intentado dos métodos diferentes, pero ambos son lentos.

Aquí Ix_Ix_blur , Ix_Iy_blur y Iy_Iy_blur son del mismo tamaño. Estoy tratando de encontrar características y dibujarlas en la imagen de OpenCV.


Método 1:

 for i in xrange (Ix_Ix_blur.shape[1]): for j in xrange(Ix_Ix_blur.shape[0]): A = np.array([ [Ix_Ix_blur[j][i], Ix_Iy_blur[j][i]], [Ix_Iy_blur[j][i], Iy_Iy_blur[j][i]] ]) detA = (A[0][0]*A[1][1])-(A[0][1]*A[1][0]) traceA = A[0][0]+A[1][1] harmonic_mean = detA/traceA if(harmonic_mean > thresh): cv2.circle(img, (i,j), 1, (0, 0, 255), -1, 8) 

Esto toma alrededor de 7 seconds para una imagen de tamaño de 512 * 512.


Método 2:

 Ix_Iy_blur_iter = np.nditer(Ix_Iy_blur) Iy_Iy_blur_iter = np.nditer(Iy_Iy_blur) Ix_Ix_blur_iter = np.nditer(Ix_Ix_blur) while(not Ix_Iy_blur_iter.finished): try: A = np.array([[Ix_Ix_blur_iter.next(), Ix_Iy_blur_iter.next()],[Ix_Iy_blur_iter.value, Iy_Iy_blur_iter.next()]]) except StopIteration: break detA = (A[0][0]*A[1][1])-(A[0][1]*A[1][0]) traceA = A[0][0]+A[1][1] harmonic_mean = detA/traceA if(harmonic_mean > thresh): i = Ix_Ix_blur_iter.iterindex/Ix.shape[0] j = Ix_Ix_blur_iter.iterindex - Ix.shape[0]*i cv2.circle(img, (j,i), 1, (0, 0, 255), -1, 8) 

Este método también parece tardar 7 seconds en iterar sobre el mismo tamaño de imagen.

¿Hay alguna otra forma de reducir el tiempo requerido para las iteraciones?

Configuración:

  • Ubuntu 12.04
  • Procesador i5 Core Gen 3
  • 4 GB de RAM
  • GPU ATI RADEON de 2 GB (que he apagado)

Primero puede usar Ix_Ix_blur[j, i] lugar de Ix_Ix_blur[j][i] . Ix_Ix_blur[j][i] creará una matriz temporal que es muy lenta.

Para acelerar el acceso a los elementos con ndarray, puede usar el método item (), que devuelve los valores numéricos nativos de Python, y no necesita crear una matriz temporal A. El cálculo con valores numéricos nativos es más rápido que una gran cantidad de escalas.

 for i in xrange (Ix_Ix_blur.shape[1]): for j in xrange(Ix_Ix_blur.shape[0]): a, b, c = Ix_Ix_blur.item(j, i), Ix_Iy_blur.item(j, i), Iy_Iy_blur.item(j, i) detA = a*c - b*b traceA = a + c harmonic_mean = detA/traceA if harmonic_mean > thresh: cv2.circle(img, (i,j), 1, (0, 0, 255), -1, 8) 

Para su problema particular, no es necesario realizar el cálculo en un bucle, puede:

 detA = Ix_Ix_blur * Iy_Iy_blur - Ix_Iy_blur**2 traceA = Ix_Ix_blur + Iy_Iy_blur harmonic_mean = detA / traceA for j, i in np.argwhere(harmonic_mean > thresh): cv2.circle(img, (i,j), 1, (0, 0, 255), -1, 8)