26

A few days back, I started using new OpenCV-Python interface, cv2.

My question is regarding the comparison of cv and cv2 interface.

Regarding the ease of use, new cv2 interface has improved far greater, and it is really easy and fun to work with cv2.

But what about speed?

I made two small code snipplets, one in cv and another in cv2, to check the performances. Both does the same function, access pixels of an image, test it, make some modifications, etc.

Below is the code:


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

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

And result is:

time taken = 14.4029130936

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

cv interface:

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)

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

The result is:

time taken = 1.16368889809

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

See, here old cv is about 12 times faster than cv2. And resulting images are same. (input image is of size 720x540)

Why does this happen?

Is cv2 slower compared to cv?

Or am I making any mistake here? Is there a faster method in cv2 for the above code?

Peter Mortensen
31.5k22 gold badges110 silver badges134 bronze badges
asked Feb 20, 2012 at 7:43

1 Answer 1

39

The image returned by cv2.imread() is an array object of NumPy. So you can use NumPy's functions to speedup calculation.

The following program shows how to speedup your origin for loop version by using item(), itemset() method of ndarray object.

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

And the following program show how to create the palette first, and use NumPy's array index to get the result:

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)

The output is:

0.453000068665
0.0309998989105
True

The cv version output is :

0.468999862671

Note: the length of axis 0 is the height of the image, the length of axis 1 is the width of the image

answered Feb 20, 2012 at 7:59
Sign up to request clarification or add additional context in comments.

7 Comments

Thanks for the answer. Can you add a few more details? Do you know a better way for the above procedure, any faster numpy functions etc?
@arkiaz, I modified your cv2 for loop version, and now it's the same speed as cv version. And I added a numpy version to speedup more.
Thanks, your first method gives comparable speed with cv, although code become little big. Result obtained with my image t=1.127. But your second method gives a very good result of t=0.054, but gives a large black screen( ie wrong output). Why is it?
@arkiaz, Please change the line "palette = np.array(palette)" to "palette = np.array(palette, np.uint8)", this will solve the problem.
well, palette=np.array(palette,np.uint8) solved the problem, and it is pretty fast, t=0.503. Thanks.
|

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.