2012-02-20 16 views
22

Alcuni giorni fa, ho iniziato a utilizzare la nuova interfaccia OpenCV-Python, cv2.Confronto delle prestazioni delle interfacce OpenCV-Python, cv e cv2

La mia domanda riguarda il confronto dell'interfaccia cv e cv2.

Per quanto riguarda la facilità d'uso, la nuova interfaccia cv2 è notevolmente migliorata ed è davvero facile e divertente lavorare con cv2.

Ma per quanto riguarda la velocità?

Ho creato due piccoli snipplet di codice, uno in e un altro in cv2, per verificare le prestazioni. Ambedue fanno la stessa funzione, pixel di accesso di un'immagine, provarlo, apportare alcune modifiche, ecc

seguito è il codice:


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 

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

E il risultato è:

tempo impiegato = 14,4029130936

======================================= =============== interfaccia

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) 

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

Il risultato è:

012.

tempo impiegato = 1,16368889809

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

Vedere, qui vecchio cv è circa 12 times faster di cv2. E le immagini risultanti sono le stesse. (l'immagine di input è di dimensioni 720x540)

Perché ciò accade?

cv2 è più lento rispetto al cv?

O sto facendo qualche errore qui? C'è un metodo più veloce in cv2 per il codice sopra?

risposta

37

L'immagine restituita da cv2.imread() è un oggetto array di NumPy. Quindi è possibile utilizzare le funzioni di NumPy per accelerare il calcolo.

Il seguente programma mostra come velocizzare la propria origine per la versione del loop utilizzando il metodo item(), itemset() dell'oggetto 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 

E il seguente programma viene illustrato come creare la tavolozza prima, e usare indice di array di NumPy per ottenere il risultato:

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) 

L'output è:

0.453000068665 
0.0309998989105 
True 

La versione cv l'output è:

0.468999862671 

Nota: la lunghezza dell'asse 0 è l'altezza dell'immagine, la lunghezza dell'asse 1 corrisponde alla larghezza dell'immagine

+0

Grazie per la risposta. Puoi aggiungere qualche altro dettaglio? Conoscete un modo migliore per la procedura sopra, qualsiasi funzione numpy più veloce ecc.? –

+0

@arkiaz, ho modificato la versione cv2 per loop e ora è la stessa velocità della versione cv. E ho aggiunto una versione numpy per accelerare di più. – HYRY

+0

Grazie, il tuo primo metodo offre una velocità comparabile con cv, sebbene il codice diventi poco grande. Risultato ottenuto con la mia immagine 't = 1.127'. Ma il tuo secondo metodo dà un ottimo risultato di 't = 0.054', ma dà un grande schermo nero (cioè output errato). Perché è? –

Problemi correlati