Optimize your OpenCV code with Numpy

Sometimes, you may optimize good code with other good one. Numpy is usually the best, so if you think that you may do a trick other do, but with numpy, you should give a try.

I did it for the convertion « COLOR_BGR2RGB » from OpenCV (a very good open-source project, by the way) which convert a « Blue-Green-Red » encoded image into a RGB format. You already guessed, it just swap the blue channel with the red one. As a clever project, they use numpy as a library for their array. But they seem not to use it internally, just for the Python binding. And that’s a pity.

So the following script creates a random « image » (the biggest possible on my system: if I take twice bigger, I got memory error) and swap the Blue and Red channels with cvtColor from OpenCV library, or with numpy indexing.

Thing worth to notice :

  1. the use of « time.clock() » which is much better than « time.time() » (milisecond precision)
  2. the nice Numpy notation to reverse the 3 first index in a dimension. (I could have written r=r[:,:,::-1], but I needed to extract from a bigger array (with 4 channels) and I kept the syntax)
  3. I test each value of the matrix with just a line : « np.any(a!=b) »
"""
cvtColor benchmarking with numpy indexing.
@author: thierry AT 2diabolos.com
"""
import numpy as np
from cv2 import COLOR_BGR2RGB, cvtColor
from time import clock

tCV= tNP=0
r = np.uint8(np.random.randint(0,256,size=(10000,2000,3)))
rc= 1 * r
for i in range(10):
    tStart=clock()
    r=cvtColor(r,COLOR_BGR2RGB)
    tCV += clock()-tStart
    tStart=clock()
    r=r[:,:,2::-1]
    tNP += clock()-tStart
    if np.any(r!=rc):
        print "the 2 conversions are NOT equivalent !!!"
print "OpenCV clock :", tCV
print "Numpy indexing clock :", tNP

On my computer, I got :

OpenCV clock : 1.65601427898
Numpy indexing clock : 0.000214317560064

Yeah, that’s an optimization factor bigger than 7500 (I even got 8500 factor for a 100 for loop) ! nearly 4 order of magnitude!

OK, I admit that it’s not that important on a 640×480 webcam image, but you are constantly using such conversion when using openCV videocapture, so it might worth the declaration of a 2 line function!

I even double checked with a function declaration, like this :

def numpySwap(rr):
    r3=rr[:, :, 2::-1]
    return r3

it should be slower because the rand matrix is being copied in memory. it is about the same. So please OpenCV guys, if you read this, could you optimize your code ?