Speed ​​up iteration over Numpy / OpenCV arrays cv2 image

I have 3 numpy arrays of shape> (500, 500). I am trying to iterate over them at the same time. I tried two different methods, but both are slow.

Here Ix_Ix_blur

, Ix_Iy_blur

and Iy_Iy_blur

are the same size. I am trying to find functions and draw them on an OpenCV image.


Method 1:

for i in xrange (Ix_Ix_blur.shape[1]):
    for j in xrange(Ix_Ix_blur.shape[0]):
        A = np.array([ [Ix_Ix_blur[j][i], Ix_Iy_blur[j][i]], 
            [Ix_Iy_blur[j][i], Iy_Iy_blur[j][i]] ])
        detA = (A[0][0]*A[1][1])-(A[0][1]*A[1][0])
        traceA = A[0][0]+A[1][1]

        harmonic_mean = detA/traceA
        if(harmonic_mean > thresh):
            cv2.circle(img, (i,j), 1, (0, 0, 255), -1, 8)

      

It takes about 7 seconds

for a 512 * 512 image


Method 2:

Ix_Iy_blur_iter = np.nditer(Ix_Iy_blur)
Iy_Iy_blur_iter = np.nditer(Iy_Iy_blur)
Ix_Ix_blur_iter = np.nditer(Ix_Ix_blur)

while(not Ix_Iy_blur_iter.finished):
    try:
        A = np.array([[Ix_Ix_blur_iter.next(), Ix_Iy_blur_iter.next()],[Ix_Iy_blur_iter.value, Iy_Iy_blur_iter.next()]])
    except StopIteration:
        break
    detA = (A[0][0]*A[1][1])-(A[0][1]*A[1][0])
    traceA = A[0][0]+A[1][1]

    harmonic_mean = detA/traceA
    if(harmonic_mean > thresh):
        i = Ix_Ix_blur_iter.iterindex/Ix.shape[0]
        j = Ix_Ix_blur_iter.iterindex - Ix.shape[0]*i
        cv2.circle(img, (j,i), 1, (0, 0, 255), -1, 8)

      

This method also seems to accept 7 seconds

to repeat the same image size.

Is there any other way that I can shorten the time it takes to iterate?

Configuration:

  • Ubuntu 12.04
  • 3rd generation Core i5 processor.
  • RAM 4 GB
  • 2GB ATI RADEON GPU (which I disabled)
+3


source to share


1 answer


You can use Ix_Ix_blur[j, i]

instead of Ix_Ix_blur[j][i]

. Ix_Ix_blur[j][i]

will create a temporary array which is very slow.

To speed up item access with ndarray, you can use the item () method, which returns python's own numeric values, and you don't need to create a temporary array A. Computing with native numeric values ​​is faster than numeric scalars.

for i in xrange (Ix_Ix_blur.shape[1]):
    for j in xrange(Ix_Ix_blur.shape[0]):
        a, b, c = Ix_Ix_blur.item(j, i), Ix_Iy_blur.item(j, i), Iy_Iy_blur.item(j, i)
        detA = a*c - b*b
        traceA = a + c
        harmonic_mean = detA/traceA
        if harmonic_mean > thresh:
            cv2.circle(img, (i,j), 1, (0, 0, 255), -1, 8)

      



For your specific task, there is no need to perform calculations in a loop, you can:

detA = Ix_Ix_blur * Iy_Iy_blur - Ix_Iy_blur**2
traceA = Ix_Ix_blur + Iy_Iy_blur
harmonic_mean = detA / traceA
for j, i in np.argwhere(harmonic_mean > thresh):
    cv2.circle(img, (i,j), 1, (0, 0, 255), -1, 8)

      

+4


source







All Articles