2012-02-20 20 views
22

Hace unos días, comencé a usar la nueva interfaz OpenCV-Python, cv2.Comparación de rendimiento de las interfaces OpenCV-Python, cv y cv2

Mi pregunta es con respecto a la comparación de cv y cv2 interfaz.

En cuanto a la facilidad de uso, la nueva interfaz cv2 ha mejorado mucho más, y es realmente fácil y divertido trabajar con cv2.

Pero, ¿y la velocidad?

Hice dos pequeños snipplets de código, uno en cv y otro en cv2, para verificar las actuaciones. Tanto hace la misma función, los píxeles de una imagen de acceso, probarlo, hacer algunas modificaciones, etc.

A continuación se muestra el código:


cv2 interface:

import time 
import numpy as np 
import cv2 

gray = cv2.imread('sir.jpg',0) 
width = gray.shape[0] 
height = gray.shape[1] 
h = np.empty([width,height,3]) 
t = time.time() 
for i in xrange(width): 
    for j in xrange(height): 
     if gray[i,j]==127: 
      h[i,j]=[255,255,255] 
     elif gray[i,j]>127: 
      h[i,j]=[0,0,255-gray[i,j]] 
     else: 
      h[i,j]=[gray[i,j],0,0] 
t2 = time.time()-t 
print "time taken = ",t2 

== =============================================== =

Y el resultado es:

tiempo tomado

= 14,4029130936

======================================= =============== interfaz

cv:

import cv,time 

gray = cv.LoadImage('sir.jpg',0) 
h = cv.CreateImage(cv.GetSize(gray),8,3) 

t=time.time() 

for i in xrange(gray.width): 
    for j in xrange(gray.height): 
     k = cv.Get2D(gray,j,i)[0] 
     if k==127: 
      cv.Set2D(h,j,i,(255,255,255)) 
     elif k>127: 
      cv.Set2D(h,j,i,(0,0,255-k)) 
     else: 
      cv.Set2D(h,j,i,(k,0,0)) 

t2 = time.time()-t 
print "time taken = ",t2 
cv.ShowImage('img',h) 
cv.WaitKey(0) 

================= =====================================

El resultado es:

tiempo tomado = 1,16368889809

======================================== ===============

Ver, aquí antiguo cv es aproximadamente 12 times faster que cv2. Y las imágenes resultantes son iguales. (la imagen de entrada es del tamaño 720x540)

¿Por qué sucede esto?

¿Es cv2 más lento en comparación con el cv?

¿O estoy cometiendo un error aquí? ¿Hay un método más rápido en cv2 para el código anterior?

Respuesta

37

La imagen devuelta por cv2.imread() es un objeto de matriz de NumPy. Entonces puede usar las funciones de NumPy para acelerar el cálculo.

El siguiente programa muestra cómo acelerar su origen para la versión de bucle utilizando el método item(), itemset() del objeto ndarray.

import time 
import numpy as np 
import cv2 

gray = cv2.imread('lena_full.jpg',0) 
height, width = gray.shape 
h = np.empty((height,width,3), np.uint8) 

t = time.time() 
for i in xrange(height): 
    for j in xrange(width): 
     k = gray.item(i, j) 
     if k == 127: 
      h.itemset(i, j, 0, 255) 
      h.itemset(i, j, 1, 255) 
      h.itemset(i, j, 2, 255) 
     elif k > 127: 
      h.itemset(i, j, 0, 0) 
      h.itemset(i, j, 1, 0) 
      h.itemset(i, j, 2, 255-k) 
     else: 
      h.itemset(i, j, 0, k) 
      h.itemset(i, j, 1, 0) 
      h.itemset(i, j, 2, 0) 
print time.time()-t 

Y el siguiente programa mostrará cómo crear la paleta en primer lugar, y el uso de índice de matriz de NumPy para obtener el resultado:

t = time.time() 
palette = [] 
for i in xrange(256): 
    if i == 127: 
     palette.append((255, 255, 255)) 
    elif i > 127: 
     palette.append((0,0,255-i)) 
    else: 
     palette.append((i, 0, 0)) 
palette = np.array(palette, np.uint8) 

h2 = palette[gray] 

print time.time() - t 

print np.all(h==h2) 

La salida es:

0.453000068665 
0.0309998989105 
True 

La versión cv salida es:

0.468999862671 

Nota: la longitud del eje 0 es la altura de la imagen, la longitud del eje 1 es el ancho de la imagen

+0

Gracias por la respuesta. ¿Puedes agregar algunos más detalles? ¿Conoces una mejor manera para el procedimiento anterior, cualquier función numpy más rápida, etc.? –

+0

@arkiaz, modifiqué tu cv2 para la versión de bucle, y ahora es la misma velocidad que la versión cv. Y agregué una versión numpy para acelerar más. – HYRY

+0

Gracias, su primer método proporciona una velocidad comparable con el cv, aunque el código se vuelve un poco grande. Resultado obtenido con mi imagen 't = 1.127'. Pero su segundo método da un muy buen resultado de 't = 0.054', pero da una gran pantalla negra (es decir, salida incorrecta). ¿Por qué es? –

Cuestiones relacionadas