2012-02-20 17 views
22

Kilka dni temu zacząłem używać nowego interfejsu OpenCV-Python, cv2.Porównanie wydajności interfejsów OpenCV-Python, cv i cv2

Moje pytanie dotyczy porównania interfejsu cv i cv2.

Jeśli chodzi o łatwość użytkowania, nowy interfejs cv2 znacznie się poprawił, a praca z cv2 jest naprawdę łatwa i przyjemna.

Ale co z prędkością?

Zrobiłem dwa małe fragmenty kodu, jeden w cv i drugi w cv2, aby sprawdzić występy. Zarówno robi tę samą funkcję, dostęp piksele obrazu, testować je, wprowadzić pewne modyfikacje, itp

Poniżej znajduje się kod:


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 

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

Rezultat:

razem wzięte = 14,4029130936

======================================= =============== interfejs

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) 

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

Wynikiem jest:

razem wzięte = 1,16368889809

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

Zobacz, tutaj stary cv jest około 12 times faster niż cv2. A wynikowe obrazy są takie same. (obraz wejściowy ma rozmiar 720x540)

Dlaczego tak się dzieje?

Czy cv2 wolniej w porównaniu do cv?

Czy robię tu jakiś błąd? Czy jest jakiś szybszy sposób w cv2 dla powyższego kodu?

Odpowiedz

37

Obraz zwrócony przez cv2.imread() jest obiektem tablicy NumPy. Możesz więc użyć funkcji NumPy do przyspieszenia obliczeń.

Poniższy program pokazuje, jak przyspieszyć pochodzenie dla wersji pętli, używając metody item(), itemset() obiektu 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 

I Poniższy program pokazuje, jak najpierw utworzyć paletę i używać indeks tablicy numpy, aby uzyskać wynik:

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) 

wyjście jest:

0.453000068665 
0.0309998989105 
True 

Wersja cv wydajność:

0.468999862671 

Uwaga: długość osi 0 to wysokość obrazu, długość osi 1 to szerokość obrazu

+0

Dzięki za odpowiedź. Czy możesz dodać jeszcze kilka szczegółów? Czy znasz lepszy sposób na powyższą procedurę, jakikolwiek szybszy numpy funkcje itp? –

+0

@arkiaz, zmodyfikowałem twoją wersję cv2 dla pętli, a teraz jest to ta sama prędkość co wersja cv. Dodałem też wersję numpy, aby przyspieszyć więcej. – HYRY

+0

Dzięki, twoja pierwsza metoda daje porównywalną prędkość z cv, chociaż kod staje się mały. Wynik uzyskany z moim obrazem 't = 1.127'. Ale twoja druga metoda daje bardzo dobry wynik 't = 0.054', ale daje duży czarny ekran (np. Błędne wyjście). Dlaczego to jest? –

Powiązane problemy