Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenCV Python binds incredibly slow iterations through image data

I recently took some code that tracked an object based on color in OpenCV c++ and rewrote it in the python bindings.

The overall results and method were the same minus syntax obviously. But, when I perform the below code on each frame of a video it takes almost 2-3 seconds to complete where as the c++ variant, also below, is instant in comparison and I can iterate between frames as fast as my finger can press a key.

Any ideas or comments?

    cv.PyrDown(img, dsimg)
    for i in range( 0, dsimg.height ):
        for j in range( 0, dsimg.width):

            if dsimg[i,j][1] > ( _RED_DIFF + dsimg[i,j][2] ) and dsimg[i,j][1] > ( _BLU_DIFF + dsimg[i,j][0] ):
                res[i,j] = 255
            else:
                res[i,j] = 0

    for( int i =0; i < (height); i++ ) 
    {
        for( int j = 0; j < (width); j++ )
        {
            if( ( (data[i * step + j * channels + 1]) > (RED_DIFF + data[i * step + j * channels + 2]) ) &&
                ( (data[i * step + j * channels + 1]) > (BLU_DIFF + data[i * step + j * channels]) ) )
                data_r[i *step_r + j * channels_r] = 255;
            else
                data_r[i * step_r + j * channels_r] = 0;
        }
    }

Thanks

like image 496
bluth Avatar asked Aug 22 '10 19:08

bluth


1 Answers

Try using numpy to do your calculation, rather than nested loops. You should get C-like performance for simple calculations like this from numpy.

For example, your nested for loops can be replaced with a couple of numpy expressions...

I'm not terribly familiar with opencv, but I think the python bindings now have a numpy array interface, so your example above should be as simple as:

cv.PyrDown(img, dsimg)

data = np.asarray(dsimg)
blue, green, red = data.T

res = (green > (_RED_DIFF + red)) & (green > (_BLU_DIFF + blue))
res = res.astype(np.uint8) * 255

res = cv.fromarray(res)

(Completely untested, of course...) Again, I'm really not terribly familar with opencv, but nested python for loops are not the way to go about modifying an image element-wise, regardless...

Hope that helps a bit, anyway!

like image 180
Joe Kington Avatar answered Nov 07 '22 03:11

Joe Kington