Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

opencv

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?

like image 304
Alexey Avatar asked Mar 05 '13 17:03

Alexey


2 Answers

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.

like image 54
Ela782 Avatar answered Sep 21 '22 12:09

Ela782


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.

like image 22
Alexey Avatar answered Sep 21 '22 12:09

Alexey