I'm atttempting to find the non-zero (x,y) coordinates of a binary image.
I've found a few references to the function countNonZero()
which only counts the non-zero coordinates and findNonZero()
which I'm unsure how to access or use since it seems to have been removed from the documentation completely.
This is the closest reference I found, but still not helpful at all. I would appreciate any specific help.
Edit: - To specify, this is using C++
Here is an explanation for how findNonZero()
saves non-zero elements. The following codes should be useful to access non-zero coordinates of your binary image. Method 1 used findNonZero()
in OpenCV, and Method 2 checked every pixels to find the non-zero (positive) ones.
Method 1:
#include <iostream> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> using namespace std; using namespace cv; int main(int argc, char** argv) { Mat img = imread("binary image"); Mat nonZeroCoordinates; findNonZero(img, nonZeroCoordinates); for (int i = 0; i < nonZeroCoordinates.total(); i++ ) { cout << "Zero#" << i << ": " << nonZeroCoordinates.at<Point>(i).x << ", " << nonZeroCoordinates.at<Point>(i).y << endl; } return 0; }
Method 2:
#include <iostream> #include <opencv2/core/core.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/highgui/highgui.hpp> using namespace std; using namespace cv; int main(int argc, char** argv) { Mat img = imread("binary image"); for (int i = 0; i < img.cols; i++ ) { for (int j = 0; j < img.rows; j++) { if (img.at<uchar>(j, i) > 0) { cout << i << ", " << j << endl; // Do your operations } } } return 0; }
There is the following source code that was supplied for OpenCV 2.4.3, which may be helpful:
#include <opencv2/core/core.hpp> #include <vector> /*! @brief find non-zero elements in a Matrix * * Given a binary matrix (likely returned from a comparison * operation such as compare(), >, ==, etc, return all of * the non-zero indices as a std::vector<cv::Point> (x,y) * * This function aims to replicate the functionality of * Matlab's command of the same name * * Example: * \code * // find the edges in an image * Mat edges, thresh; * sobel(image, edges); * // theshold the edges * thresh = edges > 0.1; * // find the non-zero components so we can do something useful with them later * vector<Point> idx; * find(thresh, idx); * \endcode * * @param binary the input image (type CV_8UC1) * @param idx the output vector of Points corresponding to non-zero indices in the input */ void find(const cv::Mat& binary, std::vector<cv::Point> &idx) { assert(binary.cols > 0 && binary.rows > 0 && binary.channels() == 1 && binary.depth() == CV_8U); const int M = binary.rows; const int N = binary.cols; for (int m = 0; m < M; ++m) { const char* bin_ptr = binary.ptr<char>(m); for (int n = 0; n < N; ++n) { if (bin_ptr[n] > 0) idx.push_back(cv::Point(n,m)); } } }
Note - it looks like the function signature was wrong so I've changed the output vector
to pass-by-reference.
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