Сравнение производительности интерфейсов OpenCV-Python, cv и cv2

Несколько дней назад я начал использовать новый интерфейс OpenCV-Python, cv2.

Мой вопрос касается сравнения интерфейсов cv и cv2.

Что касается простоты использования, новый интерфейс cv2 значительно улучшился, и работать с cv2 очень просто и весело.

Но как насчет скорости?

Я сделал два небольших snipplets кода, один в cv и еще один в cv2, чтобы проверить производительность. Оба выполняют ту же функцию, обращаются к пикселям изображения, проверяют его, вносят некоторые изменения и т.д.

Ниже приведен код:


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

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

И результат:

занятое время = 14.4029130936

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

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)

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

Результат:

занятое время = 1,16368889809

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

Смотрите, здесь старый cv примерно 12 times faster, чем cv2. И результирующие изображения одинаковы. (входное изображение имеет размер 720x540)

Почему это происходит?

Чем меньше cv2 по сравнению с cv?

Или я ошибаюсь здесь? Есть ли более быстрый метод в cv2 для вышеуказанного кода?

Ответ 1

Образ, возвращаемый cv2.imread(), является объектом массива NumPy. Таким образом, вы можете использовать функции NumPy для ускорения расчета.

Следующая программа показывает, как ускорить исходный код для версии цикла, используя метод item(), itemset() объекта 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

И следующая программа показывает, как создать палитру сначала, и используйте индекс массива NumPy, чтобы получить результат:

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)

Вывод:

0.453000068665
0.0309998989105
True

Выход версии cv:

0.468999862671

Примечание: длина оси 0 является высотой изображения, длина оси 1 - это ширина изображения