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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With