How can I find the locations of all non-zero pixels in a binary image (cv::Mat)? Do I have to scan through every pixel in the image or is there a high level OpenCV function(
I placed this as an edit in Alex's answer, it did not get reviewed though so I'll post it here, as it is useful information imho.
You can also pass a vector of Points, makes it easier to do something with them afterwards:
std::vector<cv::Point2i> locations; // output, locations of non-zero pixels
cv::findNonZero(binaryImage, locations);
One note for the cv::findNonZero
function in general: if binaryImage
contains zero non-zero elements, it will throw because it tries to allocate '1 x n' memory, where n is cv::countNonZero
, and n will obviously be 0 then. I circumvent that by manually calling cv::countNonZero
beforehand but I don't really like that solution that much.
As suggested by @AbidRahmanK, there is a function cv::findNonZero
in OpenCV version 2.4.4. Usage:
cv::Mat binaryImage; // input, binary image
cv::Mat locations; // output, locations of non-zero pixels
cv::findNonZero(binaryImage, locations);
It does the job. This function was introduced in OpenCV version 2.4.4 (for example, it is not available in the version 2.4.2). Also, as of now findNonZero
is not in the documentation for some reason.
Anyone looking to do this in python. it is also possible to do it with numpy arrays and therefore you don't need to upgrade your opencv version (or use undocumented functions).
mask = np.zeros(imgray.shape,np.uint8)
cv2.drawContours(mask,[cnt],0,255,-1)
pixelpoints = np.transpose(np.nonzero(mask))
#pixelpoints = cv2.findNonZero(mask)
Commented out is the same function using openCV instead. For more info see:
https://github.com/abidrahmank/OpenCV2-Python-Tutorials/blob/master/source/py_tutorials/py_imgproc/py_contours/py_contour_properties/py_contour_properties.rst