Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comparing two OpenCV images/2D Numpy arrays

I am new to using OpenCV, Python and Numpy, but have been a Java, C++, C programmer for a while now.

I am implementing a sigma-delta background detector, which does the following:

let i1 be first image, let i2 be second image

    for each pixel:
    if i1(x,y) > i2(x,y), then i2(x,y) = i2(x,y) + 1
    if i1(x,y) < i2(x,y), then i2(x,y) = i2(x,y) - 1

I'm basically trying to iterate through the 2D image array and compare the pixel value with the other image, but I'm struggling to get that working with numpy arrays using for loops. I've tried using a nested for loop, but I get an error saying that I can't access the elements of that array.

Edit:

for x in range (width):
    for y in range (height):
        if Mt [x,y] > It[x,y]:
            Mt [x,y] = Mt[x,y]+1
        elif Mt [x,y] < It[x,y]:
            Mt [x,y] = Mt[x,y]-1

This is working but doesn't seem very elegant or efficient. I am hoping for a faster solution...

Any suggestions would be most welcome

like image 402
user2765323 Avatar asked Sep 12 '13 17:09

user2765323


1 Answers

This is a great place to vectorize your code, for an explanation and demonstration.

#Generate two random arrays, shape must be the same
>>> Mt = np.random.rand(2,2)
>>> It = np.random.rand(2,2)
>>> Mt
array([[ 0.47961753,  0.74107574],
       [ 0.94540074,  0.05287875]])
>>> It
array([[ 0.86232671,  0.45408798],
       [ 0.99468912,  0.87005204]])

#Create a mask based on some condition
>>> mask = Mt > It
>>> mask
array([[False,  True],
       [False, False]], dtype=bool)

#Update in place
>>> Mt[mask]+=1
>>> Mt[~mask]-=1  #Numpy logical not
>>> Mt
array([[-0.52038247,  1.74107574],
       [-0.05459926, -0.94712125]])

You will probably need to create a second mask as currently the subtraction mask is Mt <= It not Mt < It, however it was a good place to demonstrate logical not.


To reproduce your code exactly use this instead:

Mt[Mt > It]+=1
Mt[Mt < It]-=1  

Because I am interested in these things:

 def looper(Mt,It):
     for x in range (Mt.shape[0]):
         for y in range (Mt.shape[1]):
             if Mt [x,y] > It[x,y]:
                Mt [x,y] +=1
             elif Mt [x,y] < It[x,y]:
                Mt [x,y] -=1

nlooper = autojit(looper)

Mt = np.random.rand(500,500)
It = np.random.rand(500,500)

%timeit looper(Mt,It)
1 loops, best of 3: 531 ms per loop

%timeit Mt[Mt > It]+=1;Mt[Mt < It]-=1
100 loops, best of 3: 2.27 ms per loop

%timeit nlooper(Mt,It)
1 loops, best of 3: 308 µs per loop

autojit is a JIT compiler for python/numpy from the numba module.

like image 163
Daniel Avatar answered Sep 30 '22 09:09

Daniel