web-dev-qa-db-fra.com

OpenCV: Trouver toutes les coordonnées non nulles d'une image mat binaire

J'essaie de trouver les coordonnées non nulles (x, y) d'une image binaire.

J'ai trouvé quelques références à la fonction countNonZero() qui ne compte que les coordonnées non nulles et findNonZero() que je ne sais pas comment accéder ou utiliser car elle semble avoir été supprimée de la documentation complètement.

This est la référence la plus proche que j'ai trouvée, mais toujours pas utile du tout. J'apprécierais toute aide spécifique.

Edit: - Pour spécifier, cela utilise C++

19
DMor

Ici est une explication de la façon dont findNonZero() enregistre les éléments non nuls. Les codes suivants devraient être utiles pour accéder aux coordonnées non nulles de votre image binaire . La méthode 1 a utilisé findNonZero() dans OpenCV, et la méthode 2 a vérifié tous les pixels pour trouver ceux non nuls (positifs).

Méthode 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;
}

Méthode 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;
}
32
WangYudong

Il y a le code source suivant qui était fourni pour OpenCV 2.4. , qui peut être utile:

#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));
        }
    }
}

Remarque - il semble que la signature de la fonction était incorrecte, j'ai donc changé la sortie vector en passe-par-référence.

5
Roger Rowland