Difference between cv2.findNonZero and Numpy.NonZero
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:
-
numpy returns
(row,col) = (y,x)
, and OpenCV returns(x,y) = (col,row)
-
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.
Related videos on Youtube
RMS
Researcher, somewhere in the healthcare field. Mother Tongue: Python. I also speak C/C++, JavaScript, R and MATLAB.
Updated on October 19, 2022Comments
-
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:
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?
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 over 7 yearsI 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 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 over 7 yearsPosted as an answer. Glad it helped ;D
-
Divakar over 7 yearsOn performance,
cv2
seems to be around3x
better across varying datasizes. -
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 over 7 yearsSee 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 over 7 yearsYou answered half of the question. Thanks ;D
-
Divakar over 7 yearsThat's just a tiny portion of timings with just some numbers! :)
-
RMS over 7 yearsgreat 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.