2010-08-22 10 views
5

Recientemente tomé un código que rastreó un objeto basado en el color en OpenCV C++ y lo reescribí en los enlaces de python.OpenCV Python une iteraciones increíblemente lentas a través de datos de imagen

Los resultados generales y el método fueron la misma sintaxis negativa, obviamente. Pero, cuando realizo el siguiente código en cada fotograma de un video, me toma casi 2-3 segundos completarlo, ya que la variante de C++, también a continuación, es instantánea en comparación y puedo iterar entre fotogramas tan rápido como mi dedo puede presionar un llave.

¿Alguna idea o comentario?

cv.PyrDown(img, dsimg) 
    for i in range(0, dsimg.height): 
     for j in range(0, dsimg.width): 

      if dsimg[i,j][1] > (_RED_DIFF + dsimg[i,j][2]) and dsimg[i,j][1] > (_BLU_DIFF + dsimg[i,j][0]): 
       res[i,j] = 255 
      else: 
       res[i,j] = 0 

for(int i =0; i < (height); i++) 
    { 
     for(int j = 0; j < (width); j++) 
     { 
      if(((data[i * step + j * channels + 1]) > (RED_DIFF + data[i * step + j * channels + 2])) && 
       ((data[i * step + j * channels + 1]) > (BLU_DIFF + data[i * step + j * channels]))) 
       data_r[i *step_r + j * channels_r] = 255; 
      else 
       data_r[i * step_r + j * channels_r] = 0; 
     } 
    } 

Gracias

Respuesta

6

Trate de usar numpy para hacer su cálculo, en lugar de bucles anidados. Debería obtener un rendimiento tipo C para cálculos simples como este de numpy.

Por ejemplo, su anidado para los bucles pueden ser reemplazados con un par de expresiones numpy ...

No estoy terriblemente familiar con OpenCV, pero creo que los enlaces Python ahora tienen una interfaz serie numpy, por lo el ejemplo anterior debería ser tan simple como:

cv.PyrDown(img, dsimg) 

data = np.asarray(dsimg) 
blue, green, red = data.T 

res = (green > (_RED_DIFF + red)) & (green > (_BLU_DIFF + blue)) 
res = res.astype(np.uint8) * 255 

res = cv.fromarray(res) 

(no está comprobado, por supuesto ...) Una vez más, estoy realmente no muy familiarizados con OpenCV, pero pitón bucles for anidados no son la manera de ir sobre la modificando una imagen por elementos, independientemente ...

Espero que ayude un poco, de todos modos!

+0

Esto definitivamente acelera las cosas, pero parece que no puedo entender por qué el resultado está más relacionado con el umbral de mi imagen y no encuentra las áreas verdes en la imagen como parece que debería. – bluth

+0

Pude haber malinterpretado en qué orden están los canales rojo, verde y azul de la imagen ... (A partir de su código anterior, parecía que el azul era el primer canal y el rojo el último ...) Tal vez intente desempacar el array "data" como 'rojo, verde, azul = datos.T'? Solo una loca suposición ... Puedo estar completamente equivocado, allí ... –

+0

Sí, ese fue mi pensamiento inicial, pero cambiar el orden no produce un resultado diferente. _RED_DIFF y _BLU son valores altos, 155, por lo que no debe haber muchos píxeles blancos dentro de la imagen y, sin embargo, los hay; es casi todo blanco cuando puse el _DIFF en 255? Parece que no puedo entender los resultados de res = (verde> (_RED_DIFF + rojo)) & (verde> (_BLU_DIFF + azul)). – bluth

Cuestiones relacionadas