简体   繁体   中英

OpenCV - locations of all non-zero pixels in binary image

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(s) that can be used? The output should be a vector of points (pixel locations).

For example, this can be done in Matlab simply as:

imstats = regionprops(binary_image, 'PixelList');
locations = imstats.PixelList;

or, even simpler

[x, y] = find(binary_image);
locations = [x, y];

Edit : In other words, how to find coordinates of all non-zero elements in cv::Mat?

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.

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 xn' 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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM