Difference between cv2.findNonZero and Numpy.NonZero

10,481

There is an error in the documentation:

Numpy gives coordinates in (row, column) format, while OpenCV gives coordinates in (x,y) format. So basically the answers will be interchanged. Note that, row = x and column = y. Note that, row = y and column = x.

So, regarding your questions:

  1. numpy returns (row,col) = (y,x), and OpenCV returns (x,y) = (col,row)

  2. You need to scan the whole matrix and retrieve some points. I don't think there will be any significant difference in performance (should be tested!).

    Since you're using Python, probably it's better to use Python facilities, e.g. numpy.

Runtime test comparing these two versions -

In [86]: mask = (np.random.rand(128,128)>0.5).astype(np.uint8)

In [87]: %timeit cv2.findNonZero(mask)
10000 loops, best of 3: 97.4 µs per loop

In [88]: %timeit np.nonzero(mask)
1000 loops, best of 3: 297 µs per loop

In [89]: mask = (np.random.rand(512,512)>0.5).astype(np.uint8)

In [90]: %timeit cv2.findNonZero(mask)
1000 loops, best of 3: 1.65 ms per loop

In [91]: %timeit np.nonzero(mask)
100 loops, best of 3: 4.8 ms per loop

In [92]: mask = (np.random.rand(1024,1024)>0.5).astype(np.uint8)

In [93]: %timeit cv2.findNonZero(mask)
100 loops, best of 3: 6.75 ms per loop

In [94]: %timeit np.nonzero(mask)
100 loops, best of 3: 19.4 ms per loop

Thus, it seems using OpenCV results in something around 3x speedup over the NumPy counterpart across varying datasizes.

Share:
10,481

Related videos on Youtube

RMS
Author by

RMS

Researcher, somewhere in the healthcare field. Mother Tongue: Python. I also speak C/C++, JavaScript, R and MATLAB.

Updated on October 19, 2022

Comments

  • RMS
    RMS over 1 year

    Silly question here.

    I want to find the locations of the pixels from some black and white images and found this two functions from Numpy library and OpenCV.

    The example I found on the internet (http://docs.opencv.org/trunk/d1/d32/tutorial_py_contour_properties.html):

        mask = np.zeros(imgray.shape,np.uint8)
        cv2.drawContours(mask,[cnt],0,255,-1)
        pixelpoints = np.transpose(np.nonzero(mask))
        pixelpointsCV2 = cv2.findNonZero(mask)
    

    Which states

    Numpy gives coordinates in (row, column) format, while OpenCV gives coordinates in (x,y) format. So basically the answers will be interchanged. Note that, row = x and column = y.

    Based on my understanding of english, isn't their explanation wrong? Shouldn't it be:

    Numpy gives coordinates in (row, column) format, while OpenCV gives coordinates in (y,x) or (column, row) format.

    My questions are:

    1. Does numpy return (row,col)/(x,y) and OpenCV (y,x) where row=x, col=y? Although IMHO it should be row=y, col=x?

    2. Which one is more computation efficient? In terms of time & resources.

    Maybe I am not getting this simple thing right due to not being a non-native English speaker.

    • Miki
      Miki over 7 years
      I think that the wrong part is Note that, row = x and column = y, which should be: Note that, row = y and column = x. So 1) numpy returns (row, col) = (y, x), and OpenCV returns (x,y) = (col, row). 2) Just run a few tests, but I don't think there will be any significant difference. Since you're working in python, I'd use python stuff (numpy)
    • RMS
      RMS over 7 years
      @Miki I ran a few tests and indeed OpenCV returns (x,y) = (col,row). If you post your comment as an answer I will accept it
    • Miki
      Miki over 7 years
      Posted as an answer. Glad it helped ;D
  • Divakar
    Divakar over 7 years
    On performance, cv2 seems to be around 3x better across varying datasizes.
  • Miki
    Miki over 7 years
    @Divakar Thanks. If you have a small benchmark you can add to the answer (and I'll make it a "Community answer") ;D
  • Divakar
    Divakar over 7 years
    See if the edits seem consistent with your thoughts. Feel free to edit further if needed. Also, I think you should keep as it as a personal post :)
  • Miki
    Miki over 7 years
    You answered half of the question. Thanks ;D
  • Divakar
    Divakar over 7 years
    That's just a tiny portion of timings with just some numbers! :)
  • RMS
    RMS over 7 years
    great answer. it would be better if that page were corrected because I've noticed there a lot of people who didn't notice the mistake.